2014-02-27 38 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在十進制和它正好是在調用層次傳遞到初始化函數更高的一個步驟的屏幕寬度參數。由於調用約定無效,因此從堆棧中讀取此值而不是由調用函數的圖形驅動程序設置的實際返回地址。