_try_except原理探究
调用_except_handle3
这个异常处理函数,这里并不是每个编译器的异常处理函数都是相同的,然后存入结构体,将esp的值赋给fs:[0]
,再就是提升堆栈的操作
每个使用?_try _except
的函数,不管其内部嵌套或反复使用多少_try _except
,都只注册一遍,即只将一个?_EXCEPTION_REGISTRATION_RECORD?
挂入当前线程的异常链表中(对于递归函数,每一次调用都会创建一个?_EXCEPTION_REGISTRATION_RECORD
,并挂入线程的异常链表中)。
可以看到只有一个异常处理函数
那么这里编译器是如何做到只用一个异常处理函数的呢?编译器把原来_EXCEPTION_REGISTRATION_RECORD
结构进行了拓展,添加了三个成员
新堆栈结构如下:
scopetable
查看地址可以发现有三个结构体
存储着的正式异常函数的开始地址和结束地址
第一个值previousTryLevel
是上一个try
结构的编号,这里如果在最外层就是-1,如果在第二层就是0,如果在第三层就是1,以此类推
trylevel
该成员表示代码运行到了哪个try
结构里面,进入一个try
则加1,try
结构执行完成之后则减1
_except_handler3
1.CPU检测到异常 -> 查中断表执行处理函数 ->?CommonDispatchException?
->?KiDispatchException?
->?KiUserExceptionDispatcher?
? ? ? ? ? ? ? ? ->?RtlDispatchException?
->VEH
?->?SEH
2.执行_except_handler3
函数
<1> 根据trylevel?
选择scopetable
数组
<2> 调用scopetable
数组中对应的lpfnFilter
函数
<3> 如果lpfnFilter
函数返回0 向上遍历 直到previousTryLevel=-1
假设有两个异常点
首先找到trylevel
为0
然后找到异常过滤表达式为1
.
然后遍历数组的lpfnFilter
如果返回值为1则调用异常处理函数,如果为0则该异常函数不处理,如果为-1则继续从原异常点向下执行
假设在B这个地方出异常,得到trylevel
为2
那么这里就回去遍历lpfnFilter
为2的地方
假设这里返回值为0,则继续查找,注意这个地方是向上查找,首先判断当前previousTryLevel
的值是否为-1,如果为-1就停止查找(-1代表已经是最外层)try
结构,然后再向上找,假设这里返回值仍然为0,判断previousTryLevel
的值为-1,就停止查找,没有找到响应的异常处理函数
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!