2014-02-27 168 views
3

我使用ARB_DEBUG_OUTPUT分机呼叫我的错误日志记录功能后赶上的OpenGL错误,但程序崩溃。访问冲突与ARB_DEBUG_OUTPUT

我设置使用的代码从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 64位

编辑:我也试过手动调用调试回调,但它不”触发异常。

+1

调用回调函数并不奇怪 - 毕竟,您是定义函数的人。但是,您不应该添加'ARB'后缀。此外,在调用“DebugMessageCallback”时,不需要将Ctr转换为“GLDEBUGPROC”的回调函数的签名拟合,因此函数ptr已经具有正确的类型。关于崩溃,请查看callstack - 在某些NVIDIA模块中是否发生访问冲突?我想是的,但请确认。 – thokra

+0

这句话的要点是什么:'(void)length;'?既然它什么都不做,我得到的印象你其实是想在那里做点什么? –

+1

@ AndonM.Coleman:这是C/C++来阻止编译器抱怨未使用的变量。:D通常你会看到包裹在一个宏中,像'#define UNUSED(x)(void)x;' – thokra

回答

5

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

我使用的Windows API头文件中定义的宏CALLBACK改变了回调定义

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

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