36

For example,

    def test():
        print "test"

I used perf record -g -p $pid, but the result was just all about PyEval_EvalFrameEx. How can I get the real name "test" or if can not by using perf?

wuwl
  • 581
  • 1
  • 5
  • 11
  • Why are you specifically requiring the use of `perf`? – NPE Nov 13 '14 at 07:30
  • 5
    My python program will call some c++ extensions, so I use perf to check the call stack for c++ extensions, also I want to get the python. – wuwl Nov 13 '14 at 07:49

5 Answers5

8

As of 2018, perf simply doesn't have support for reading the Python stack frames (cf. a 2014 Python mailinglist discussion).

Python 3.6 has some support for Dtrace and Systemtap.

An alternative to this is Pyflame, a stochastic profiler for Python that samples python call stacks via ptrace(). In contrast to Dtrace/Systemtap you don't need extra permissions and it also works with Python versions that are compiled without instrumentalization support.

When you use the --threads option with Pyflame you see Python lines that call into C/C++ extensions, although the stack-trace stops at the last Python frame. But perhaps this is sufficient for your use case.

Edit: Pyflame was abandoned in the end of 2019 or so. A hacker news thread mentions the following alternatives:

maxschlepzig
  • 35,645
  • 14
  • 145
  • 182
4

You won't be able to do this with perf, that's specifically built to interface the Linux process model, decode those stack frames, etc. It's doing what it's supposed to by telling you that it was executing the function PyEval_EvalFrameEx. It would have to be extended with python-specific information to be able to actually decode Python's frame information, which isn't going to happen. Unfortunately I haven't found a really good way to debug both Python and C/C++ modules easily. It's generally pdb for one and gdb for the other.

gct
  • 14,100
  • 15
  • 68
  • 107
2

Since Python 3.12, the interpreter can run in a special mode that allows Python functions to appear in the output of the perf profiler. When this mode is enabled, the interpreter will interpose a small piece of code compiled on the fly before the execution of every Python function and it will teach perf the relationship between this piece of code and the associated Python function using perf map files.

https://docs.python.org/3.12/howto/perf_profiling.html

Steven Sun
  • 141
  • 6
1

Maybe the traceback module will do the trick for you:

https://docs.python.org/2/library/traceback.html https://docs.python.org/3/library/traceback.html

rotten
  • 1,580
  • 19
  • 25
0

Austin 3.3 has a where option which allows you to emit the current stack trace of a running Python process

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

enter image description here

On Linux, the austinp variant allows emitting native stack traces, that can go as deep as the Linux kernel with the -k switch:

enter image description here

Both work with the -C switch which allows emitting stack traces from child processes too.

Phoenix87
  • 1,003
  • 11
  • 15