Linux堆栈大小

时间:2011-06-07 20:02:46

标签: linux linux-kernel linux-device-driver

我正在寻找linux内核中堆栈的良好描述,但我发现找到任何有用的东西都非常困难。

我知道大多数系统的堆栈限制为4k,其他系统的堆栈限制为8k。我假设每个内核线程/下半部分都有自己的堆栈。我也听说如果一个中断发生,它会使用当前线程的堆栈,但是我找不到任何关于这个的文档。我正在寻找的是如何分配堆栈,如果有任何好的调试例程(我怀疑特定问题的堆栈溢出,我想知道是否有可能将内核编译为警察堆栈大小等。)

3 个答案:

答案 0 :(得分:34)

文档缺乏的原因是它是一个非常依赖于架构的区域。代码实际上是最好的文档 - 例如,THREAD_SIZE宏定义了(依赖于体系结构的)每线程内核堆栈大小。

堆栈在alloc_thread_info_node()中分配,或者该功能的架构特定覆盖(struct thread_info始终位于堆栈的底部)。 struct task_struct中的堆栈指针在dup_task_struct()中更新,这是作为克隆线程的一部分调用的。

内核通过在堆栈末尾放置一个canary值STACK_END_MAGIC(紧跟在内存中struct thread_info之后)来检查内核堆栈溢出。在页面错误处理程序中,如果发生内核空间中的错误,则检查此canary - 请参阅例如the x86 fault handler,如果堆栈canary已被破坏,则在Oops消息之后打印消息Thread overran stack, or stack corrupted

当然,这不会触发所有堆栈溢出,只会破坏堆栈金丝雀。但是,如果您遇到堆栈溢出,您应该始终能够从Oops输出中判断 - 如果堆栈指针低于&threadinfo,则会出现这种情况。

答案 1 :(得分:3)

您可以使用ulimit命令确定进程堆栈大小。我的系统上有8192 KiB:

$ ulimit -s
8192

答案 2 :(得分:0)

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

至于使用userland堆栈的中断,我有点怀疑,因为访问用户区内存是内核的一种麻烦,特别是来自中断例程。但我不确定。