在C90中实现无溢出系统堆栈

问题描述 投票:7回答:2

我只是在阅读有关Google Go默认情况下如何使每个线程的堆栈大小减小的信息,如果发生溢出,则链接到新堆栈(请参阅here第16页)。我想知道在C中做到这一点的最佳方法。

我不得不说我不是C专家,所以也许有更好的方法来检测C上的堆栈溢出,但是由于我的无知,这就是我认为我将实现它的方式:

我想到的第一件事是,每当我们有一个新的新堆栈时,我们都会得到一个堆栈变量的地址,并由此获得一个大致的起始堆栈地址。然后,我们将需要能够检索线程有多少堆栈空间。如果线程不是主线程,这将是可能的,但是我不知道我们如何获得有关C的信息。

然后,我们需要通过检索当前的堆栈变量地址来检查(可能是每个函数调用)已经使用了多少堆栈。如果我们检测到可能的堆栈溢出,则需要某种方式来创建新堆栈并链接到最后一个堆栈。我认为可以用C语言完成的唯一方法是创建一个新线程来执行所需的函数,并锁定当前线程,直到函数返回结果为止。

所以,有没有一种更清洁/更好的方法来实现这一目标?

c go stack-overflow c89
2个回答
9
投票

请参见GCC的split-stack capability。我相信这最初是为了支持Go而实现的。正如您所建议的,它几乎可以工作。

编辑:下面的评论讨论了另一个对激活记录进行堆分配的系统。


2
投票

您可以执行此操作-我相信现代gcc甚至可以选择它-但是它大大增加了函数调用的成本,并且几乎没有实际收益。尤其是在具有64位寻址的现代系统上,每个线程都有足够的地址空间来拥有自己的堆栈,而与其他所有线程的堆栈相距甚远。如果您发现自己使用的不只是对数级调用递归,那么您的算法仍然存在问题...

© www.soinside.com 2019 - 2024. All rights reserved.