WndProc中的64位异常会自动失败
在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的第一次机会异常: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-messages
当堆栈正在被解除访问冲突异常时,会引发另一个异常。 正在被吞咽,导致AV消失。 您需要了解哪些代码正在执行此操作。 调试+异常,检查投掷框中的Win32异常。 调试器将停止第一个,继续。 当它再次停止时检出调用堆栈。 如果无法弄清楚,请将其添加到您的问题中。
好的,我收到了微软的回复:
你好,
感谢您的报告。 我发现这是一个Windows问题,并且有一个可用的修复程序。 请参阅http://support.microsoft.com/kb/976038以获取可以根据需要安装的修复程序。
@Skute:请注意,程序兼容性助手会询问是否允许程序继续执行,并且在此之后,程序兼容性助手将始终被允许,这可能是您所看到的令人困惑的行为的原因。
Pat Brenner Visual C ++图书馆开发
因此,解决方法是确保安装了修补程序,或者使用__try / __except块将每个WndProc包装在应用程序中。
我们设法解决这个问题的唯一方法是在应用程序中的每个WndProc回调周围放置一个__try / __except。 然后我们将异常发送到异常处理程序。 可怕的,但看起来这是Windows本身的问题。 仍在等待微软回到我们身边。
链接地址: http://www.djcxy.com/p/45389.html