異常屏蔽處理

異常屏蔽處理

2013年05月15日 ⁄ 綜合 ⁄ 共 2906字 ⁄ 字型大小 小 中 大 ⁄ 評論關閉

 

 

1。SetErrorMode(SEM_NOGPFAULTERRORBOX),這樣在出現GP錯誤時不會彈出那個對話框,但應用程序會被關閉;  
  2。使用SetUnhandledExcptionFilter設置最外層的異常過濾器,你可以選擇EXCEPTION_EXECUTE_HANDLER、EXCEPTION_CONTINUE_EXECUTION或EXCEPTION_CONTINUE_SEARCH;  
  3。將結構化異常處理__try/__except/__final或C++異常處理try/catch套在你的WinMain外面,自己處理異常。  
   
  無論如何,發生不該出現的異常而不去尋找異常的原因,而是想辦法「屏蔽」異常,不是解決問題的辦法。

 

========================================================================

 

SetUnhandledExceptionFilter 很多情況下會有無效的情況. 所以使用 seh 很多,但今天偶然發現了 vs2008 的crt版本也是引起這種情況的原因之一.

    char s[9];

    _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_DEBUG );//沒用
    _CrtSetReportMode( _CRT_ASSERT, 0 );//沒用

    int i = 0;

    //i = 5/i;

    s[10000024] = '0';
    strcpy(s, "hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");

    printf("%s%d", s,i);

 

這在 vs2008 下是會報錯的,調試時會跳入 gs_report.c 中的  __report_gsfailure ,查了一下發現是微軟自己的 "緩衝溢出檢查" 發現有溢出就立即退出程序了. 並且會清空 SetUnhandledExceptionFilter  設置過的處理函數,具體可見其代碼:

 

    SetUnhandledExceptionFilter(NULL);

    UnhandledExceptionFilter((EXCEPTION_POINTERS *)&GS_ExceptionPointers);

--------------------------------------------------

可以關閉 "緩衝溢出檢查" 來恢復 SetUnhandledExceptionFilter 的功能. 我覺得微軟這樣做實在是過份,活生生把 SetUnhandledExceptionFilter 給廢了--至少yan割了,使得 SetUnhandledExceptionFilter 幾乎沒有存在的價值.

以下這篇文章也提到了.

http://www.diybl.com/course/1_web/webjs/20100710/408222.html

--------------------------------------------------

去除莫名其妙的CRT調用導入

去除莫名其妙的CRT調用導入

www.diybl.com    時間 : 2010-07-10  作者:網路   編輯:Mr.阿布 點擊:  39 [ 評論 ]

   用上了VC9,在做DLL的時候發現即使不用到CRT函數還是會鏈上msvcr90.dll這個鳥東西。特地花了點時間研究了一下如何去掉這些多餘的調用

(1)入口點的CRT初始化

   鏈接器->高級->入口點裡設定自己的DLL入口點,這樣就去掉了CRT初始化用到的一堆鳥調用。

(2)_purecall

   只要有純虛函數的地方就一定會導入這麼個調用。這個東西是在調用純虛函數非法時使用的,我們可以自己定義一個,裡面的內容就是出個錯誤提示然後掛掉或者其他怎麼滴

int __cdecl _purecall (void)
{
  DebugBreak();
  return 0;
}

(3)delete

   當導出的類里有虛的析構函數時,就會導入CRT里的delete。看了一下彙編,發現釋放對象的時候是下面這段代碼:

if (del_type & 2)
{
  for (i = 0; i < N; i++)
    ~XXX();
  delete obj;
}
else
{
  ~XXX();
  if (del_type & 1)
    delete obj;
}
   上面那個是delete[]部分,下面那個是delete部分,所以重載了類里的這兩個操作符,對CRT delete的引用就會變少了。當然,重載了delete就必須重載new了。

(4)徹底消除delete和type_info::_type_info_dtor_internal_method()

   全部使用了自己的delete後發現還是會引用CRT里的delete。找了一下,發現和後面那個call是一起的,似乎是用在RTTI里的。據說VS2005以後是默認打開RTTI的。反正俺們用不著,加上/GR-,上述兩位就拜拜了。

(5)C++異常

   用不著時把它給關了,又去掉了一大堆CRT調用。

(6)_crt_debugger_hook

   用在檢查棧溢出的函數里,只要函數的局部變數一多(譬如放個數組之類的)就會有這樣的代碼。如果確實不需要的話可以關掉緩衝區安全檢查這個選項(/GS-),可以去除這個調用。

   終於,把那些莫名其妙導入的CRT調用去掉了,只剩下用到的幾個。這樣看起來比較清爽乾淨。。。。。。

 

====================================================

 

try,catch,finally執行流程 


try{ 
//1:拋出異常的代碼 
//2:代碼 
}catch(){ 
//3:代碼 
//4:拋出異常 
}finally{ 
//5:代碼 

//6:代碼 
首先要明確的一點是:不管try是否拋出異常,finally語句塊都會執行。 
小心注意6!! 

整個try,catch,finally執行有以下幾種情況: 

1:try語句塊沒有拋出異常。如果是這種情況,程序會執行try,finally以及finally塊之後的代碼; 

2:try語句塊拋出了異常並且catch有匹配的異常。當遇到try裡面拋出的異常後,try塊裡面剩下的代碼就不執行了,跳轉到catch塊裡面。 

這裡又可以分為2種情況。第一種,拋出的異常被後面的catch捕獲,而catch又沒有拋出新的異常,那麼執行順序是1356 ;第二種,如果catch裡面又拋出新的異常,順序是1345,然後將新的異常返回給方法調用者,6就不執行了 ; 

3:try語句塊拋出了異常,但是後面的catch沒有能匹配的異常。那麼會執行try和finally裡面的語句也就是15,然後將該異常返回給方法調用者,不執行6 。 

總結: 

如果異常不能被捕捉的話,finally{}後面的語句就不會執行了,而finally{}一定被執行

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值