Linux堆栈大小

42

我正在寻找一个关于Linux内核中堆栈的良好描述,但我发现很难找到任何有用的信息。

我知道对于大多数系统,堆栈被限制为4k,而对于其他一些系统则为8k。 我假设每个内核线程/底半部分都有自己的堆栈。 我还听说如果发生中断,它会使用当前线程的堆栈,但我找不到任何相关的文档资料。我想了解的是如何分配堆栈,是否存在任何好的调试例程(我怀疑特定问题的堆栈溢出,并且我想知道是否可以编译内核以监管堆栈大小等)。


你正在使用哪个内核版本?这样我们就能更好地了解可用的内核调试配置选项。 - Will Tate
我似乎不理解这个。为什么调试器不能完成这个任务? - cnicutar
“bottom-halves” 可能共享同一个堆栈。此外,“bottom-halves” 已经消失很久了,现在只剩下 softirqs。 - ninjalj
2
使用 ulimit -s 命令,结果以 KiB 为单位。 - Miles Rout
这是关于用户空间还是内核线程的问题? 用户空间:https://unix.stackexchange.com/questions/145557/how-does-stack-allocation-work-in-linux/239323#239323 - Ciro Santilli OurBigBook.com
3个回答

40
文档很少的原因是它是一个相当依赖架构的领域。代码确实是最好的文档——例如,THREAD_SIZE 宏定义了(依赖于架构的)每个线程内核堆栈大小。
堆栈是在 alloc_thread_stack_node() 中分配的。 struct task_struct 中的堆栈指针在 dup_task_struct() 中更新,该函数在克隆线程时被调用。
内核确实会检查内核堆栈溢出,方法是 在堆栈末尾放置一个金丝雀值 STACK_END_MAGIC。在页面错误处理程序中,如果发生内核空间故障,则会检查此金丝雀 - 例如,请参见 x86 错误处理程序,如果堆栈金丝雀已被破坏,则 Oops 消息后将打印消息 Thread overran stack, or stack corrupted
当然,这并不会在所有堆栈溢出情况下触发,只有破坏堆栈金丝雀的情况才会触发。但是,您应该始终能够从“Oops”输出中判断是否遭受了堆栈溢出-如果堆栈指针低于 task-> stack ,那就是这种情况。

5
您可以使用ulimit命令确定进程堆栈的大小。在我的系统上,我得到了8192 KiB:
$ ulimit -s
8192

9
答案质量低,因为问题涉及内核。引用:“Linux内核中的堆栈”。 - catpnosis
2
@MilesRout 不好意思,我认为这与内核栈大小有关。 - Geoffrey R.
1
看起来这好像不是回答那个问题的正确场所,但是请帮我查找进程堆栈大小(因为这个问题有答案)。 - Manoel Vilela
@ManoelVilela 在命令行中输入 ulimit -s - Miles Rout

1

对于进程,您可以通过ulimit命令(-s选项)控制进程的堆栈大小。对于线程,默认的堆栈大小变化很大,但是您可以通过调用pthread_attr_setstacksize()来控制它(假设您正在使用pthreads)。

至于使用用户空间堆栈进行中断,我有点怀疑,因为从内核访问用户空间存储器尤其是从中断例程中访问存储器是有些麻烦的。但我不确定。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接