clq

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

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调用去掉了,只剩下用到的几个。这样看起来比较清爽干净。。。。。。

posted on 2012-01-22 13:22  clq  阅读(2855)  评论(3编辑  收藏  举报