Ian Woodley
Ian Woodley

Reputation: 85

glDebugMessageCallback causing access violation (GLFW + GLAD)

I have OpenGL version 4.4 installed, the corresponding 4.4 core GLAD build, and GLFW version 3.2 (editing in Visual Studio 2015). I'm using the callback function as detailed at https://learnopengl.com/#!In-Practice/Debugging:

void APIENTRY glDebugOutput(GLenum source, GLenum type, GLuint id, GLenum severity, 
    GLsizei length, const GLchar *message, const void *userParam);

I have the following function:

GLFWwindow* init(int width, int height, const char* header) {
    GLFWwindow* window;

    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GL_TRUE);

    window = glfwCreateWindow(width, height, header, NULL, NULL);
    if (window == NULL) {
        glfwTerminate();
        throw std::runtime_error("Failed to create GLFW window.");
    }
    glfwMakeContextCurrent(window);
    glfwSetFramebufferSizeCallback(window, resizeCallback);

    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
    {
        glfwTerminate();
        throw std::runtime_error("Failed to initialize GLAD");
    }

    GLint flags; glGetIntegerv(GL_CONTEXT_FLAGS, &flags);
    if (flags & GL_CONTEXT_FLAG_DEBUG_BIT)
    {
        glEnable(GL_DEBUG_OUTPUT);
        glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
        glDebugMessageCallback(glDebugOutput, nullptr); // segfault on this line
        glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, GL_TRUE);
    }

    return window;
}

I've tried re-installing GLAD and changing APIENTRY to CALLBACK, to no avail. I'm completely lost, any suggestions?

Upvotes: 1

Views: 3392

Answers (1)

derhass
derhass

Reputation: 45362

What you're requesting here:

glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

is GL 3.3 core. Accroding to the relevant extension specifications:

If version 3.2 or greater is requested, the context returned may implement any of the following versions:

  • The requested profile of the requested version.
  • The requested profile of any later version, so long as no features have been removed from that later version and profile.

you may get some context >= 3.3. The fact that you have an OpenGL implementation capable of GL 4.4 does not guarantee that you get a 4.4 context. YOu might get - and a lot of drivers nowadays actually do that - exactly the version you asked for.

If you look into the code from GLAD, you will find:

static void load_GL_VERSION_4_3(GLADloadproc load) {
        if(!GLAD_GL_VERSION_4_3) return;
        [...]
        glad_glDebugMessageCallback = (PFNGLDEBUGMESSAGECALLBACKPROC)load("glDebugMessageCallback");
        [...]
}

So GLAD will not even attempt to load that function pointer if the GL version of your context is not at least 4.3. As a result, calling this function without making sure that you're on a >= 4.3 context is just undefined behavior, and a crash is very likely.

Upvotes: 7

Related Questions