Can I put break points on background threads in Python?

陌路散爱 提交于 2019-12-01 01:53:07

问题


I'm using the PyDev for Eclipse plugin, and I'm trying to set a break point in some code that gets run in a background thread. The break point never gets hit even though the code is executing. Here's a small example:

import thread

def go(count):
    print 'count is %d.' % count # set break point here

print 'calling from main thread:'
go(13)
print 'calling from bg thread:'
thread.start_new_thread(go, (23,))

raw_input('press enter to quit.')

The break point in that example gets hit when it's called on the main thread, but not when it's called from a background thread. Is there anything I can do, or is that a limitation of the PyDev debugger?

Update

Thanks for the work arounds. I submitted a PyDev feature request, and it has been completed. It should be released with version 1.6.0. Thanks, PyDev team!


回答1:


The problem is that there's no API in the thread module to know when a thread starts.

What you can do in your example is set the debugger trace function yourself (as Alex pointed) as in the code below (if you're not in the remote debugger, the pydevd.connected = True is currently required -- I'll change pydev so that this is not needed anymore). You may want to add a try..except ImportError for the pydevd import (which will fail if you're not running in the debugger)

def go(count):

   import pydevd
   pydevd.connected = True
   pydevd.settrace(suspend=False)
   print 'count is %d.' % count # set break point here

Now, on a second thought, I think that pydev can replace the start_new_thread method in the thread module providing its own function which will setup the debugger and later call the original function (just did that and it seems to be working, so, if you use the nightly that will be available in some hours, which will become the future 1.6.0, it should be working without doing anything special).




回答2:


The underlying issue is with sys.settrace, the low-level Python function used to perform all tracing and debugging -- as the docs say,

The function is thread-specific; for a debugger to support multiple threads, it must be registered using settrace() for each thread being debugged.

I believe that when you set a breakpoint in PyDev, the resulting settrace call is always happening on the main thread (I have not looked at PyDev recently so they may have added some way to work around that, but I don't recall any from the time when I did look).

A workaround you might implement yourself is, in your main thread after the breakpoint has been set, to use sys.gettrace to get PyDev's trace function, save it in a global variable, and make sure in all threads of interest to call sys.settrace with that global variable as the argument -- a tad cumbersome (more so for threads that already exist at the time the breakpoint is set!), but I can't think of any simpler alternative.




回答3:


On this question, I found a way to start the command-line debugger:

import pdb; pdb.set_trace()

It's not as easy to use as the Eclipse debugger, but it's better than nothing.




回答4:


For me this worked according to one of Fabio's posts, after setting the trace with setTrace("000.000.000.000") # where 0's are the IP of your computer running Eclipse/PyDev

threading.settrace(pydevd.GetGlobalDebugger().trace_dispatch)


来源:https://stackoverflow.com/questions/3114719/can-i-put-break-points-on-background-threads-in-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!