如何在大型项目中使用-fsplit -stack

How to use -fsplit-stack on a large project

本文关键字:-fsplit -stack 大型项目      更新时间:2023-10-16

我最近发布了一个有关堆栈细分和提升coroutines的问题,但似乎-fsplit -stack方法仅适用于与该标志编译的源文件一起使用,当您的运行时会分解。分支到尚未使用-fsplit -stack编译的另一个函数。例如

这意味着运行时使用函数本地技术来检测何时超过当前堆栈。而不是一个"后卫页面信号"的技巧,堆栈的末端总是具有一个护罩页面,该页面将在写或读取上引起信号,并告诉运行时间分配新的堆栈框架并分支到此。

那么该标志的用途是什么?如果我链接到任何尚未与此构建的库,代码将破坏(甚至是libstdc 和libc),那么人们实际上如何在大项目中使用这些东西?


通过阅读有关拆分堆栈的GCC Wiki,似乎从拆分堆栈功能调用非拆分堆栈函数会导致分配64KB堆栈帧。好。

,但似乎尚未实现从功能指针中调用非拆分堆栈函数以遵循上述方案。

那个标志有什么用?如果我继续调用任何虚拟功能,我的程序会违反吗?

从下面的答案中看,Clang似乎没有实施分裂堆栈?

您必须使用segmeented-stacks支持和您的应用程序编译BOOST(至少boost.context和boost.coroutine)。

  • compile boost(boost.context和boost.coroutine)带有b2属性分割stacks = on(启用boost.coroutine and boost.context中的特殊代码)。

  • 您的应用必须使用-dboostrongegented_stacks和-fsplit -actack编译(BOOST.COROUTINES标题)。

请参阅boost.coroutine文档

boost.coroutine包含一个演示分段堆栈的示例(在目录coroutine/xpemend/example/bemmetric/call b2 toolset = gcc分割堆栈= on)。

关于您的最后一个问题GCC Wiki表示:

对于从拆分堆栈代码到非分类堆栈代码的调用,链接器 将更改拆分堆栈(呼叫者)中的初始说明 功能。这意味着链接器将必须特别 了解编译器发出的说明。的效果 更改将是将所需的框架增加一个数字 足够大,可以合理地用于非分类堆栈。这将是一个 目标依赖数;默认值大约是64K。笔记 当拆分堆栈功能时,将发布此大堆栈 返回。请注意,我正在忽略一个拆分堆栈代码的情况 共享库在主要可执行文件中调用非堆栈代码; 这似乎是一个不太可能的问题。

请注意:当LLVM支持分段堆栈时,clang seams不提供__splitstack_<xyz>函数。

首先,我要说的是拆分堆栈支持本质上是有些实验性的。这不是广泛支持的事情,也不是单一的实现被认为是要走的路。因此,编译器中存在IT的一部分是实现实际使用的研究。

也就是说,人们通常希望使用这样的功能来启用许多带有小堆栈的线程,但是如果需要的话,它们可能会变得更大。在某些应用程序中,可以严格控制这些线程中的代码。例如。不称呼通用库(例如Boost)的相当专业的请求处理程序。高性能系统的工作通常涉及根据给定路径中使用的代码的约束,这将是一个例子。它肯定会限制该功能的适用性,但是如果有人在生产中使用它,我不会感到惊讶。

请注意,诸如-fno -exceptions和-fno -rtti之类的标志存在类似的问题。通常,C 需要将所有内容汇编成可执行的所有内容,并具有一组兼容的标志。有时会混合匹配,但通常是脆弱的。这是构建所有内容的动机的一部分,来自源头和诸如Bazel之类的密封构建工具。其他语言对非源组件有不同的方法,尤其是基于虚拟机的语言,例如Java和.NET家族。在这些世界中,诸如拆分堆栈之类的事情是在较低级别的汇编中确定的,但通常在源代码级别上对它们没有任何控制或意识。