gcc 使用-funwind-tables进行编译时,究竟会发生什么?

tjjdgumg  于 2022-11-13  发布在  其他
关注(0)|答案(1)|浏览(1073)

发件人:https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html

-fexceptions:启用异常处理生成传播异常所需额外代码对于某些目标,这意味着GCC为所有函数生成框架展开信息,
**-funwind-tables**类似于-fexceptions,只是它只生成任何需要的静态数据,而不以任何其他方式影响生成的代码。通常不需要启用此选项;而是由需要此处理的语言处理器代表您启用它。

有人能解释一下,从-funwind-tables,“任何需要的静态数据”是什么意思吗?他们指的是什么数据?为什么需要生成数据?如果没有生成数据会发生什么?这些数据用于哪里?
而且它还写着“类似于-fexception“。所以我认为它也会生成框架展开信息。什么是框架展开信息?谁使用框架信息,如何使用?
在一些SO文章中,我读到程序必须用这个标志编译,_Unwind_Backtrace才能正常工作。请解释_Unwind_Backtrace如何使用-funwind-tables生成的信息。

stszievb

stszievb1#

-funwind-tables选项中提到的静态数据是帧展开信息,即允许正在运行的程序从给定的执行点返回函数调用堆栈的数据。返回函数调用堆栈意味着从被调用函数的执行上下文移动到调用方的上下文,即从函数 return 时通常会发生的情况。除了框架展开信息允许您从函数体内部任意点执行此操作;你也不会被迫退出被调用的函数,你可以简单地“窥视”调用者的上下文(例如,检索被调用函数被调用的位置),也是递归的,但是然后在被调用函数中继续正常的执行流程。
为了能够做到以上所述,你需要访问更多关于编译代码的信息,而不是程序遵循“正常”执行流所严格需要的信息。(即框架展开信息)由链接器放在特殊的链接器节中(例如,用于x86平台的.eh_frame部分,或者用于ARM平台的.ARM.exidx.ARM.extab部分);这些链接器部分与C等语言中实现异常处理所需的链接器部分相同,在C中,执行流可能会因抛出异常而从被调用函数跳转到其调用方。如果使用-fno-unwind-tables选项禁用此数据的生成,则无法返回函数调用堆栈或使用C++异常。
值得注意的是,libunwind使用了帧展开信息,libunwind是一个跨平台的库,它支持生成回溯跟踪、跳转到调用堆栈中的任意点等。
_Unwind_Backtrace()是在GCC核心库中实现的函数(更具体地说,在libgcc_s中),它允许执行回调函数(作为参数提供),即从调用方函数的上下文开始,移动到其调用方,等等。请参见https://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/baselib--unwind-backtrace.html。同样,该函数需要从适当的链接器部分访问帧展开信息才能完成其工作。

相关问题