[译]C++异常的幕后2:一个小ABI

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

内容简介:作者:如果我们准备尝试理解为什么异常是复杂的,以及它们如何工作,我们可以读大量的手册,也可以尝试自己编写异常的处理。实际上,我惊讶于这个议题好资料的缺乏:我找到的几乎所有东西要么非常详细,要么非常基础,只有一两个例外。当然,有一些要实现的规范(最值得注意的是C++的ABI,但我们还有CFI、DWARF与libstdc),但只阅读规范不足以真正理解底层。让我们从最明显的开始:重新发明轮子!我们知道一个事实,C不能处理异常,因此让我们尝试使用一个C链接器链接一个抛出的C++程序,看会发生什么。我想出了这样一个简

作者: nicolasbrailo

如果我们准备尝试理解为什么异常是复杂的,以及它们如何工作,我们可以读大量的手册,也可以尝试自己编写异常的处理。实际上,我惊讶于这个议题好资料的缺乏:我找到的几乎所有东西要么非常详细,要么非常基础,只有一两个例外。当然,有一些要实现的规范(最值得注意的是C++的ABI,但我们还有CFI、DWARF与libstdc),但只阅读规范不足以真正理解底层。

让我们从最明显的开始:重新发明轮子!我们知道一个事实,C不能处理异常,因此让我们尝试使用一个C链接器链接一个抛出的C++程序,看会发生什么。我想出了这样一个简单的东西:

1

2

3

4

5

6

#include "throw.h"

extern "C" {

    void seppuku() {

        throw Exception();

    }

}

不要忘了extern,否则g++将重整我们小函数的名字,我们将不能将它与我们的C程序链接。当然,我们需要一个头文件来将C++世界与C世界“链接”(没有双关语)起来:

1

2

3

4

5

6

7

8

9

10

11

struct Exception {};

 

#ifdef __cplusplus

extern "C" {

#endif

 

    void seppuku();

 

#ifdef __cplusplus

}

#endif

以及一个非常简单的main:

1

2

3

4

5

6

7

#include "throw.h"

 

int main()

{

    seppuku();

    return 0;

}

如果现在我们尝试编译并链接这个代码会发生什么?

1

2

> g++ -c -o throw.o -O0 -ggdb throw.cpp

> gcc -c -o main.o -O0 -ggdb main.c

注意:你可以从我的 github库 里下载这个项目的完整源代码。

目前还好。G++与gcc都陶醉在它们的小世界里。然而一旦我们尝试链接它们,混乱接踵而至:

> gcc main.o throw.o -o app
throw.o: In function `foo()':
Throw.cpp:4: undefined reference to `__cxa_allocate_exception'
throw.cpp:4: undefined reference to `__cxa_throw'
throw.o:(.rodata._ZTI9Exception[typeinfo for Exception]+0x0): undefined reference to `vtable for __cxxabiv1::__class_type_info'
collect2: ld returned 1 exit status

确实,gcc抱怨缺少C++符号。虽然这些是非常特殊的C++符号。检查最后一行错误:缺少用于cxxabiv1的vtable。定义在libstdc++中,cxxabi援引用于C++的应用程序二进制接口。因此现在我们了解到异常处理是在带有C++ABI定义接口的标准C++库的辅助下完成。

C++ ABI定义了一个标准二进制格式,因此我们可以在一个程序里将对象链接起来;如果我们使用两个编译器编译一个.o文件,这些编译器使用不同的ABI,我们将不能把.o文件链接进应用程序。ABI也将定义其他一些格式,例如执行栈回滚或异常抛出的接口。在这个情形里,ABI在C++与我们程序里其他某些处理栈回滚的库之间定义了一个接口(不一定二进制格式,只是一个接口),即ABI定义了C++特定的内容,因此它可与非C++库交谈:这使得在C++里能捕捉从其他语言抛出的异常,除了别的之外。

无论如何,链接器将我们指向幕后异常处理的第一层:一个我们必须自己实现的接口,cxxabi。在下一篇我们将开始我们自己的小ABI,就像定义在C++ ABI里那样。


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

查看所有标签

猜你喜欢:

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

计算理论导论

计算理论导论

塞普斯 / 机械工业出版社 / 2002-8 / 39.0

This book——by a noted authority and educator in the field——presents computer science theory from a uniquely intuitive,“big picture”perspective.The author grounds his clear and interesting study on ......一起来看看 《计算理论导论》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码