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 让我的程序崩溃!的主要内容,如果未能解决你的问题,请参考以下文章
NSOutlineView -- reloadItem:reloadChildren: 让我的应用程序崩溃
Paypal iOS SDK 返回一个错误并让我的应用程序崩溃
iOS:[self.fetchedResultsController performFetch:&error];让我的应用崩溃