Not working python breakpoints in C thread in pych

2019-01-25 21:20发布

问题:

I have a django application using a C++ library (imported via swig). The C++ library launches own thread which calls callbacks in Python code.

I cannot setup a breakpoint in python code, neither in PyDev nor PyCharm. Tried also 'gevent compatibility' option too with no luck.

I verified the callbacks are properly called as logging.info dumps what expected. Breakpoints set in other threads work fine. So it seems that python debuggers cannot manage breakpoints in python code called by threads created in non-python code.

Does anyone know a workaround? Maybe there is some 'magic' thread initialization sequence I could use?

回答1:

You have to setup the debugger machinery for it to work on non-python threads (this is done automatically when a Python thread is created, but when you create a thread for which Python doesn't have any creation hook, you have to do it yourself) -- note that for some frameworks -- such as QThread/Gevent -- things are monkey patched so that we know about the initialization and start the debugger, but for other frameworks you have to do it yourself.

To do that, after starting the thread you have to call:

import pydevd
pydevd.settrace(suspend=False, trace_only_current_thread=True)

Note that if you had put suspend=True, it'd simulate a manual breakpoint and would stop at that point of the code.



回答2:

This is a follow-up to @fabio-zadrozny answer.

Here is a mixin I've created that my class (which gets callbacks from a C-thread) inherits from.

class TracingMixing(object):
    """The callbacks in the FUSE Filesystem are C threads and breakpoints don't work normally.
       This mixin adds callbacks to every function call so that we can breakpoint them."""

    def __call__(self, op, path, *args):
        pydevd.settrace(suspend=False, trace_only_current_thread=True, patch_multiprocessing=True)
        return getattr(self, op)(path, *args)