[英]SwapBuffers crashing my program!
我有一个 OpenGL 程序,可以在我的所有计算机上运行,但只有一台。 它是具有 Vista 64 和 Radeon HD4850 的台式机。 问题似乎出在我对 SwapBuffers(hdc) 的调用中。
它编译得很好,然后给了我一个例外:
Program.exe 中 0x00000000 处的未处理异常:0xC0000005:访问冲突。
在调用 SwapBuffers 之前使用 VC++ 中断显示 hdc 的值为:
0xfe011734 {unused=???} 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 导致问题似乎很奇怪。
无论如何,我错了还是这是 memory 问题? (访问冲突)
此外,如果我删除对 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)
看起来您可以在 window 被破坏后访问 HDC,如果您在获得 WM_QUIT 后立即跳出循环,问题会消失吗?
无论 hdc 设置为什么,它看起来都不是一个合适的值。 window 是在此调用之前创建的吗? 此应用程序是否涉及任何可能损害 hdc 的多线程?
尝试在 hdc 本身的地址上创建一个监视,并查看该值何时更改为无效位置,这可能会提示您更改的位置。
我们有相同(或至少非常相似)的问题。 事实证明,戴尔 Nahimic 服务和华硕 Sonic Suite 使用了一些奇怪的注入代码。 对我们来说,禁用这些服务后问题就自行解决了。
这几乎肯定是驱动程序中的错误。 您看不到 hdc 值的原因是因为崩溃的顶部堆栈帧实际上在 ATKOGL32.dll 内部,但由于没有符号,调试器会向您显示您的代码。 据我所知,ATKOGL32.dll 实际上是 ATI 驱动程序的华硕包装,这就是崩溃发生的地方。 您可能想从 amd.com 安装库存 ATI 驱动程序,看看崩溃是否仍然存在。
尽管无论您进行什么系列的 OpenGL 调用,驱动程序都不应崩溃,但根据我的经验,崩溃通常是您的程序进行某种无效调用的结果。 从技术上讲,这应该被忽略,并且设置了错误 state 但这并不总是会发生。 您可以使用 gDebugger 之类的程序轻松检查任何无效的 OpenGL 调用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.