C++异常的幕后16:在着陆垫里找到正确的捕捉

原文地址:https://monoinfinito.wordpress.com/2013/05/07/c-exceptions-under-the-hood-16-finding-the-right-catch-in-a-landing-pad/

作者:nicolasbrailo

应我们要求第16章要实现能够处理异常的小ABI;上次我们实现了personality函数,使它能够处理有多个着陆垫的函数。现在我们尝试使它识别某个着陆垫是否能处理指定的异常,因此我们可以在catch语句上使用异常说明。

当然,要知道一个着陆垫是否能处理一个异常是困难的任务。你还想要什么吗?目前要克服的最大问题是:

  • 首先:我们如何找出一个catch块接受的类型?
  • 假设我们可以找出一个catch的类型,我们怎样处理一个catch(…)?
  • 对带有多条catch语句的着陆垫,我们怎样知道所有可能的catch类型?
  • 考虑下面的例子:

1

2

3

4

5

6

7

8

9

struct Base {};

struct Child : public Base {};

void foo() { throw Child; }

 

void bar()

{

    try { foo(); }

    catch(const Base&){ ... }

}

  • 我们不仅要检查着陆垫是否接受当前异常,还要检查它是否接受当前异常的任意父类!

要使我们的工作更轻松,假设我们现在只使用有一个catch的着陆垫,且在我们程序里没有继承。同样,我们怎样找出着陆垫接受的类型?

在.gcc_except_table里有一个地方我们还没分析:活动表。让我们反汇编我们的throw.cpp对象,看那里有什么,就在调用表之后,对我们的“try but don’t catch“函数:

备注:你可以从我的github repo下载完整的源代码。

1

2

3

4

5

6

.LLSDACSE1:

    .byte   0x1

    .byte   0

    .align 4

    .long   _ZTI14Fake_Exception

.LLSDATT1:

看起来不太像,但一定有一个指针(一个众所周知的真实指针)指向具有我们异常名字的某个东西。让我们去到_ZTI14Fake_Exception的定义:

1

2

3

4

5

6

7

_ZTI14Fake_Exception:

    .long   _ZTVN10__cxxabiv117__class_type_infoE+8

    .long   _ZTS14Fake_Exception

    .weak   _ZTS9Exception

    .section    .rodata._ZTS9Exception,"aG",@progbits,_ZTS9Exception,comdat

    .type   _ZTS9Exception, @object

    .size   _ZTS9Exception, 11

我们得到了一些非常有趣的结果。你能识别出它吗?这是用于结构体Fake_Exception的std:: type_info!

现在我们知道确实有一种方法可以让指针指向我们异常的某种反射信息。我们能通过编程找到它吗?下次见。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值