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

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

内容简介:关于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:在着陆垫里获取正确的捕捉》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

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

Learn Python 3 the Hard Way

Learn Python 3 the Hard Way

Zed A. Shaw / Addison / 2017-7-7 / USD 30.74

You Will Learn Python 3! Zed Shaw has perfected the world’s best system for learning Python 3. Follow it and you will succeed—just like the millions of beginners Zed has taught to date! You bring t......一起来看看 《Learn Python 3 the Hard Way》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具