[pypy-dev] Making Pyrasite work with PyPy

Tin Tvrtković tinchester at gmail.com
Sat Mar 5 17:20:49 EST 2016


Hello,

in case you haven't heard of it, Pyrasite
(https://github.com/lmacken/pyrasite) is a tool for injecting code into
running Python processes. Personally I have found it invaluable for
forensics on services running in production and have successfully solved
memory leaks, connection leaks and deadlocks with it. One of the
payloads provided will open a remote REPL right in a running process,
without the process having *any* preparation logic in it. I think this
is extremely powerful and makes Python catch and up even surpass Java
(which has automatic stack trace dumping on SIGQUIT and useful tools
like JConsole and VisualVM that can connect to running processes, again
by default with no setup in the process) for these kinds of things.

Anyway, Pyrasite uses gdb under the hood; gdb will attach to a running
process and inject the following:

    gdb_cmds = [
        'PyGILState_Ensure()',
        'PyRun_SimpleString("'
            'import sys; sys.path.insert(0, \\"%s\\"); '
            'sys.path.insert(0, \\"%s\\"); '
            'exec(open(\\"%s\\").read())")' %
                (os.path.dirname(filename),
                os.path.abspath(os.path.join(os.path.dirname(__file__),
'..')),
                filename),
        'PyGILState_Release($1)',
        ]
       
If I change the Py* functions to PyPy* (PyRun_SimpleString to
PyPyRun_SimpleString), this seems to work just fine on PyPy too.

This is great, and now I'd like to contribute back to Pyrasite and get
PyPy support in there. It'd be great if Pyrasite could automatically
detect if the underlying process is CPython or PyPy, so since my
experience working on the C level is very basic, I'm asking you, the
PyPy devs, if there's a good way of detecting a process is PyPy given
its PID and gdb's ability of attaching to a process and doing gdb
things. Worst case scenario, gdb supports "info functions", which is how
I found the PyPy functions in the first place, but is there a better way?

I apologize if this is off-topic for PyPy-dev.



More information about the pypy-dev mailing list