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

有帮助吗?

解决方案

参见第 6.2 节 x86_64 ABI. 。这详细介绍了接口,但没有介绍很多底层数据。这也独立于 C++,并且也可以用于其他目的。

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

.eh_frame 遵循 DWARF 格式(主要在使用 gdb 时发挥作用的调试格式)。它的格式与 .debug_frame 编译时发出的部分 -g. 。本质上,它包含在调用堆栈上方任何位置弹出回机器寄存器和堆栈状态所需的信息。有关详细信息,请参阅 dwarfstd.org 上的矮人标准。

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

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

其他提示

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

不幸的是,我不熟悉这些函数,无法告诉您该看什么(除了 libgcc 的源代码——其中包括异常处理运行时)。

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

虽然这看起来是针对 Itanium 的,但 x86 的实现大概是类似的: 异常处理ABI

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top