views:

198

answers:

3

The following code will give a hard fail when run under Windows 7 32bit:

void CTestView::OnDraw(CDC* /*pDC*/)
{
    *(int*)0 = 0; // Crash

    CTestDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    if (!pDoc)
        return;

    // TODO: add draw code for native data here
}

However, if I try this on Windows 7 64bit, I just get this in the output window:

First-chance exception at 0x13929384 in Test.exe: 0xC0000005: Access violation writing location 0x00000000.
First-chance exception at 0x77c6ee42 in Test.exe: 0xC0150010: The activation context being deactivated is not active for the current thread of execution.

What is the reason for this? I know it's a hardware exception (http://msdn.microsoft.com/en-us/library/aa363082.aspx), but why the difference when ran under 32bit and 64bit? And what can I do to correctly handle these kind of errors? Because they should really be trapped and fixed, as opposed to what currently happens which is Windows just carries on pumping messages to the application and let's it run (so the user and the developers are completely unaware any problems have actually occurred).

Update: Our regular crash reporting software uses SetUnhandledExceptionFilter but that doesn't get called on x64 for hardware exceptions inside a WndProc. Does anyone have any information on this, or a workaround?

Update2: I've reported the issue at Microsoft Connect:
https://connect.microsoft.com/VisualStudio/feedback/details/550944/hardware-exceptions-on-x64-machines-are-silently-caught-in-wndproc-messages

+3  A: 

There's another exception being raised while the stack is being unwound for the Access Violation exception. Which is being swallowed, causing the AV to disappear. You'll need to find out what code is doing this. Debug + Exceptions, check the Thrown box for Win32 Exceptions. The debugger will stop on the first one, continue. Check out the call stack when it stop again. Add it to your question if you can't figure it out.

Hans Passant
The activation context exception only occurs when the AV exception is thrown.
Mark Ingram
A: 

The only way we've managed to work around this problem is to put a __try / __except around each WndProc callback in the application. We then route the exception to our exception handler. Horrible, but looks like it's a problem with Windows itself. Still waiting on Microsoft to get back to us.

Mark Ingram
A: 

OK, I've received a reply from Microsoft:

Hello,

Thanks for the report. I've found out that this is a Windows issue, and there is a hot fix available. Please see http://support.microsoft.com/kb/976038 for a fix that you can install if you wish.

@Skute: note that the Program Compatibility Assistant will ask once if the program should be allowed to continue to execute, and after that it will always be allowed, so that may be the cause of the confusing behavior you are seeing.

Pat Brenner Visual C++ Libraries Development

So the workaround is either make sure the hotfix is installed, or wrap each WndProc in your application with a __try / __except block.

Mark Ingram