我能用linux perf得到python调用栈吗?

omvjsjqw  于 2023-03-17  发布在  Linux
关注(0)|答案(5)|浏览(135)

例如,

def test():
        print "test"

我用的是perf record -g -p $pid,但是结果都是PyEval_EvalFrameEx。我怎么才能得到真实的的“test”,或者如果不能用perf呢?

anauzrmj

anauzrmj1#

截至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选项时,你会看到Python代码行调用了C/C++扩展,尽管堆栈跟踪会在最后一个Python帧停止,但这对你的用例来说已经足够了。

**编辑:**Pyflame在2019年底左右是abandoned,一个hacker news thread提到了以下替代品:

dwbf0jvd

dwbf0jvd2#

你不能用perf来做这些,perf是专门为连接Linux进程模型,解码那些堆栈帧等而构建的,它做了它应该做的事情,告诉你它正在执行函数PyEval_EvalFrameEx,它必须用Python特定的信息来扩展,才能真正解码Python的帧信息,这是不可能的。不幸的是,我还没有找到一个真正好的方法来轻松地调试Python和C/C++模块。通常一个是pdb,另一个是gdb。

wsxa1bj1

wsxa1bj14#

从Python 3.12开始,解释器可以在一种特殊的模式下运行,这种模式允许Python函数出现在perf分析器的输出中,当这种模式被启用时,解释器会在每个Python函数执行之前插入一小段即时编译的代码,并且它会使用perfMap文件来教perf这段代码和相关的Python函数之间的关系。
https://docs.python.org/3.12/howto/perf_profiling.html

643ylb08

643ylb085#

Austin 3.3有一个where选项,允许您发出正在运行的Python进程的当前堆栈跟踪
https://github.com/P403n1x87/austin#where

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

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

相关问题