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

时间:2010-04-13 16:46:48

标签: c++ windows exception-handling 64-bit 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
}

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

  

第一次机会异常在0x13929384   在Test.exe中:0xC0000005:Access   违规写入位置0x00000000   0x77c6ee42处的第一次机会异常   在Test.exe中:0xC0150010:   激活上下文被停用   当前线程无效   执行。

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

更新 我们的常规崩溃报告软件使用SetUnhandledExceptionFilter但是在W64上的硬件异常不会在x64上调用。有没有人有这方面的信息或解决方法?

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

5 个答案:

答案 0 :(得分:3)

在为访问冲突异常解除堆栈时会引发另一个异常。被吞下,导致AV消失。您需要找出正在执行此操作的代码。 Debug + Exceptions,检查Win32 Exceptions的Thrown框。调试器将在第一个停止,继续。再次停止时检查调用堆栈。如果你想不出来,请将它添加到你的问题中。

答案 1 :(得分:1)

好的,我收到了微软的回复:

  

您好,

     

感谢您的报告。我发现了   这是一个Windows问题,并且   有一个热修复可用。请   看到   http://support.microsoft.com/kb/976038   对于您可以安装的修复程序   愿望。

     

@Skute:注意该程序   兼容性助理会询问一次   如果该程序应该被允许   继续执行,然后继续执行   将永远被允许,所以这可能是   造成混淆行为的原因   你看到了。

     

Pat Brenner Visual C ++库   发展

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

答案 2 :(得分:0)

我们设法解决此问题的唯一方法是在应用程序中的每个WndProc回调周围放置__try / __except。然后我们将异常路由到我们的异常处理程序。可怕,但看起来这是Windows本身的一个问题。仍在等待微软回复我们。

答案 3 :(得分:0)

我猜想这个问题实际上与SEH在x64中的工作方式有关。如果您的异常必须在堆栈展开时通过内核模式返回,那么您所依赖的是设计行为:The case of the disappearing OnLoad exception。 Windows是"处理"你的例外;热修复是一种解决方法,可以使特定的x64应用程序像x86一样崩溃。

答案 4 :(得分:0)

我做了一些功课来找到这个: 窗口捕获异常。这是堆栈和拆解:

stack and disassembling when wndproc get called