ARB_DEBUG_OUTPUT访问冲突

时间:2014-02-27 08:58:23

标签: c++ visual-c++ opengl glload

我使用ARB_DEBUG_OUTPUT扩展来捕获OpenGL错误,但程序在调用错误记录功能后崩溃。

我使用this blog post中的代码设置了扩展程序。这是我用来设置回调的确切代码:

glDebugMessageCallback((GLDEBUGPROC)debugCallbackARB, stderr);
glEnable(GL_DEBUG_OUTPUT);
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);

这是debugCallbackARB

void debugCallbackARB(GLenum source, GLenum type, GLuint id, GLenum severity,
                     GLsizei length, const GLchar *message, GLvoid *userParam)
{
    (void)length;
    FILE *outFile = (FILE*)userParam;
    char finalMessage[256];
    formatDebugOutputARB(finalMessage, 256, source, type, id, severity, message);
    logger->debug("%s", finalMessage);
}

我使用带有无效参数的glEnable来触发回调:

glEnable(GL_DEPTH);

成功打印错误消息后,程序会触发未处理的异常Access violation executing location 0x00000500.

我正在使用SDL2创建OpenGL 3.3核心配置文件调试上下文,并使用GL Load来获取GL扩展指针。

如果禁用扩展程序,程序不会因无效glEnable调用而崩溃。

我该如何解决这个问题?

电脑规格:

  • NVIDIA GeForce GT 630
  • ForceWare 327.23
  • Windows 7 x64

编辑:我也尝试手动调用调试回调,但不会触发异常。

1 个答案:

答案 0 :(得分:5)

OpenGL回调函数使用__stdcall调用约定,而不是默认情况下在MSVC2012中打开的__cdecl

我将回调定义更改为

void CALLBACK debugCallbackARB(GLenum source, GLenum type, GLuint id, GLenum severity,
                 GLsizei length, const GLchar *message, GLvoid *userParam)

使用Windows API标头定义的CALLBACK宏。

无效地址0x00000500的十进制数为1280,它恰好是传入初始化函数的屏幕宽度参数,在调用层次结构中高出一级。由于调用约定无效,因此从堆栈中读取此值,而不是调用函数的图形驱动程序设置的实际返回地址。