19

gcc 如何在 linux 上实现 C++ 异常的堆栈展开?特别是,它如何知道展开框架时调用哪些析构函数(即,存储了什么样的信息以及存储在哪里)?

4

3 回答 3

13

请参阅x86_64 ABI的第 6.2 节。这详细说明了界面,但没有详细说明基础数据。这也独立于 C++,也可以用于其他目的。

gcc 发出的 ELF 二进制文件主要有两个部分用于异常处理。它们是.eh_frame.gcc_except_table

.eh_frame遵循 DWARF 格式(使用 gdb 时主要使用的调试格式)。.debug_frame它与编译时发出的部分具有完全相同的格式-g。本质上,它包含在调用堆栈更高的任何位置弹出回机器寄存器和堆栈状态所需的信息。有关这方面的更多信息,请参阅 dwarfstd.org 上的 Dwarf 标准。

.gcc_except_table包含有关异常处理“着陆区”处理程序位置的信息。这是必要的,以便知道何时停止展开。不幸的是,这部分没有很好的记录。我能够收集到的唯一信息片段来自 gcc 邮件列表。尤其看这个帖子

剩下的信息就是实际代码解释在这些数据部分中找到的信息的内容。相关代码位于 libstdc++ 和 libgcc 中。我现在不记得哪些片段生活在哪个片段中。DWARF 调用帧信息的解释器可以在文件 gcc/unwind-dw.c 中的 gcc 源代码中找到

于 2010-12-22T03:59:47.773 回答
3

虽然这看起来适用于 Itanium,但大概 x86 的实现类似:异常处理 ABI

于 2008-09-17T21:10:14.467 回答
3

目前可用的文档不多,但是基本系统是 GCC 将 try/catch 块转换为函数调用,然后链接到具有所需运行时支持的库中有关树构建代码的文档包括语句“抛出异常是不直接在 GIMPLE 中表示,因为它是通过调用函数来实现的”)。

不幸的是,我不熟悉这些函数,也不能告诉你要看什么(除了 libgcc 的源代码——它包括异常处理运行时)。

有一个“新手的异常处理”文档可用。

于 2008-09-17T22:24:56.130 回答