1

我理解它的方式,分段堆栈是在编译器支持下构建的,因此每当在分段堆栈上运行的函数调用另一个函数时,如果首先检查堆栈是否有足够的空间用于该新函数的堆栈帧。如果它没有附加另一个分段堆栈并且代码分支到该函数。

但是,如果说例如我有一个正在运行的光纤并且我从另一个未使用该-fsplit-stack选项编译的共享(或编译为非共享对象文件)库中调用另一个函数,这是否有效?该库中的函数如何知道它们必须检查分段堆栈中是否有足够的空间才能继续?

只对 clang 和 gcc 实现感兴趣(尤其是 boost 上下文),谢谢!

4

1 回答 1

1

我将回顾一下我记得在之前关于这个主题的问题中看到的一段文档:

向后兼容性

我们希望能够在没有拆分堆栈的情况下编译预构建库的系统上使用拆分堆栈程序。这意味着我们需要确保在调用任何此类函数之前有足够的堆栈空间。

在拆分堆栈模式下编译的每个目标文件都将被注释以指示函数使用拆分堆栈。这可能应该用注释进行注释,但在 GNU 中没有对创建任意注释的一般支持as。因此,在拆分堆栈模式下编译的每个目标文件都会有一个具有特殊名称的空部分: . note.GNU-split-stack. 如果在拆分堆栈模式下编译的目标文件包含一些具有该no_split_stack属性的函数,那么该目标文件也将具有.note.GNU-no-split-stack section. 这将告诉链接器某些函数可能没有预期的拆分堆栈序言。

[...]

对于从拆分堆栈代码到非拆分堆栈代码的调用,链接器将更改拆分堆栈(调用者)函数中的初始指令。这意味着链接器必须对编译器发出的指令有特殊的了解。更改的效果是将所需的帧大小增加一个足够大的数字,以合理地为非拆分堆栈工作。这将是一个依赖于目标的数字;默认值为 64K。请注意,当拆分堆栈函数返回时,这个大堆栈将被释放。请注意,我忽略了共享库中的拆分堆栈代码调用主可执行文件中的非拆分堆栈代码的情况;这似乎是一个不太可能的问题。

我特别记得列表(斜体)警告 - 我不记得是我突出显示它还是其他人。该讨论中的关键字是关于“回调”。

于 2017-11-19T16:29:45.210 回答