【问题标题】:Linux Stack SizesLinux 堆栈大小
【发布时间】:2011-06-07 20:02:45
【问题描述】:

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

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

【问题讨论】:

  • 您使用的是哪个内核版本?因此我们对您可用的内核调试配置选项有更好的了解。
  • 我似乎不明白这一点。为什么调试器不足以完成任务?
  • "bottom-halves" 可能共享同一个堆栈。另外,“下半部分”很久以前就消失了,现在还剩下一些软中断。
  • 使用ulimit -s 命令。结果以 KiB 为单位。
  • 这是关于用户态还是kthreads?用户区:unix.stackexchange.com/questions/145557/…

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


【解决方案1】:

文档稀缺的原因是它是一个非常依赖架构的领域。该代码确实是最好的文档 - 例如,THREAD_SIZE 宏定义了(与架构相关的)每个线程的内核堆栈大小。

堆栈分配在alloc_thread_stack_node()。 struct task_struct 中的堆栈指针在 dup_task_struct() 中更新,这被称为克隆线程的一部分。

内核确实通过placing a canary value STACK_END_MAGIC at the end of the stack 检查内核堆栈溢出。在页面错误处理程序中,如果内核空间发生错误,则检查此金丝雀 - 例如,请参阅the x86 fault handler,如果堆栈金丝雀已被破坏,则会在 Oops 消息之后打印消息 Thread overran stack, or stack corrupted。

当然,这不会在所有堆栈溢出时触发,只会在破坏堆栈金丝雀的情况下触发。但是,您应该始终能够从 Oops 输出中判断您是否遇到了堆栈溢出 - 如果堆栈指针低于 task->stack,就会出现这种情况。

【讨论】:

    【解决方案2】:

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

    $ ulimit -s
    8192
    

    【讨论】:

    • 低质量的答案,因为问题是关于内核的。引用“linux内核中的堆栈”。
    • @MilesRout 我的错,我认为它与内核堆栈大小有关。
    • 确实,这似乎不是回答这个问题的正确地方,但真诚地帮助我寻找进程堆栈大小(正如问题所回答的那样)
    • @ManoelVilela 在命令行中输入ulimit -s
    【解决方案3】:

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

    至于使用用户态堆栈的中断,我有点怀疑,因为访问用户态内存是内核的一种麻烦,尤其是中断例程。但我不确定。

    【讨论】:

      猜你喜欢
      • 2023-04-10
      • 2014-09-24
      • 2016-12-20
      • 1970-01-01
      • 2011-10-18
      • 2017-02-28
      • 2010-11-24
      • 2010-12-13
      • 1970-01-01
      相关资源
      最近更新 更多