我正在寻找linux内核中堆栈的良好描述,但我发现找到任何有用的东西都非常困难。
我知道大多数系统的堆栈限制为4k,其他系统的堆栈限制为8k。我假设每个内核线程/下半部分都有自己的堆栈。我也听说如果一个中断发生,它会使用当前线程的堆栈,但是我找不到任何关于这个的文档。我正在寻找的是如何分配堆栈,如果有任何好的调试例程(我怀疑特定问题的堆栈溢出,我想知道是否有可能将内核编译为警察堆栈大小等。)
答案 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堆栈的中断,我有点怀疑,因为访问用户区内存是内核的一种麻烦,特别是来自中断例程。但我不确定。