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

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

内容简介:作者:如果我们准备尝试理解为什么异常是复杂的,以及它们如何工作,我们可以读大量的手册,也可以尝试自己编写异常的处理。实际上,我惊讶于这个议题好资料的缺乏:我找到的几乎所有东西要么非常详细,要么非常基础,只有一两个例外。当然,有一些要实现的规范(最值得注意的是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》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

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

图灵的秘密

图灵的秘密

Charles Petzold / 杨卫东 / 人民邮电出版社 / 2012-11 / 69.00元

图灵机是英国数学家阿兰•图灵提出的一种抽象计算模型,本书深入剖析了图灵这篇描述图灵机和可计算性的原始论文《论可计算数及其在判定性问题上的应用》。书中在详解论文的同时,也附带了大量的历史背景资料、图灵的个人经历,以及图灵机对于人们理解计算机、人类意识和宇宙所产生的影响。 本书适合所有计算机科学专业的学生、程序员或其他技术人员,同时也适合欲了解图灵生平及其构建图灵机的思维的读者阅读。一起来看看 《图灵的秘密》 这本书的介绍吧!

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

在线图片转Base64编码工具

html转js在线工具
html转js在线工具

html转js在线工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具