Access violation with ARB_DEBUG_OUTPUT

967 views Asked by At

I am using the ARB_DEBUG_OUTPUT extension to catch OpenGL errors but the program crashes after calling my error logging function.

I set up the extension using the code from this blog post. Here's the exact code I use to setup the callback:

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

Here's 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);
}

I use glEnable with an invalid parameter to trigger the callback:

glEnable(GL_DEPTH);

After printing the error message successfully the program triggers an unhandled exception Access violation executing location 0x00000500.

I am using SDL2 to create the OpenGL 3.3 core profile debug context and GL Load to fetch the GL extension pointers.

The program doesn't crash on the invalid glEnable call if I disable the extension.

How can I fix this?

Computer specs:

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

Edit: I also tried calling the debug callback manually but it doesn't trigger the exception.

1

There are 1 answers

0
pekkav On BEST ANSWER

The OpenGL callback functions use the __stdcall calling convention instead of __cdecl that's turned on by default in MSVC2012.

I changed the callback definition to

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

using the CALLBACK macro defined by the Windows API headers.

The invalid address 0x00000500 is 1280 in decimal and it happens to be a screen width parameter passed in to an initialization function one step higher in the call hierarchy. Because of the invalid calling convention this value was read from the stack instead of the actual return address set by the graphics driver calling the function.