tags:

views:

798

answers:

3

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)
+1  A: 

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 ?

Michael
Nope. The crash happens immediately when I start the program. I tried putting a break; in after quit = true; and same problem...
Tony R
Can you add what the crashing callstack is?
Michael
A: 

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.

Andrei Krotkov
I'm not doing multithreading. hdc seems to never change before the crash. On my other computers the value of hdc is the same (unused; expression cannot be evaluated).I installed an older display driver, and things work until I restart the PC. Then I have to reinstall the driver for it to work.
Tony R
Alright, wow. My further actions upon discovering that would be to start messing with the Hardware. Swap out the video card, see if that helps?
Andrei Krotkov
I swapped my HD4850 with the HD4870 on my other working PC. No problems. Appears to be a bug in the HD4850?
Tony R
Try swapping in the 4850 into the other, working Vista computer - see if it's the drivers or the card itself?
Andrei Krotkov
A: 

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.

Lucas