Linux 堆栈大小
我正在寻找 Linux 内核中堆栈的良好描述,但我发现找到任何有用的东西出奇地困难。
我知道大多数系统的堆栈限制为 4k,而其他系统则限制为 8k。我假设每个内核线程/下半部分都有自己的堆栈。我还听说,如果中断发生,它会使用当前线程的堆栈,但我找不到任何有关这方面的文档。我正在寻找的是堆栈是如何分配的,是否有任何好的调试例程(我怀疑特定问题的堆栈溢出,并且我想知道是否可以编译内核以进行警察检查)堆栈大小等)。
I'm looking for a good description of stacks within the linux kernel, but I'm finding it surprisingly difficult to find anything useful.
I know that stacks are limited to 4k for most systems, and 8k for others. I'm assuming that each kernel thread / bottom half has its own stack. I've also heard that if an interrupt goes off, it uses the current thread's stack, but I can't find any documentation on any of this. What I'm looking for is how the stacks are allocated, if there's any good debugging routines for them (I'm suspecting a stack overflow for a particular problem, and I'd like to know if its possible to compile the kernel to police stack sizes, etc).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
文档稀缺的原因是它是一个非常依赖于体系结构的领域。代码确实是最好的文档 - 例如,THREAD_SIZE 宏定义(依赖于架构)每线程内核堆栈大小。
堆栈在
alloc_thread_stack_node()
。
struct task_struct
中的堆栈指针在dup_task_struct()
,它作为克隆线程的一部分被调用。内核确实通过 放置金丝雀来检查内核堆栈溢出堆栈末尾的值
STACK_END_MAGIC
。在页面错误处理程序中,如果内核空间中发生错误,则会检查此金丝雀 - 请参阅例如 x86 故障处理程序,如果堆栈金丝雀已被清除,它会在 Oops 消息之后打印消息Thread overran stack, or stack baded
被重创了。当然,这不会在所有堆栈溢出时触发,只会在破坏堆栈金丝雀的堆栈溢出时触发。但是,您应该始终能够从 Oops 输出中判断您是否遇到了堆栈溢出 - 如果堆栈指针低于
task->stack
就会出现这种情况。The reason that documentation is scarce is that it's an area that's quite architecture-dependent. The code is really the best documentation - for example, the
THREAD_SIZE
macro defines the (architecture-dependent) per-thread kernel stack size.The stacks are allocated in
alloc_thread_stack_node()
. The stack pointer in thestruct task_struct
is updated indup_task_struct()
, which is called as part of cloning a thread.The kernel does check for kernel stack overflows, by placing a canary value
STACK_END_MAGIC
at the end of the stack. In the page fault handler, if a fault in kernel space occurs this canary is checked - see for example the x86 fault handler which prints the messageThread overran stack, or stack corrupted
after the Oops message if the stack canary has been clobbered.Of course this won't trigger on all stack overruns, only the ones that clobber the stack canary. However, you should always be able to tell from the Oops output if you've suffered a stack overrun - that's the case if the stack pointer is below
task->stack
.您可以使用
ulimit
命令确定进程堆栈大小。我的系统上有 8192 KiB:You can determine the process stack size with the
ulimit
command. I get 8192 KiB on my system:对于进程,您可以通过
ulimit
命令(-s
选项)控制进程的堆栈大小。对于线程,默认堆栈大小变化很大,但您可以通过调用 pthread_attr_setstacksize() 来控制它(假设您使用的是 pthread)。至于使用用户态堆栈的中断,我有些怀疑,因为访问用户态内存是内核的一种麻烦,尤其是中断例程。但我不确定。
For processes, you can control the stack size of processes via
ulimit
command (-s
option). For threads, the default stack size varies a lot, but you can control it via a call topthread_attr_setstacksize()
(assuming you are using pthreads).As for the interrupt using the userland stack, I somewhat doubt it, as accessing userland memory is a kind of a hassle from the kernel, especially from an interrupt routine. But I don't know for sure.