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