2013-02-26 31 views
2

我正在做SEH的一些實驗。在我的代碼中,我在__try子句中寫了錯誤原因塊,在__except()中寫了一個處理程序。使用SEH時觀察到的不同行爲(結構化異常處理)

__try{ 
Test *pTest = 0; 
int k = pTest->GetValue(); 
cout << "continue after exception" << endl; 
} 
__except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION,EXCEPTION_EXECUTE_HANDLER) 
{ 
cout << "caught!!" << endl; 
} 
cout << "Exception handled" << endl; 

的第二個參數__except()是其中任一 -

EXCEPTION_CONTINUE_SEARCH異常無法識別。繼續搜索堆棧中的處理程序,首先是包含try-except語句,然後是具有次高優先級的處理程序。

EXCEPTION_CONTINUE_EXECUTION異常被識別但被駁回。在發生異常的地方繼續執行。

EXCEPTION_EXECUTE_HANDLER異常被識別。通過執行__except複合語句將控制權移交給異常處理程序,然後在異常發生時繼續執行。

當我使用EXCEPTION_CONTINUE_EXECUTION/EXCEPTION_EXECUTE_HANDLER時,它不會在發生異常時繼續執行(可能是我誤解了異常發生點的含義)。 當我在調試模式下運行時,輸出爲

caught 
Exception handled 

當我在釋放模式運行,輸出

continue after exception 
Exception handled 

我不明白爲什麼它是表現不同。任何人都請幫忙。

+0

秀的GetValue()方法的內容 – ixSci 2013-02-26 11:29:19

+0

顯示我們Test'的'定義和展示我們如何調試和發佈選項對於SEH和C++異常不同,也有該選項。或者更好地向我們展示在發佈模式下對'__try {}'塊的反彙編。它可能有更好的線索。 – 2013-02-26 11:31:10

+0

,我怕'pTest'是一個指向類,它可能不需要爲了執行'的GetValue(被取消引用)'和編譯器認識到,當優化在釋放模式被啓用。或者,甚至可能將'GetValue()'看作無用的,並且不會生成任何代碼來調用它。編譯器也可能會發現,取消引用NULL指針會導致未定義的行爲,並決定在編譯時通過擰你的代碼來懲罰它,它完全有權這樣做。 'gcc'因爲這樣做而臭名昭着。 – 2013-02-26 11:53:05

回答

4

@Joachim正確地指出了有關逗號操作問題。

我想,__except()應該是這樣的:

__except((GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION) ? 
     EXCEPTION_EXECUTE_HANDLER : 
     EXCEPTION_CONTINUE_SEARCH) 

這將使如果異常訪問衝突異常處理程序執行。如果不是,則例外將傳播到最接近的外部__try(如果有的話)。

我很擔心pTest是一個指向類的指針,爲了執行GetValue()並且編譯器可以識別在釋放模式下啓用優化時可能不需要解除引用。或者,甚至可能將GetValue()視爲無用,並且不會生成任何代碼來調用它。編譯器也可能會發現,取消引用NULL指針會導致未定義的行爲,並決定在編譯時通過擰你的代碼來懲罰它,它完全有權這樣做。例如,gcc因此而臭名昭着。

+0

我已根據您的建議編輯了代碼。但即使發生異常,EXCEPTION_ACCESS_VIOLATION也不顯示字符串「抓住!!」在發佈模式 – 2013-02-26 11:19:56

1

表達

GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION,EXCEPTION_EXECUTE_HANDLER 

不會做你希望它是什麼。它所做的是比較GetExceptionCode()EXCEPTION_ACCESS_VIOLATION的結果,但整個表達式的結果是EXCEPTION_EXECUTE_HANDLER

詳細瞭解逗號運算符at Wikipedia

你想要做的是什麼,大概是:

GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION || GetExceptionCode() == EXCEPTION_EXECUTE_HANDLER 
+0

'GetExceptionCode()'不會返回'EXCEPTION_EXECUTE_HANDLER'。 – 2013-02-26 11:06:22

+0

感謝Joachim回答。但我仍然無能爲力,爲什麼它在調試/發佈模式下表現不同。 – 2013-02-26 11:13:11