[译]C++异常的幕后19:在着陆垫里获取正确的捕捉

栏目: C++ · 发布时间: 5年前

内容简介:关于C++异常处理的第19篇文章:我们已经编写了一个personality函数。目前为止,它通过读LSDA,能够在正确的栈帧上选择正确的着陆垫以处理抛出异常,但在一个着陆垫里找出正确的catch有些困难。为了最终得到一个合适的personality合适,我们需要仔细查阅.gcc_except_table里的所有活动表,查看异常可以处理的所有类型。记得活动表吗?让我们再来看它,不过这次对一个带有多个catch块的try。

作者: nicolasbrailo

关于C++异常处理的第19篇文章:我们已经编写了一个personality函数。目前为止,它通过读LSDA,能够在正确的栈帧上选择正确的着陆垫以处理抛出异常,但在一个着陆垫里找出正确的catch有些困难。为了最终得到一个合适的personality合适,我们需要仔细查阅.gcc_except_table里的所有活动表,查看异常可以处理的所有类型。

记得活动表吗?让我们再来看它,不过这次对一个带有多个catch块的try。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

# 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;它匹配要抛出的当前异常,因此我们可以设置着陆垫

这听起来复杂,因为每一步有许多间接成分,但你可以在我的 github repo 里查看这个项目的完整代码。

在上面的链接里你还将看到一个红利:修改personality函数正确地检测及使用catch(…)块。这是一个简单的改变,因为personality函数知道如何读类型表:带有一个空指针的类型(即在这个表里的位置不是保存std::type_info的有效指针,而是空指针)表示一个catch all块。这有一个有趣的副作用:catch(T)将能够仅处理原生(即来自C++)异常,而catch(…)也能捕捉不是从C++里抛出的异常。

最终我们知道异常如何抛出,栈如何回滚,personality函数如何选择正确的栈帧来处理异常,以及如何选择着陆垫里正确的catch,但我们仍然有更多的问题要解决:运行析构函数。下次我们将修改personality函数来支持RAII对象。


以上所述就是小编给大家介绍的《[译]C++异常的幕后19:在着陆垫里获取正确的捕捉》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

高扩展性网站的50条原则

高扩展性网站的50条原则

[美] Martin L. Abbott、[美]Michael T. Fisher / 张欣、杨海玲 / 人民邮电出版社 / 2012-6-3 / 35.00元

《高扩展性网站的50条原则》给出了设计高扩展网站的50条原则,如不要过度设计、设计时就考虑扩展性、把方案简化3倍以上、减少DNS查找、尽可能减少对象等,每个原则都与不同的主题绑定在一起。大部分原则是面向技术的,只有少量原则解决的是与关键习惯和方法有关的问题,当然,每个原则都对构建可扩展的产品至关重要。 主要内容包括: 通过克隆、复制、分离功能和拆分数据集提高网站扩展性; 采用横向......一起来看看 《高扩展性网站的50条原则》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

SHA 加密
SHA 加密

SHA 加密工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具