2010-04-13 133 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