Vectored Exception Handling was introduced in Windows XP.[7] Vectored Exception Handling is made available to Windows programmers using languages such as C++ and Visual Basic. VEH does not replace Structured Exception Handling (SEH), rather VEH and SEH coexist, with VEH handlers having priority over SEH handlers.[1][7] Compared with SEH, VEH works more like kernel-delivered Unix signals.[8](wikipedia)
主要大体内容就是说VEH与SEH共存,且VEH优先级比SEH高。
我们可以注册多个VEH,VEH之间通过双向链表链接,所以相对于SEH,VEH可以指定位置。同时VEH保存在堆中。
当异常发生的时候,系统将遍历VEH链表,尝试处理异常。 SEH工作原理讲了那么多别的,最终我们还是要回到最主要的问题上,SEH是个啥,他怎么工作的呢?
在线程初始化的时候,会自动在栈中安装一个SEH结构体,作为默认异常处理,他的next就是0xFFFFFFFFF,而这个异常程序大家应该都很熟悉,就是windows程序崩溃时那个弹窗,打印出来出错函数地址。
如果程序中使用了try、excpt、assert来处理异常信息,那么编译器就会在栈中压入一个SEH结构体,同时插入链表中。
当出现异常的时候,操作系统会先中断程序,然后从TIB中取出第一个SEH结构体(也就是最近的SEH结构),使用其中的handler处理这个异常。
如果这个异常处理函数处理不了这个异常,那么就顺着next往上找别的异常处理函数,直到找到一个可以处理这个异常的函数或者到底部,也就是弹出错误窗口然后杀死线程。
通常处理完异常后,需要执行展开(Unwind)操作,该操作先通知目标结点前的各异常处理函数释放资源,然后将之前的SEH链全部删除。该操作通常由各高级语言Rtl模块来完成,Win32汇编操作时既可以不展开,也可以手工展开,还可以使用RtlUnwind函数展开。 unwind当一个函数注册一个SEH的时候,通常都会干这些事: