【问题标题】:glDebugMessageCallback causes segfaultglDebugMessageCallback 导致段错误
【发布时间】:2017-08-08 00:53:22
【问题描述】:

我在这里遇到了一些问题。我无法调试我的 C++ OpenGL 程序,因为激活调试消息会导致段错误。

我注册了一个调试回调函数:

static void APIENTRY openglCallbackFunction(
  GLenum source,
  GLenum type,
  GLuint id,
  GLenum severity,
  GLsizei length,
  const GLchar* message,
  const void* userParam) {
  (void)source; (void)type; (void)id;
  (void)severity; (void)length; (void)userParam;
  fprintf(stderr, "%s\n", message);
  if (severity==GL_DEBUG_SEVERITY_HIGH) {
    fprintf(stderr, "Aborting...\n");
    abort();
  }
}

我在以下代码中启动调试上下文:

this->window = glfwCreateWindow(this->winx, this->winy, "Cortex Stretcher", NULL, NULL);
  if(this->window == NULL) {
    fprintf(stderr, "Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. Try the 2.1 version of the tutorials.\n" );
    glfwTerminate();
    return -1;
  }
  glfwMakeContextCurrent(this->window);

  GLint flags; glGetIntegerv(GL_CONTEXT_FLAGS, &flags);
  if (flags & GL_CONTEXT_FLAG_DEBUG_BIT)
  {
     cout << "Debug output enabled!" << endl;
     glEnable(GL_DEBUG_OUTPUT);
     glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
     glDebugMessageCallback(openglCallbackFunction, nullptr);
    //  glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, GL_TRUE);
  }

如果我只是注释掉glDebugMessageCallback(openglCallbackFunction, nullptr);,那么我的代码运行时不会出现任何错误(除了我的模型渲染不正确,这就是我尝试调试的原因)。

但如果我尝试注册回调,那么我的代码会出现段错误(在注册时)。知道为什么吗?这本质上只是复制粘贴的代码。

注意:glGetString(GL_VERSION) 返回 4.5.0 NVIDIA 375.39

【问题讨论】:

  • glDebugMessageCallback 仅在 OpenGL > 4.3 中可用。您的错误消息让我认为您使用的是 OpenGL 3.3 或 2.1,两者都不支持。
  • 事实并非如此。如果我打印出glGetString(GL_VERSION);,我会得到 4.5.0 NVIDIA 375.39。我正在使用 Titan X。

标签: c++ opengl opengl-4


【解决方案1】:

您使用的是哪种 GL 加载机制?您的代码确实创建了一个上下文并使其成为当前的,但您从不加载任何 GL 函数指针。典型的gl.h 标头仅包含 GL 1.1 之前的 GL 函数,并且这些函数也是您可以依赖的唯一函数,它们可以由 OpenGL 库以独立于平台的方式导出。您的编译器(和链接器)没有抱怨 glDebugMessageCallback 的事实表明您使用了一些 GL 加载程序,例如 glew、glad 或其他。这些通常通过为每个 GL 函数声明一个函数指针来工作,这些函数指针初始化为NULL,并在您调用一些初始化函数后加载。由于您在尝试设置调试回调之前没有执行此操作,因此您只是在调用 NULL 指针。

【讨论】:

  • 啊,我确实在用glew。我明白它现在在做什么,但我当时没有发布这个问题,你完全正确,我的调试设置在我初始化 glew 之前被调用!谢谢!
  • 我可耻地将调试设置夹在 GLFW 和 gl3w 初始化步骤之间。这解决了我的问题。
猜你喜欢
  • 1970-01-01
  • 2015-09-03
  • 2012-08-17
  • 1970-01-01
  • 2011-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多