最近在将
pdb
调试器添加到我的 Python 2.7.10 代码中时,我收到以下消息:
Traceback (most recent call last):
File "/Users/isaachess/Programming/vivint/Platform/MessageProcessing/vivint_cloud/queues/connectors/amqplib_connector.py", line 191, in acking_callback
callback(message.body)
File "/Users/isaachess/Programming/vivint/Platform/MessageProcessing/vivint_cloud/queues/consumable_message_queue.py", line 32, in deserialized_callback
self._callback_method(msg)
File "/Users/isaachess/Programming/vivint/Platform/BusinessLogic/businesslogic/util/statsd_util.py", line 95, in _time_func
retVal = f(*args, **kwargs)
File "/Users/isaachess/Programming/vivint/Platform/MessageProcessing/vivint_cloud/net/router.py", line 226, in handle
try:
File "/Users/isaachess/Programming/vivint/Platform/MessageProcessing/vivint_cloud/net/router.py", line 226, in handle
try:
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/bdb.py", line 49, in trace_dispatch
return self.dispatch_line(frame)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/bdb.py", line 68, in dispatch_line
if self.quitting: raise BdbQuit
BdbQuit
这是插入行后:
import pdb; pdb.set_trace()
在代码中。
我不明白为什么会发生这种情况。我已经阅读了 Bdb 和 Bdbquit,但无法弄清楚为什么我的代码中会发生这种情况。谁能给我提供一些关于为什么会发生这种情况的提示?我真的想让调试器再次工作。
当我在生产代码中留下
import pdb
和 pdb.set_trace()
时,我遇到了这个问题。当 pdb.set_trace()
行被执行时,python 正在等待我的输入来告诉它 c
继续或进入等...因为 python 代码正在由 Web 服务器调用,所以我不在那里按 c
继续。经过这么长时间(不确定多久)它终于引发了 BdbQuit
异常。
我没有进行任何设置来捕获该异常,因此它在我的网络服务器中引发了 500。
我花了一段时间才明白是我在守护进程/后台运行的调试代码导致了这个问题。我觉得很傻。
如果您从
(pdb)
提示继续并允许代码正常完成,我不会期望像您指示的回溯那样的输出,但如果您退出 pdb
,使用 quit
命令或 ^D (EOF) ,会发生类似的回溯,因为没有任何东西可以捕获调试器退出时引发的 BdbQuit
异常。在 bdb.py
中,self.quitting
通过 True
方法(以及各种 run 方法中的 set_quit
子句)设置为 finally
。当 trace_dispatch
为 raise BdbQuit
时,由 self.quitting
True
调用的调度方法,并且 except:
的典型 BdbQuit
子句是一个简单的 pass
语句; pdb
继承了 gdb
的所有内容。
简而言之,当调试器交互提前完成时,异常处理用于禁用调试器使用的系统跟踪功能。
完全避免回溯的一种方法是以不同方式使用
pdb
。您可以在 pdb.set_trace()
中调用代码(而不是相反),而不是从代码中调用 BdbQuit
(并且根本不处理 pdb
),此时 BdbQuit
异常将按预期处理数据库。这还允许您在不修改代码的情况下选择断点位置(使用 pdb
的 break
命令)。或者您可以混合使用这两种方法;在 pdb
、pdb.set_trace()
调用等下运行您的代码,这些调用将成为断点,您只能通过修改代码来删除它们。
您可以使用
pdb
命令并将脚本调用作为其命令行参数,或使用 pdb
来调用 python -m pdb
中的代码。
一个可能的原因是您正在后台运行 Python 脚本。当进程在后台运行时,您无法通过终端向进程发送输入,因此 pdb 控制台无法工作。最终,它提高了
BdbQuit
。
除了 Eirik Fuller 的回答之外,我想补充一点,你不能在不同进程中运行的东西中使用
pdb
。为了调试,你可以检查这个答案:https://stackoverflow.com/a/23654936/7806805,但它看起来很黑客,或者你可以让你的程序在单线程中运行。请参阅文档:https://docs.python.org/3/library/concurrent.futures.html。对于多处理问题,您甚至可能需要浏览https://www.reddit.com/r/learnpython/comments/46x9sm/why_is_pdbset_trace_crashing_whenever_it_is_in_an/
无论如何,你的问题缺乏必要的背景。请补充您的问题。
对于那些在 Django 测试中遇到此问题的人,这可能是由于将
--parallel
标志传递给测试命令造成的。正如之前的答复中指出的,这是由于多重处理造成的。尝试删除该标志,看看是否可以解决问题,它对我来说是这样。
我在将数据传输到脚本中时遇到了这个问题。看起来
pdb
不想让管道保持打开状态,所以它会抛出 BdbQuit
。我通过将 stdin
数据保存到临时文件中,然后从 python 读取临时文件来解决了这个问题。
之前
$ pbpaste | script.py
Traceback (most recent call last):
File "/Users/admin/Code/script.py", line 78, in <module>
process(args)
... blah blah ...
File "/usr/local/Cellar/[email protected]/3.9.13_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/bdb.py", line 88, in trace_dispatch
return self.dispatch_line(frame)
File "/usr/local/Cellar/[email protected]/3.9.13_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/bdb.py", line 113, in dispatch_line
if self.quitting: raise BdbQuit
bdb.BdbQuit
之后
$ pbpaste > temp.txt
$ python3 script.py test.txt
> /Users/admin/Code/script.py(49)f()
-> hello = "world"
(Pdb)
我们需要为运行 Django 的 docker 服务启用 shell 输入。如果您使用 docker compose,请在 docker-compose 文件中添加:
stdin_open: true
:
version: '3'
services:
...
django_app:
build: .
ports:
- '8000:8000'
stdin_open: true
我使用
pdbpp
更幸运,它是 pdb
的替代品,即除了本身之外不需要任何其他东西(没有插件,没有额外的配置/选项)。它支持自动完成,这就是我所追求的ipdb
。
您可以使用
pip install pdbpp
安装它。
当我的代码中存在
breakpoint()
调用时,我遇到了此错误。它与这里提出的其他原因非常相似(pdb
的各种用途)。只要知道这也是一种可能性即可。