【问题标题】:Kernel visibility into the call stack in PythonPython中调用堆栈的内核可见性
【发布时间】:2020-06-06 21:02:13
【问题描述】:

操作系统是否可以查看 CPython 中的调用堆栈(例如函数之间的调用)?例如。操作系统以何种方式参与 Python 堆栈的创建、检索和/或管理及其stack frames 的操作?

上下文:

  • 我的理解是 Python 解释器确实支持尾调用递归,所以这似乎是留给 Python 处理的事情。
  • 大多数操作系统对堆栈大小施加了最大限制(例如,我相信在 Linux 操作系统中,最大堆栈大小默认为 8192 KB,但可以通过例如 ulimit 进行更改),这意味着内核显然可以参与其中至少限制了调用堆栈的大小。

【问题讨论】:

    标签: python recursion memory-management linux-kernel cpython


    【解决方案1】:

    操作系统以何种方式参与 Python 堆栈的创建、检索和/或管理及其堆栈帧的操作?

    不是。堆栈帧是由进程处理的,内核不干预。

    我的理解是Python解释器不支持尾调用递归,所以这似乎是留给Python处理的事情。

    嗯,是的,处理自己的堆栈是 Python 的工作,不管尾递归如何。 Python 不支持尾递归这一事实可能对深度递归调用有一些缺点,但代码总是可以被重写为迭代。

    另请参阅:What is the maximum recursion depth in Python, and how to increase it?

    内核显然可以参与至少限制调用堆栈的大小

    是的,内核确实限制了堆栈大小。它的完成方式是在栈顶之后分配一个不可见的保护页:当栈满时,进行另一个调用(从而添加另一个栈帧)将触发对保护页的读取和/或写入,并且内核将检测到它并增加堆栈大小。但是,这只发生达到某个预定义的数量,之后进程会因为超出允许的最大堆栈大小而被终止。

    另见:Stack memory management in Linux

    【讨论】:

    • 谢谢,所以内核参与其中,它将其呈现为指定为stack(与heap 分开)的虚拟内存空间,以简单地限制其大小并解决任何页面错误?即内核不关心它的用途?即进程是否使用它来存储堆栈帧或任何其他类型的数据与内核无关?
    • @Josh 基本上是的。它仍然是一个特殊领域,在许多情况下会受到不同的对待,但流程本身负责对其进行管理。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-05
    • 2015-02-13
    • 2017-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-10
    相关资源
    最近更新 更多