WndProc中的64位异常默默地失败

Mar*_*ram 7 c++ windows 64-bit exception-handling seh

在Windows 7 32位下运行时,以下代码将导致硬故障:

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
}
Run Code Online (Sandbox Code Playgroud)

但是,如果我在Windows 7 64bit上尝试这个,我只是在输出窗口中得到这个:

Test.exe中0x13929384处的第一次机会异常:0xC0000005:访问冲突写入位置0x00000000.
Test.exe中0x77c6ee42的第一次机会异常:0xC0150010:当前执行的线程未激活的激活上下文无效.

这是什么原因?我知道这是一个硬件异常(http://msdn.microsoft.com/en-us/library/aa363082.aspx),但为什么在32位和64位下运行时有区别?我能做些什么来正确处理这些错误?因为它们应该被捕获和修复,而不是目前发生的事情,Windows只是继续向应用程序发送消息并让它运行(因此用户和开发人员完全没有意识到实际发生了任何问题).

更新: 我们的常规崩溃报告软件使用SetUnhandledExceptionFilter但不会在x64上调用WndProc中的硬件异常.有没有人有关于此的任何信息,或解决方法?

Update2: 我在Microsoft Connect上报告了这个问题:https:
//connect.microsoft.com/VisualStudio/feedback/details/550944/hardware-exceptions-on-x64-machines-are-silently-caught-in-wndproc-消息

Mar*_*ram 1

好的,我已经收到微软的回复:

你好,

感谢您的报告。我发现这是一个 Windows 问题,并且有可用的修补程序。如果您愿意,请参阅 http://support.microsoft.com/kb/976038 以获取可以安装的修复程序。

@Skute:请注意,程序兼容性助手会询问一次是否应允许程序继续执行,之后将始终允许执行,因此这可能是您所看到的令人困惑的行为的原因。

Pat Brenner Visual C++ 库开发

因此,解决方法是确保安装了修补程序,或者使用 __try / __ except 块将应用程序中的每个 WndProc 包装起来。