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

时间:2020-03-05 18:59:55  来源:igfitidea点击:

gcc如何在Linux上实现C ++异常的堆栈展开?特别是,在展开帧时,它如何知道要调用哪些析构函数(即,存储了哪些信息以及将其存储在什么位置)?

解决方案

回答

尽管这似乎是针对Itanium,但是大概与x86的实现类似:异常处理ABI

回答

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

不幸的是,我对这些功能并不熟悉,无法告诉我们要看的内容(除了libgcc的源代码(包括异常处理运行时)。

有一个"新手异常处理"文档。

回答

请参阅x86_64 ABI的6.2节。这将详细说明界面,但不会包含很多基础数据。这也独立于C ++,并且可以想象也可以用于其他目的。

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

.eh_frame遵循DWARF格式(使用gdb时主要发挥作用的调试格式)。它的格式与使用-g编译时发出的.debug_frame`节的格式完全相同。本质上,它包含必要的信息,以便在调用堆栈上方的任何位置弹出机器寄存器和堆栈的状态。有关更多信息,请参阅dwarfstd.org上的Dwarf Standard。

.gcc_except_table包含有关异常处理信息的信息,这些异常处理是处理程序的位置。这是必要的,以便知道何时停止放卷。不幸的是,本节没有很好的记录。我能够收集的唯一信息片段来自gcc邮件列表。特别看到这个帖子

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