标签:着陆 19 C++ 垫里 偏移 table 异常 uleb128 personality
关于C++异常处理的第19篇文章:我们已经编写了一个personality函数。目前为止,它通过读LSDA,能够在正确的栈帧上选择正确的着陆垫以处理抛出异常,但在一个着陆垫里找出正确的catch有些困难。为了最终得到一个合适的personality合适,我们需要仔细查阅.gcc_except_table里的所有活动表,查看异常可以处理的所有类型。
记得活动表吗?让我们再来看它,不过这次对一个带有多个catch块的try。
# Call site table
.LLSDACSB2:
# Call site 1
.uleb128 ip_range_start
.uleb128 ip_range_len
.uleb128 landing_pad_ip
.uleb128 (action_offset+1) => 0x3
# Rest of call site table
# Action table start
.LLSDACSE2:
# Action 1
.byte 0x2
.byte 0
# Action 2
.byte 0x1
.byte 0x7d
.align 4
.long _ZTI9Exception
.long _ZTI14Fake_Exception
.LLSDATT2:
# Types table start
如果我们旨在上面的例子里读着陆垫支持的异常(顺便提一下,就是catchit函数的LSDA),我们需要像这样做:
- 从调用表获取活动偏移,2:记住你将实际读偏移加1,因此0意味着没有活动。
- 去往活动偏移2,获取类型索引1。类型表以反序索引(即我们有一个指向它末尾的指针,我们需要使用-1 * index来访问每个元素)。
- 去到types_table[-1];对Fake_Exception你讲得到一个指向type_info的指针。
- Fake_Exception不是要抛出的当前异常;得到我们当前活动(0x7d)下一个活动的偏移
- 以uleb128读0x7d实际产生-3;从我们读这个偏移的位置回退3字节找到下一个活动
- 读类型索引2
- 这次得到Exception的type_infp;它匹配要抛出的当前异常,因此我们可以设置着陆垫
这听起来复杂,因为每一步有许多间接成分
最终我们知道异常如何抛出,栈如何回滚,personality函数如何选择正确的栈帧来处理异常,以及如何选择着陆垫里正确的catch,但我们仍然有更多的问题要解决:运行析构函数。下次我们将修改personality函数来支持RAII对象。
标签:着陆,19,C++,垫里,偏移,table,异常,uleb128,personality 来源: https://blog.csdn.net/Abelia/article/details/94196371
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。