代码之家  ›  专栏  ›  技术社区  ›  Mark Ingram

WndProc中的64位异常会自动失败

  •  7
  • Mark Ingram  · 技术社区  · 15 年前

    在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
    }
    

    0x13929384出现第一次机会异常 在Test.exe中:0xc000005:Access
    0x77c6ee42处的第一次机会异常 执行的时间。

    原因是什么?我知道这是硬件的例外( http://msdn.microsoft.com/en-us/library/aa363082.aspx ),但为什么在32位和64位下运行时会有差异?我该怎么做才能正确处理这些错误呢?因为它们真的应该被捕获和修复,而不是像现在这样,Windows只是继续向应用程序发送消息,然后让它运行(所以用户和开发人员完全不知道实际发生了什么问题)。

    更新: SetUnhandledExceptionFilter 但在x64上,对于WndProc内部的硬件异常,不会调用这种方法。有人知道这方面的信息吗,或者有解决方法吗?

    更新2:
    https://connect.microsoft.com/VisualStudio/feedback/details/550944/hardware-exceptions-on-x64-machines-are-silently-caught-in-wndproc-messages

    5 回复  |  直到 15 年前
        1
  •  3
  •   Hans Passant    15 年前

    在为访问冲突异常解除堆栈缠绕时,引发了另一个异常。正被吞咽,导致AV消失。您需要找出是什么代码在执行此操作。调试+异常,选中Win32异常的抛出框。调试器将在第一个调试器上停止,请继续。再次停止时检查调用堆栈。如果你想不出来,就把它加到你的问题里。

        2
  •  1
  •   Mark Ingram    14 年前

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

    谢谢你的报告。我发现了 这是Windows的问题,而且 看见 http://support.microsoft.com/kb/976038 如果需要,可以安装修复程序

    如果程序被允许 继续执行,然后 总是被允许的,所以 混乱行为的原因 你看到了。

    Pat Brenner Visual C++库 发展

    因此,解决方法是要么确保安装了修补程序,要么在应用程序中用一个\uuu try/\uu except块包装每个WndProc。

        3
  •  0
  •   Mark Ingram    14 年前

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

        4
  •  0
  •   Granger    14 年前

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

        5
  •  0
  •   mr.dot    12 年前

    我做了一些家庭作业来发现:

    stack and disassembling when wndproc get called