c++異常捕獲


概念:
“C++異常”就是 try{}catch(...){}
“SEH異常”就是 __try{} __except(-1/0/1){}
(關於這兩種異常,如有不了解的地方,網上有很多資料可以參考)


目前微軟所有的VC編譯器(從VC6到VC2010),都默認是打開對C++異常的編譯支持的(位於項目選項中的“代碼生成”->啟用C++異常:/EHsc,VC6是Enable Exception handling)


(以下需要仔細閱讀)
在VC6中,對EXE工程是同時默認開啟“C++異常可以捕獲SEH異常”。在此條件下,用“C++異常”也可以捕獲向非法地址的讀寫等基本的Windows異常。
如:try{ int *a=0; *a=100; }catch(...){printf("excption!");},執行到*a=100時,會跳轉到catch塊,並執行printf。


但是,VC6建立的DLL或其他非EXE工程,如果是Release模式,並且編譯時,啟用了代碼自動優化,那么結果就變成了
只啟用了“C++異常”,即“C++異常無法捕獲SEH異常”。這樣的一個后果是,在DLL中,即使
像這樣用try{ int *a=0; *a=100; }catch(...){printf("excption!");}保護代碼,
當代碼執行到*a=100非法地址賦值語句時,catch(...)卻什么都捕獲不到,會直接造成程序崩潰。
除非明確使用“SEH異常”__try...__except(1)..,才能捕獲到這種Windows異常。


相應的解決辦法:
對於從VC7開始以及以后的VC++,在“代碼生成”->“啟用C++異常”處,均有第三個選項:“有效,但有SEH異常(/EHa)”,
這樣就是可以讓程序“使用C++異常也能夠捕獲到SEH異常”。
這樣無論是在EXE還是DLL中,try{}catch(...){}同樣可以捕獲Windows異常。


對於VC6的非EXE工程,有以下兩個方法,來用try..catch..捕獲Windows的SEH異常:
1、通過關閉編譯時的優化(禁用或者只使用Default級別,個人感覺是因為VC6的編譯器不是非常完善)。
2、通過在當前工程的編譯選項中,手工加上 /EHa 參數。這個編譯選項是沒有界面可以去設置的,只能手工添加。
這兩個方法選擇任何一個都可以。建議使用第二個方法。


另外要注意“C++異常”與“SEH異常”無法同時在同一個函數中混用。
更多 0
最好不要用C++異常去捕獲SEH異常。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM