paip.提升用户体验---gcc c++ try catch不能捕获异常的解决--使用 SEH Ca6
作者Attilax , EMAIL:1466519819@qq.com
来源:attilax的专栏
地址:http://blog.csdn.net/attilax
环境:xp sp3 ,ide是qt creator2.8.1 ,,内建的编译器是gcc 4.8 (gcc.exe -v)
现象以及原因:
/////////////////////////////////////////////////////
不能捕获 "index out of range", 下标越界异常...经过测试,只能捕获手动throw出来的异常..使用windows的__try ____except,,QT 的QT_try QT_catch 都是不行....c++标准 try, catch, throw是C++标准里的语法,标准只要求try catch捕获throw出来的异常,并不要求捕获系统异常(如被0除,段错误,CPU异常等)。从C++层面来说,不要期望try, catch能捕获系统异常。
解决方法:使用SEH捕获异常:
///////////////////////////////
调用操作系统提供的SEH异常处理流程走ok兰....代码比较多,参考:Structured Exception Handling and MinGW 这个文章...有源码下载.使用方法如下..
__seh_try {
puts(" ---pre");
QStringList li;
qDebug()<<li.at(1);
int n=5/0;
puts(" ---after");
}
__seh_except(info, context)
{
puts(" catch .....ok ");
qDebug()<<"info->ExceptionCode--"<<info->ExceptionCode;
qDebug()<<"--info->context--"<<context;
if(info->ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
fputs("Access violation exception raised.\n", stderr);
}
__seh_end
可以使用SEH捕获的异常如下:
///////////////////////////////////////////////////////////
除0异常
访问一个不可用的内存地址(例如,NULL指针);
下标越界异常
其它异常等。
常见异常码(exception code)
//////////////////////////////////////////
每一个SEH异常都有一个与其相关联的异常码(exception code)
ERROR_NOACCESS (998) or EXCEPTION_ACCESS_VIOLATION (0xC0000005, 0n3221225477)
EXCEPTION_INT_DIVIDE_BY_ZERO (0xC0000094, 0n3221225620)
ERROR_STACK_OVERFLOW (1001) or EXCEPTION_STACK_OVERFLOW (0xC00000FD, 0n3221225725)
C++ exception (0xE06D7363, 0n3765269347)
ERROR_DLL_INIT_FAILED (0x8007045A)
捕获系统异常原理:
////////////
这得益于硬件体系中的中断机制. 简而言之, 当发生整数除 0 之类的错误时, 硬件会触发中断, 这时操作系统会根据上下文查出是哪个进程不给力了, 然后给这个进程发出一个信号. ????这次就不是 C++ 标准了, 而是 POSIX 标准
异常处理过程, 但毕竟是函数都会有调用栈, 能返回. 假如在handle_div_0中不调用exit自寻死路, 而是选择返回, 那么程序会怎么样呢? 运行一下, 当出现错误时,stderr会死循环般地刷屏.
????实际上, 当错误发生时, 操作系统会在当前错误出现处加载信号处理函数的调用栈帧, 并且把它的返回地址设置为出错的那条指令之前, 这样看起来就像是出错之前的瞬间调用了信号处理函数. 当信号处理函数返回时, 则又会再次执行那条会出错的指令, 除非信号处理函数能通过某些特别的技巧修复指令, 否则退出时会重蹈覆辙.
修复指令这种事情简直是天方夜谭, 所以选择输出一跳错误语句并退出也算是不错的方法. 在 C 语言时代, 还可以通过setjmp和longjmp来跳转程序流程. 不过setjmp和longjmp操作起来太不方便了,
其它捕获异常方法VEH,CRT
向量化异常处理(Vectored Exception Handling)
向量化异常处理(VEH)是结构化异常处理的一个扩展,它在Windows XP中被引入。
你可以使用AddVectoredExceptionHandler()函数添加一个向量化异常处理器,VEH的缺点是它只能用在WinXP及其以后的版本,因此需要在运行时检查AddVectoredExceptionHandler()函数是否存在。
除了SEH异常和C++类型化异常,C运行库(C runtime libraries, CRT)也提供它自己的错误处理机制,在你的程序中也应该考虑使用它。
C++信号处理C++ Singal Handling
C++提供了被称为信号的中断机制。你可以使用signal()函数处理信号。
Visual C++提供了6中类型的信号:
l SIGABRT Abnormal termination
l SIGFPE Floating-point error
l SIGILL Illegal instruction
l SIGINT CTRL+C signal
l SIGSEGV Illegal storage access
l SIGTERM
获取异常信息 Retrieving Exception Information汇编法
参考:
paip.c++ gcc 不能捕获exception异常的解决 - attilax的专栏 - 博客频道 - CSDN.NET.htm
Structured Exception Handling and MinGW - ProgrammingUnlimited.Net.htm
【翻译】异常和异常处理(windows平台) - 进步一点点 - 博客园.htm
***44,347 AddVectoredExceptionHandler function (Windows).htm
***7,441 c++ exception error seh demo.cpp
***18,848 c++ 捕获所有异常的写法_空空软件_百度空间.htm
***102,936 C++-MinGW能支持VC的__try的语法吗? - 德问 编程社交问答.htm
***46,332 C++?中捕获整数除零错误_carlosstephen_新浪博客.htm
***130,760 C++编译器无法捕捉到的8种错误 - 博客 - 伯乐在线.htm
顾问C语言的异常机制 setjump longjump函数【转】 - 红联Linux门户 - 中国领先的Linux技术网站 - 网站导航 - Linux通用技术 - Linux编程与内核.htm
***0 f.txt
***74,315 import【翻译】异常和异常处理(windows平台) - 进步一点点 - 博客园.htm
***64,191 Linux 下 C++ 异常处理技巧.htm
***Open Discussion _set_se_translator().htm
***445 paip.提升用户体验-----注册全局异常处理器.txt
***310 paip.提升用户体验-----注册全局异常处理器.txt.bak
***28,672 paip.提升用户体验---gcc c++ try catch不能捕获异常的解决--使用 SEH Ca6.wps
***3,440 paip.提升用户体验---gcc c++ 捕获windows SEH异常的实现.txt
***3,420 paip.提升用户体验---gcc c++ 捕获windows SEH异常的实现.txt.bak
***123,057 Problem Fatal error at thread exit if FLS callback not freed.htm
2013-09-29 23:26 223,823 SEH异常,每个程序员都应当引起重视。 - CSDN论坛 - CSDN.NET.htm
***22,516 Structured Exception Handling and MinGW - ProgrammingUnlimited.Net.htm
***77,215 try catch拦截不到异常啊???_百度知道.htm
***112,730 undefined reference to GCC遇到 undefined reference to 错误的解决方法!-C C++-ChinaUnix.net.htm
***44,750 Using a Vectored Exception Handler (Windows).htm
2013-09-29 21:33 44,996 [转载]Qt异常处理_yi_yuan_1988_新浪博客.htm
***kongbu0622) 的专栏 - 博客频道 - CSDN.NET.htm
2013-09-29 23:19 74,921 【翻译】异常和异常处理(windows平台) - 进步一点点 - 博客园.htm
***25,235 关于C++异常捕获的基本问题_百度知道.htm
***66,255 结构化异常SEH转化为C++标准异常的简单实现.htm
***20,145 编译错误:undefine reference to `qMain(int, char )'_Golden Times_百度空间.htm