简体   繁体   中英

SwapBuffers crashing my program!

I have an OpenGL program that works on all of my computers but one. It's a desktop with Vista 64 and a Radeon HD4850. The problem seems to be in my call to SwapBuffers(hdc).

It compiles fine and then gives me an exception:

Unhandled exception at 0x00000000 in Program.exe: 0xC0000005: Acces violation.

Using VC++ to break before the call to SwapBuffers shows hdc's value to be:

0xfe011734 {unused=???} CXX0030: Error: expression cannot be evaluated

Anyone have a clue what could be happening? Is there something about SwapBuffers that would change from one PC to the next? I've gotten it to work on XP32, XP64 and a (different) 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.
    } 

The drivers on the problematic system (HD4850) are up-to-date. I've run, and wrote, the program on another Vista64 system with a Radeon HD4870, also with up-to-date drivers. As far as I know, the drivers for these two cards are nearly identical as both are in the HD48xx series. For that reason it seems odd that the GPU is causing the problem.

Anyway, am I wrong or is this a memory issue? (Access violation)

Also, if I remove the call to SwapBuffers(hdc), the program runs seemingly well, although nothing is drawn, of course, because the framebuffers are never swapped. But it is at least stable.

Call stack (-> is stack 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()    

Heres the assembly (-> is the next instruction to be executed):

            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) 

It looks like you could be accessing the HDC after the window has been destroyed, does the problem disappear if you break out of the loop as soon as you get WM_QUIT?

Whatever hdc is set to, it doesn't look to be a proper value. Is the window created before this call? Is there any multithreading involved with this application that could hurt hdc?

Try creating a watch on the address of hdc itself, and see when the value is changed to be an invalid location, that might give you a hint as to where it changes.

We had the same (or at least very similar) issue. It turns out the Dell Nahimic service and Asus Sonic Suite use some weird injection code. For us the problem solved itself after disabling these services.

Source: https://github.com/glfw/glfw/issues/1682

This is almost definitely a bug in the drivers. The reason why you can't see the value of hdc is because the top stackframe for the crash is actually inside ATKOGL32.dll but since there are no symbols for that the debugger shows you your code. As far as I can tell ATKOGL32.dll is actually an ASUS wrapper for the ATI driver and that's where the crash happens. You might want to install stock ATI drivers from amd.com and see if the crash still persists.

While the driver should never crash no matter what series of OpenGL calls you make, in my experience usually the crashes are the result of some kind of invalid call that your program makes. Technically this should just be ignored and the error state set but thats not always what happens. You can check for any invalid OpenGL calls easily by using a program like gDebugger.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM