我可以在Python中的后台线程上放置断点吗?

时间:2010-06-24 23:50:55

标签: python eclipse debugging breakpoints pydev

我正在使用PyDev for Eclipse插件,我试图在一些代码中设置一个断点,该代码在后台线程中运行。即使代码正在执行,断点也永远不会被击中。这是一个小例子:

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.')

该示例中的断点在主线程上调用时会被触发,但在从后台线程调用时则不会。有什么我可以做的,或者是PyDev调试器的限制?

更新

感谢您的解决方案。我提交了PyDev feature request,现已完成。它应该与1.6.0版一起发布。谢谢,PyDev团队!

4 个答案:

答案 0 :(得分:6)

问题是线程模块中没有API知道线程何时启动。

你可以在你的例子中做的是自己设置调试器跟踪功能(如Alex指出的那样),如下面的代码所示(如果你不在远程调试器中,则目前需要pydevd.connected = True - 我将改变pydev以便不再需要它。您可能想要为pydevd导入添加try..except ImportError(如果您未在调试器中运行,则会失败)

  

def go(count):

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

现在,第二个想法,我认为pydev可以替换线程模块中的start_new_thread方法,提供自己的函数,它将设置调试器,然后调用原始函数(只是这样做,它似乎工作,所以,如果你使用将在几个小时内可用的夜间,这将成为未来1.6.0,它应该没有做任何特别的工作)。

答案 1 :(得分:4)

底层问题是sys.settrace,用于执行所有跟踪和调试的低级Python函数 - 正如文档所说,

  

该函数是特定于线程的;为一个   调试器支持多个线程,   它必须使用settrace()注册   对于每个正在调试的线程。

我相信当你在PyDev中设置断点时,结果settrace调用总是在主线程上发生(我最近没有看过PyDev所以他们可能已经添加了一些方法来解决这个问题,但是从我看的时候起,我不记得了。

您可能自己实现的解决方法是,在设置断点之后的主线程中,使用sys.gettrace来获取PyDev的跟踪函数,将其保存在全局变量中,并确保在所有感兴趣的线程中使用该全局变量作为参数调用sys.settrace - 有点麻烦(对于断点设置时已存在的线程更是如此!),但我想不出任何更简单的替代方法。

答案 2 :(得分:2)

this question上,我找到了一种启动命令行调试器的方法:

import pdb; pdb.set_trace()

它不像Eclipse调试器那么容易使用,但它总比没有好。

答案 3 :(得分:1)

对我而言,根据Fabio的一篇文章,在使用setTrace设置跟踪(“000.000.000.000”)之后,这是有用的,其中0是运行Eclipse / PyDev的计算机的IP

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