我如何确定此内存更改/损坏的根源?

问题描述 投票:0回答:1

我目前正在开发一个Vulkan程序,我希望将其用作游戏引擎,但距离目标还很遥远。第一步,我只是尝试使用动态结构列表来渲染三角形,以获取诸如顶点和着色器之类的数据。为了解决特定于平台的障碍,我使用GLFW创建窗口和Vulkan曲面。

现在,我正尝试从文件中加载SPIR-V着色器,并使用它们创建VkShaderModule,将在渲染管道中使用它们。目前,我代码的抽象部分是这样开始的:

main.c

#include "application.h"
#include "config.h"
#include "engine_vulkan.h"
#include "glfw/glfw3.h"

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv) {
    printf("VLK Engine - Version %s\n", VERSION_NUMBER);
    if (enable_validation_layers) {
        printf("Validation layers enabled.\n");
    }
    printf("\n");

    struct VulkanData vulkan_data = {0};
    struct Application app = {.window = NULL, .vulkan_data = &vulkan_data, .objects = NULL};

    bool ret = application_init(&app);
    if (ret == false) {
        fprintf(stderr, "Cannot initialize applcation.\n");
        return EXIT_FAILURE;
    }

    while (application_loopcondition(&app)) {
        application_loopevent(&app);
    }

    application_close(&app);

    return EXIT_SUCCESS;
}

application.c

#include "application.h"

#include "engine_object.h"
#include "engine_vulkan.h"

bool application_init(struct Application *app) {
    bool ret;

    // Initialize GLFW
    glfwInit();

    // Create window
    glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
    app->window = glfwCreateWindow(800, 600, "Vulkan window", NULL, NULL);
    if (app->window == NULL) {
        fprintf(stderr, "Failed to create window.\n");
        return false;
    }

    printf("Created window @ 0x%p\n", app->window);

    // Initialize game object list
    objectlink_init(app);

    // Create game objects
    struct RenderObjectCreateInfo ro_create_info = {.vertex_shader_path = "shaders/shader.vert.spv",
                                                    .fragment_shader_path =
                                                        "shaders/shader.frag.spv",
                                                    .is_static = true};
    struct RenderObject triangle = {0};
    object_init(app, &ro_create_info, &triangle);

    objectlink_add(app, &triangle);

    // Init Vulkan
    ret = vulkan_init(app);
    if (!ret) {
        fprintf(stderr, "Failed to initialize Vulkan.\n");
        return false;
    }

    return true;
}

bool application_loopcondition(struct Application *app) {
    // Close only if GLFW says so
    return !glfwWindowShouldClose(app->window);
}

void application_loopevent(struct Application *app) {
    // Poll for events like keyboard & mouse
    glfwPollEvents();
}

void application_close(struct Application *app) {
    // Destroy objects
    objectlink_destroy(app);
    // Close Vulkan instance
    vulkan_close(app);
    // End window & GLFW
    glfwDestroyWindow(app->window);
    glfwTerminate();
}

重要结构

struct Application {
    GLFWwindow *window;
    struct VulkanData *vulkan_data;
    struct RenderObjectLink *objects;
};

struct RenderObject {
    char *vertex_shader_path;
    struct ShaderFile vertex_shader_data;
    VkShaderModule vertex_shader;
    char *fragment_shader_path;
    struct ShaderFile fragment_shader_data;
    VkShaderModule fragment_shader;
    bool is_static;
};

struct RenderObjectCreateInfo {
    char *vertex_shader_path;
    char *fragment_shader_path;
    bool is_static;
};

struct RenderObjectLink {
    struct RenderObject *render_object;
    struct RenderObjectLink *next;
};

在我的应用程序结构中存储VkShaderModule时出现了我的应用程序中的问题。我的程序应该存储有关对象的信息的方式是在称为Applicationapp结构中,该结构指向RenderObjectLink字段中的objects链表。我的函数objectlink_initobjectlink_add正常工作,但是当进入GLFW函数render_objectglfwWindowShouldClose时,glfwPollEvents字段指向的结构内的数据会更改/损坏。

由于这两个函数是在初始化Vulkan和创建着色器模块后运行的,因此我在GDB中发现Vulkan函数运行正常,并且仅在运行GLFW循环函数时我的数据结构才被破坏。我已经使用硬件监视点对GDB进行了调试,以确定对这些着色器的引用(以及整个程序中的其他变量)是否在输入这些函数后发生了变化。

Thread 1 hit Hardware watchpoint 4: app->objects->render_object->vertex_shader

Old value = (VkShaderModule) 0x731f0f000000000a
New value = (VkShaderModule) 0x40d625 <glfwPollEvents+43>
_glfwPlatformPollEvents () at C:/Users/dylanweber/Documents/C-Projects/vlkengine/main/glfw/src/win32_window.c:1878
1878    {

这会持续发生,但运行时变量会更改为不同的值。内存分析工具(例如Dr. Memory)(因为我使用Windows,因此无法使用Valgrind)仅显示系统DLL中的内存问题(例如通过GLFW读取控制器输入的xinput),与我的程序无关。造成这种腐败的原因是什么?我可以使用哪些工具/资源来发现这些问题?

c mingw glfw vulkan memory-corruption
1个回答
0
投票

根据代码,objectlink_add函数接受第二个参数作为指针。这种方法最可能的用途是将指针添加到基础数据结构,并保留它以备将来参考。帖子中提到了渲染管道,这可能是一种链接。

但是,该函数是从application_init过程调用的,该过程在其堆栈上分配了对象triangle。当函数返回时,其堆栈消失,指针处的值变为无效。

有几种解决方法:

  1. 使用malloc(或类似方法)动态分配三角形结构。因此从函数返回后它不会消失。这是最通用的方法,但是希望在某些时候调用free()函数。

  2. triangle对象可以是static

  3. objectlink_add可以在某些内部结构中复制triangle字段,但是,如果有多种类型的对象,那就很成问题了。

© www.soinside.com 2019 - 2024. All rights reserved.