异常屏蔽处理

 

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、付费专栏及课程。

余额充值