结构化异常
SEH包括两个部分:终止处理和异常处理
1.异常终止处理程序
语法:__try/__finally
1)从try块到finally的正常代码控制流
2)局部展开:从try块中的提前退出(由goto、longjump、continue、break、return等语句引起)将呈现控制流转入finally块。
3)全局展开:找try块对应except,从最里层找,没有则着上层,找到except进入异常过滤程序得到异常类型,然后返回到最里层finally块执行
补充:不会执行finally的情况有:try块中调用ExitProcess、ExitThread、TerminateProcess、TerminateThread终止进程或线程;Try块中有栈耗尽的异常(finally块没有执行的机会);异常导致SEH链的中断
2.异常过滤程序和异常处理程序
语法:__try/__except
异常过滤器
异常过滤器只有三个可能的值(定义在Windows的Excpt.h中):
EXCEPTION_EXECUTE_HANDLER
EXCEPTION_CONTINUE_SERCH
EXCEPTION_CONTINUE_EXECUTION
下面是两种基本的使用方法:
方式一:直接使用过滤器的三个返回值之一
__try {
……
}
__except ( EXCEPTION_EXECUTE_HANDLER ) {
……
}
方式二:自定义过滤器
__try {
……
}
__except ( MyFilter( GetExceptionCode() ) )
{
……
}
LONG MyFilter ( DWORD dwExceptionCode )
{
if ( dwExceptionCode == EXCEPTION_ACCESS_VIOLATION )
return EXCEPTION_EXECUTE_HANDLER ;
else
return EXCEPTION_CONTINUE_SEARCH ;
}
异常处理过程示意图:
全局展开示意图:
停止全局展开:在finally块中使用return语句
GetExceptionCode()只能在异常过滤程序里(__except后的括号里)或者异常处理程序代码里面;不能被自定义的异常过程程序函数调用。
GetExceptionInfomation()获取异常信息,只在异常过滤程序中调用,因为返回的数据只在异常过滤程序中有效,一旦程序控制流被转移到异常处理程序或其他地方,栈上的数据就被销毁了。