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

发布于 2024-09-06 15:08:52 字数 620 浏览 8 评论 0原文

我正在使用 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 功能请求,并且它已经完成了。它应该以 1.6.0 版本发布。谢谢 PyDev 团队!

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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

无力看清 2024-09-13 15:08:52

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

您在示例中可以做的就是自己设置调试器跟踪函数(正如 Alex 指出的),如下面的代码所示(如果您不在远程调试器中,则当前需要 pydevd.connected = True - 我将更改pydev,这样就不再需要了)。您可能需要为 pydevd 导入添加 try.. except ImportError (如果您没有在调试器中运行,则会失败)

def go(计数):

<前><代码>导入 pydevd
pydevd.connected = True
pydevd.settrace(挂起=假)
打印“计数为 %d”。 % count # 在这里设置断点

现在,再想一想,我认为 pydev 可以替换 thread 模块中的 start_new_thread 方法,提供自己的函数,该函数将设置调试器并稍后调用原始函数(只是这样做了,似乎是工作,所以,如果您使用将在几个小时内可用的每晚(这将成为未来的 1.6.0),它应该可以工作,而不需要做任何特殊的事情)。

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

铁憨憨 2024-09-13 15:08:52

根本问题在于 sys.settrace,用于执行所有跟踪和调试的低级 Python 函数——正如文档所说,

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

我相信,当您在 PyDev 中设置断点时,生成的 settrace 调用始终发生在主线程上(我最近没有查看 PyDev,因此他们可能添加了一些方法来解决该问题,但是我不记得我看过的时候有任何东西)。

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

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.

坠似风落 2024-09-13 15:08:52

这个问题上,我发现启动命令行调试器的一种方法:

import pdb; pdb.set_trace()

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

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.

好多鱼好多余 2024-09-13 15:08:52

对我来说,根据 Fabio 的一篇文章,在使用 setTrace("000.000.000.000") # 设置跟踪后,这有效,其中 0 是运行 Eclipse/PyDev 的计算机的 IP

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

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)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文