2010-04-13 92 views
7

下面的代码会给时在Windows 7 32位运行硬故障:64位异常静默失败

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位,我刚刚得到这个在输出窗口:0000005:访问 冲突写入位置在00000000 0x13929384 在将Test.exe

第一次机会异常。
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

+0

我不认为只是为64位编译时的选项? – jalf 2010-04-14 10:49:16

+0

为x64编译并不是一个真正的选择,我们的源代码包含大约100万行代码,并且有相当数量的汇编程序。将其与通过QA等运行两个单独构建的额外成本相结合。 – 2010-04-15 08:57:03

+1

另请参见[WindowProc回调函数]的备注部分(http://msdn.microsoft.com/en-us/library/windows/desktop/ms633573% 28v = vs.85%29.aspx) – wimh 2014-01-20 13:08:53

回答

1

OK,我已经收到了回信从微软:

你好,

感谢您的报告。我发现了 这是一个Windows问题,而 有一个可用的修复程序。请 请参阅 http://support.microsoft.com/kb/976038 对于您可以安装,如果您 希望的修复。

@Skute:注意要 继续执行程序 兼容性助手会问一次 如果该程序应该被允许,之后,它 总是被允许的,所以,可能是 混乱的原因行为 你正在看。

帕特布伦纳的Visual C++库 发展

所以解决方法是要么确保安装修补程序,或与__try/__except块应用程序包的每个WndProc的。

+0

你能提供更多的信息你在哪里使用__try __except?是否有可能在C++应用程序的catch块中从WindowProc中捕获异常。关于修补程序我在注册表中设置DisableUserModeCallbackFilter为1,最好的是FATAL_USER_CALLBACK_EXCEPTION,不是我的例外。 – Demion 2013-03-08 01:21:56

+0

在你的'WNDPROC'函数中使用'__try''__except',或者如果你使用的是MFC的'CWnd :: OnMsg'函数(我认为这可能是错误的) 。 – 2013-03-08 13:29:44

+0

是否有可能从WindowProc抛出异常,而不是在WindowProc中捕获? – Demion 2013-03-08 13:37:07

3

有而堆栈退绕的访问冲突异常被引发另一个异常。正在被吞咽,导致AV消失。您需要了解哪些代码正在执行此操作。调试+异常,检查投掷框中的Win32异常。调试器将停止第一个,继续。当它再次停止时检出调用堆栈。如果无法弄清楚,请将其添加到您的问题中。

+1

仅当引发AV异常时才会出现激活上下文异常。 – 2010-04-14 07:35:33

0

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

0

我会冒险猜测这个问题实际上与SEH在x64中的工作方式有关。如果您的异常必须在堆栈退出时通过内核模式返回,那么您坚持的是设计行为:The case of the disappearing OnLoad exception。 Windows为您“处理”您的例外; hot-fix是一种解决方法,可以使特定的x64应用像x86一样崩溃。

0

我做了一些功课,找到这个: 异常被窗口捕获。下面是堆栈和拆卸:

stack and disassembling when wndproc get called