我怎样才能在程序的垂死挣扎中分配更多的堆栈?

How can I allocate more stack in my program's death throes?

在 Posix 系统上,我正在编写一个信号处理程序,使用 sigaction

我想在调用 exit() 之前记录一些调试信息。这涉及一些过程调用。

如果出现堆栈溢出,有什么方法可以在不进一步搞砸的情况下进行这些函数调用?

我知道在完成调试后,我将调用 exit(),因此我们永远不会展开堆栈。我可以编写一个小的汇编程序插入代码来将堆栈指针设置为堆栈的底部吗?

没关系,我在破坏它;稍后将不需要它,并且通过丢弃堆栈的开头,我不会丢弃堆栈的末尾。

有没有人做过这个或替代方法,并证明它有效?

在 POSIX 上,您可以使用 sigaltstack() 为特定的信号处理程序设置单独的堆栈。 Linux 上有关此功能的联机帮助页非常好:

The most common usage of an alternate signal stack is to handle the SIGSEGV signal that is generated if the space available for the normal process stack is exhausted: in this case, a signal handler for SIGSEGV cannot be invoked on the process stack; if we wish to handle it, we must use an alternate signal stack.

要记住的一件事是您需要使用 sigaction() 而不是 signal() 来建立相关的信号处理程序,但无论如何这是个好主意。此外,sigaction()s struct sigactionsa_flags 需要包含 SA_ONSTACK.

不要求您的程序使用堆栈(对于调用框架,而不是数据结构)。作为图灵完备的编程语言,您可以将任何功能递归循环(例如使用函数调用的循环)重写为过程递归循环(例如过程forwhiledo .. while 等循环,为您提供适当的语言和数据结构。

然后您可能会发现将 stack(数据结构,与调用帧不同)增长到几千兆字节对于大多数使用 realloc 的笔记本电脑来说是微不足道的...作为额外的好处,您将不再需要深入研究不可移植的 hack,例如实现定义的汇编程序符号或信号。