【问题标题】:Can I get the python call stack with the linux perf?我可以使用 linux perf 获得 python 调用堆栈吗?
【发布时间】:2014-11-13 06:53:21
【问题描述】:

例如,

    def test():
        print "test"

我使用了perf record -g -p $pid,但结果只是关于PyEval_EvalFrameEx。如何获取真名“test”或者如果不能使用 perf?

【问题讨论】:

  • 为什么特别要求使用perf
  • 我的python程序会调用一些c++扩展,所以我用perf来检查c++扩展的调用栈,我也想得到python。

标签: python linux perf


【解决方案1】:

截至 2018 年,perf 根本不支持读取 Python 堆栈帧(参见a 2014 Python mailinglist discussion)。

Python 3.6 对Dtrace and Systemtap 有一些支持。

对此的替代方法是Pyflame, a stochastic profiler for Python,它通过ptrace() 对python 调用堆栈进行采样。与 Dtrace/Systemtap 相比,您不需要额外的权限,而且它也适用于在没有工具化支持的情况下编译的 Python 版本。

当您在 Pyflame 中使用 --threads 选项时,您会看到调用 C/C++ 扩展的 Python 行,尽管堆栈跟踪在最后一个 Python 帧处停止。但也许这对您的用例来说已经足够了。

编辑: Pyflame 在 2019 年底左右为 abandonedhacker news thread 提到了以下替代方案:

【讨论】:

    【解决方案2】:

    您将无法使用 perf 来执行此操作,它是专门为连接 Linux 进程模型、解码这些堆栈帧等而构建的。它通过告诉您它正在执行函数 PyEval_EvalFrameEx 来完成它应该做的事情。它必须使用特定于 python 的信息进行扩展,才能真正解码 Python 的帧信息,这不会发生。不幸的是,我还没有找到一种非常好的方法来轻松调试 Python 和 C/C++ 模块。通常一个是 pdb,另一个是 gdb。

    【讨论】:

      【解决方案3】:
      【解决方案4】:

      Austin 3.3 有一个 where 选项,可让您发出正在运行的 Python 进程的当前堆栈跟踪

      https://github.com/P403n1x87/austin#where

      在 Linux 上,austinp 变体允许发出本机堆栈跟踪,使用 -k 开关可以深入到 Linux 内核:

      两者都可以使用-C 开关,该开关也允许从子进程发出堆栈跟踪。

      【讨论】:

        猜你喜欢
        • 2014-03-30
        • 1970-01-01
        • 2015-04-26
        • 1970-01-01
        • 2020-09-02
        • 2012-06-27
        • 2015-08-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多