Question

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

Was it helpful?

Solution 2

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.

OTHER TIPS

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.

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.

I would venture a guess that the problem is actually related to how SEH works in x64. If your exception has to go back up through kernel-mode while the stack is unwinding, then what you're stuck with is by-design behavior: The case of the disappearing OnLoad exception. Windows is "handling" your exception for you; the hot-fix is a workaround to make specific x64 apps crash just like x86 does.

I did some homework to find this: the exception is caught by windows. Here are stacks and disassembling:

stack and disassembling when wndproc get called

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top