在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上尝试这个,我只是在输出窗口中得到这个:
Test.exe中0x13929384的第一次机会exception:0xC0000005:访问冲突写入位置0x00000000。
Test.exe中0x77c6ee42的第一次机会exception:0xC0150010:当前正在执行的线程未激活正在激活的激活上下文。
这是什么原因? 我知道这是一个硬件exception( http://msdn.microsoft.com/en-us/library/aa363082.aspx ),但为什么在32位和64位下运行的差异呢? 我能做些什么来正确处理这些错误? 因为它们应该真正被困住和修复,而不是正在发生什么,Windows正在进行向应用程序发送消息,让它运行(所以用户和开发人员完全不知道实际发生的任何问题)。
更新:我们的常规崩溃报告软件使用SetUnhandledExceptionFilter
但不会在x64中调用WndProc中的硬件exception。 有没有人有任何这方面的信息,或解决方法?
Update2:我已经在Microsoft Connect上报告了这个问题:
https://connect.microsoft.com/VisualStudio/feedback/details/550944/hardware-exceptions-on-x64-machines-are-silently-caught-in-wndproc-messages
当堆栈正在解除访问冲突异常时,还有另一个异常。 哪些被吞下,导致AV消失。 你需要找出代码是做什么的。 调试+异常,检查投掷框为Win32异常。 调试器将停止在第一个,继续。 当它再次停止时检出调用堆栈。 把它添加到你的问题,如果你无法弄清楚。
好的,我收到了微软的回复:
你好,
感谢您的报告。 我发现这是一个Windows问题,并有一个可用的修复程序。 请参阅http://support.microsoft.com/kb/976038以获得可以根据需要安装的修复程序。
@Skute:请注意,程序兼容性助手会询问一次程序是否应该被允许继续执行,在此之后,程序兼容性助手将永远被允许,这可能是您所看到的混淆行为的原因。
Pat Brenner Visual C ++图书馆开发
因此,解决方法是确保安装了修补程序,或者用__try / __except块将每个WndProc包装在应用程序中。
我们设法解决这个问题的唯一方法是在应用程序中的每个WndProc回调周围放置一个__try / __except。 然后,我们将异常路由到异常处理程序。 太可怕了,但看起来这是Windows本身的问题。 还在等待微软回到我们身边。
我想冒险猜测,这个问题实际上与SEH在x64中的工作方式有关。 如果你的异常必须通过内核模式返回,而堆栈解绕,那么你坚持的是设计行为: 消失OnLoad异常的情况 。 Windows正在为您处理您的例外情况; 热修复是一种解决方法,使特定的x64应用程序崩溃就像x86一样。
我做了一些功课找到这个:窗户抓住了例外。 这里是堆叠和拆解: