gcc 如何在 linux 上实现 C++ 异常的堆栈展开?

Posted

技术标签:

【中文标题】gcc 如何在 linux 上实现 C++ 异常的堆栈展开?【英文标题】:How does gcc implement stack unrolling for C++ exceptions on linux? 【发布时间】:2008-09-17 20:23:42 【问题描述】:

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

【问题讨论】:

【参考方案1】:

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

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

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

.gcc_except_table 包含有关异常处理“着陆点”处理程序位置的信息。这是必要的,以便知道何时停止展开。不幸的是,这部分没有很好的记录。我能够收集到的唯一 sn-ps 信息来自 gcc 邮件列表。具体见this post

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

【讨论】:

【参考方案2】:

目前可用的文档不多,但是基本系统是 GCC 将 try/catch 块转换为 function calls 然后 links in a library with the needed runtime support (documentation about the tree building code 包括语句“抛出异常在 GIMPLE 中不直接表示, 因为它是通过调用函数来实现的”)。

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

有一个“Exception Handling for Newbies”文档可用。

【讨论】:

【参考方案3】:

虽然这看起来适用于 Itanium,但大概 x86 的实现类似:exception handling ABI

【讨论】:

GCC 在没有适用于该平台的现有 ABI 时尽可能遵循安腾 ABI。这包括 x86 和 x86-64。

以上是关于gcc 如何在 linux 上实现 C++ 异常的堆栈展开?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C++ 程序中通过拓扑考虑在多核 HT 上实现亲和性?

如何在F#任务计算表达式的每一步上实现非嵌套异常处理?

如何使用 bluez 在 linux 上实现 HFP?

在磁盘上实现的 FIFO 队列(或堆栈),而不是 ram(最好在 C++ 中)[关闭]

如何在Linux上实现:Eureka服务的开机自启动?

如何在 Java 上实现 CORBA AMI