SwapBuffers 让我的程序崩溃!

Posted

技术标签:

【中文标题】SwapBuffers 让我的程序崩溃!【英文标题】:SwapBuffers crashing my program! 【发布时间】:2009-03-20 23:13:36 【问题描述】:

我有一个 OpenGL 程序,可以在我的所有计算机上运行,​​但只有一台。它是具有 Vista 64 和 Radeon HD4850 的台式机。问题似乎出在我对 SwapBuffers(hdc) 的调用中。

它编译得很好,然后给了我一个异常:

Program.exe 中 0x00000000 处未处理的异常:0xC0000005:访问冲突。

在调用 SwapBuffers 之前使用 VC++ 中断显示 hdc 的值为:

0xfe011734 未使用=??? CXX0030:错误:无法评估表达式

有人知道会发生什么吗? SwapBuffers 是否会从一台 PC 更改为另一台 PC?我已经让它在 XP32、XP64 和(不同的)Vista64 上工作。

while (!quit)
    
        if (PeekMessage(&msg, NULL, NULL, NULL, PM_REMOVE))
        
            if (msg.message == WM_QUIT)
                quit = true;

            TranslateMessage(&msg);
            DispatchMessage(&msg);
        

        renderFrame();  //draws the scene

        SwapBuffers(hdc);

        if (GetAsyncKeyState(VK_ESCAPE))
            shutdown();

        think();        //calculates object positions, etc.
     

有问题的系统 (HD4850) 上的驱动程序是最新的。我已经在另一个带有 Radeon HD4870 的 Vista64 系统上运行并编写了该程序,该系统也带有最新的驱动程序。据我所知,这两张卡的驱动程序几乎与 HD48xx 系列相同。因此,GPU 导致问题似乎很奇怪。

无论如何,我错了还是内存问题? (访问冲突)

另外,如果我删除对 SwapBuffers(hdc) 的调用,程序看起来运行良好,虽然没有绘制任何内容,当然,因为帧缓冲区从不交换。但它至少是稳定的。

调用栈(->是栈ptr):

    ATKOGL32.dll!6aef27bc()     
    opengl32.dll!665edb2d()     
    opengl32.dll!665f80d1()     
    gdi32.dll!75e14104()    
->   MyProg.exe!WinMain(HINSTANCE__ * hinstance=0x009a0000, HINSTANCE__ * hprevinstance=0x00000000, char * lpcmdline=0x003b4a51, int nshowcmd=1)  Line 259 + 0xe bytes
    MyProg.exe!__tmainCRTStartup()  Line 578 + 0x35 bytes
    MyProg.exe!WinMainCRTStartup()  Line 400
    kernel32.dll!7641e3f3()     
    ntdll.dll!777dcfed()    
    ntdll.dll!777dd1ff()    

这是程序集(-> 是要执行的下一条指令):

            SwapBuffers(hdc);
    009B1B5C  mov         esi,esp 
    009B1B5E  mov         eax,dword ptr [hdc (9BF874h)] 
    009B1B63  push        eax  
    009B1B64  call        dword ptr [__imp__SwapBuffers@4 (0E1040Ch)] 
->  009B1B6A  cmp         esi,esp 
    009B1B6C  call        @ILT+780(__RTC_CheckEsp) (9B1311h) 

【问题讨论】:

【参考方案1】:

看起来你可以在窗口被销毁后访问 HDC,如果你一得到 WM_QUIT 就跳出循环,问题会消失吗?

【讨论】:

不。当我启动程序时,崩溃立即发生。我试着休息一下;在退出后=真;和同样的问题...... 你能添加崩溃的调用堆栈是什么吗?【参考方案2】:

这几乎肯定是驱动程序中的错误。您看不到 hdc 值的原因是因为崩溃的顶部堆栈帧实际上是在 ATKOGL32.dll 中,但由于没有符号,因此调试器会向您显示您的代码。据我所知,ATKOGL32.dll 实际上是 ASUS 驱动程序的 ASUS 包装器,这就是崩溃发生的地方。您可能需要从 amd.com 安装库存 ATI 驱动程序,然后查看崩溃是否仍然存在。

虽然无论您进行什么系列的 OpenGL 调用,驱动程序都不会崩溃,但根据我的经验,崩溃通常是您的程序进行的某种无效调用的结果。从技术上讲,这应该被忽略并设置错误状态,但这并不总是会发生。您可以使用 gDebugger 之类的程序轻松检查任何无效的 OpenGL 调用。

【讨论】:

在我问了这个问题两年多之后,以及在其他技术论坛网站上发了多个帖子后,我仍然无法解决这张卡上的问题。每次重新启动计算机时,我都必须重新安装驱动程序。我确信这张卡有问题......我会接受你的回答,因为你可能是最接近的人。 当我忘记实际上传我的顶点和索引缓冲区时发生了这种情况,所以当我调用glDrawElements 时它们是空的。真的,驱动程序应该忽略这个调用,因为没有数据可以绘制......但是不,Nvidia驱动程序中的访问冲突。也让我发疯,因为我认为我拉入的一个新库正在破坏记忆。【参考方案3】:

无论 hdc 设置什么,它看起来都不是一个合适的值。是否在此调用之前创建了窗口?此应用程序是否涉及任何可能损害 hdc 的多线程?

尝试在 hdc 本身的地址上创建监视,并查看该值何时更改为无效位置,这可能会提示您更改的位置。

【讨论】:

我没有做多线程。 hdc 在崩溃之前似乎永远不会改变。在我的其他计算机上, hdc 的值是相同的(未使用;无法评估表达式)。我安装了一个较旧的显示驱动程序,并且在我重新启动 PC 之前一切正常。然后我必须重新安装驱动程序才能工作。 好吧,哇。我发现这将是开始弄乱硬件后的进一步行动。换个显卡看看有没有用? 我将 HD4850 换成了另一台工作 PC 上的 HD4870。没问题。似乎是 HD4850 中的错误? 尝试将 4850 换到另一台正常工作的 Vista 计算机 - 看看是驱动程序还是卡本身?

以上是关于SwapBuffers 让我的程序崩溃!的主要内容,如果未能解决你的问题,请参考以下文章

XCode Instruments 让我的应用程序崩溃

NSOutlineView -- reloadItem:reloadChildren: 让我的应用程序崩溃

Paypal iOS SDK 返回一个错误并让我的应用程序崩溃

iOS:[self.fetchedResultsController performFetch:&error];让我的应用崩溃

滚动表格视图时应用程序崩溃

当我尝试使用 ArrayAdapter 时,我的应用程序崩溃了