7

以下代码在 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
}

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

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-消息

4

5 回答 5

3

在因访问冲突异常而展开堆栈时引发了另一个异常。被吞下,导致 AV 消失。您需要找出执行此操作的代码。调试 + 异常,选中 Win32 异常的抛出框。调试器将在第一个停止,继续。再次停止时检查调用堆栈。如果您无法弄清楚,请将其添加到您的问题中。

于 2010-04-13T17:22:34.160 回答
1

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

你好,

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

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

Pat Brenner Visual C++ 库开发

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

于 2010-07-14T08:16:05.117 回答
0

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

于 2010-07-10T20:44:01.897 回答
0

我冒昧地猜测这个问题实际上与 SEH 在 x64 中的工作方式有关。如果您的异常必须在堆栈展开时通过内核模式恢复,那么您会遇到设计行为:OnLoad exception 消失的情况。Windows 正在为您“处理”您的异常;热修复是一种使特定 x64 应用程序崩溃的解决方法,就像 x86 一样。

于 2010-12-09T15:44:18.493 回答
0

我做了一些功课来找到这个:异常被windows捕获。这是堆栈和拆卸:

调用 wndproc 时的堆栈和反汇编

于 2013-06-26T06:05:05.497 回答