我有一个OpenGL程序,除了一台电脑之外,它可以在我所有的电脑上运行。这是一台Vista 64和Radeon HD 4850的台式机。问题似乎出在我对SwapBuffers(hdc)的调用上。
它编译得很好,然后给我一个异常:
Program.exe中0x 00000000处出现未处理的异常:数据类型:访问违规。
使用VC++在调用SwapBuffers之前中断,显示hdc的值为:
0xfe 011734 {未使用=???} CXX 0030:错误:无法计算表达式
有人知道会发生什么吗?有没有什么关于交换缓冲区,将改变从一个PC到下一个?我已经得到了它的工作在XP 32,XP 64和(不同的)Vista 64。
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.
}
有问题的系统(HD 4850)上的驱动程序是最新的。我在另一个装有Radeon HD 4870的Vista 64系统上运行并编写了该程序,也使用了最新的驱动程序。据我所知,这两个卡的驱动程序几乎完全相同,因为它们都在HD 48 xx系列中。出于这个原因,GPU导致问题似乎很奇怪。
无论如何,我错了还是这是一个内存问题?(访问冲突)
此外,如果我删除对SwapBuffers(hdc)的调用,程序看起来运行得很好,尽管没有绘制任何内容,当然,因为帧缓冲区从来没有交换过。
调用堆栈(-〉是堆栈指针):
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)
4条答案
按热度按时间cygmwpex1#
看起来你可能在窗口被破坏后访问HDC,如果你一得到WM_QUIT就跳出循环,问题会消失吗?
9udxz4iz2#
这几乎可以肯定是驱动程序中的一个bug。你看不到hdc值的原因是因为崩溃的顶层堆栈帧实际上在ATKOGL32.dll中,但由于没有相应的符号,调试器会向你显示代码。据我所知,ATKOGL32.dll实际上是ATI驱动程序的华硕 Package 程序,这就是崩溃发生的地方。您可能需要从www.example.com安装常用的ATI驱动程序amd.com,并查看崩溃是否仍然存在。
虽然驱动程序应该永远不会崩溃,无论你做了什么系列的OpenGL调用,在我的经验,通常崩溃的结果是某种类型的无效调用,你的程序。从技术上讲,这应该只是忽略和错误状态设置,但这并不总是发生。你可以检查任何无效的OpenGL调用很容易通过使用程序,如gDebugger。
k4aesqcs3#
无论hdc被设置为什么,它看起来都不是一个正确的值。窗口是在调用之前创建的吗?这个应用程序是否涉及到任何可能会损害hdc的多线程?
尝试在hdc本身的地址上创建一个监视器,并查看该值何时更改为无效位置,这可能给予您它在何处更改。
ru9i0ody4#
我们遇到了同样的(或者至少是非常相似的)问题。原来戴尔Nahimic服务和华硕Sonic套件使用了一些奇怪的注入代码。对我们来说,禁用这些服务后问题自行解决了。
来源:https://github.com/glfw/glfw/issues/1682