pdb ---Python调试器

源代码: Lib/pdb.py


模块 pdb 为Python程序定义交互式源代码调试器。它支持在源代码行级别设置(条件)断点和单步执行,检查堆栈帧,源代码列表,以及在任何堆栈帧的上下文中评估任意Python代码。它还支持事后调试,可以在程序控制下调用。

调试器是可扩展的——它实际上定义为类 Pdb . 这是目前没有文件,但很容易理解阅读来源。扩展接口使用模块 bdbcmd .

调试器的提示是 (Pdb) . 在调试器控制下运行程序的典型用法是:

>>> import pdb
>>> import mymodule
>>> pdb.run('mymodule.test()')
> <string>(0)?()
(Pdb) continue
> <string>(1)?()
(Pdb) continue
NameError: 'spam'
> <string>(1)?()
(Pdb)

在 3.3 版更改: 标签完成通过 readline 模块可用于命令和命令参数,例如,当前全局和本地名称作为 p 命令。

pdb.py 也可以作为脚本调用以调试其他脚本。例如::

python3 -m pdb myscript.py

当作为脚本调用时,如果正在调试的程序异常退出,PDB将自动进入事后调试。事后调试后(或程序正常退出后),PDB将重新启动程序。自动重新启动会保留PDB的状态(如断点),在大多数情况下,它比在程序退出时退出调试器更有用。

3.2 新版功能: pdb.py 现在接受 -c 执行命令的选项,如同在 .pdbrc 文件,见 调试器命令 .

3.7 新版功能: pdb.py 现在接受 -m 执行与此类似的模块的选项 python3 -m 做。与脚本一样,调试器将在模块的第一行之前暂停执行。

从正在运行的程序中断到调试器的典型用法是插入:

import pdb; pdb.set_trace()

在您想要进入调试器的位置。然后,您可以单步执行此语句后面的代码,并继续运行,而不必使用 continue 命令。

3.7 新版功能: 内置的 breakpoint() 当使用默认值调用时,可以使用而不是 import pdb; pdb.set_trace() .

检查崩溃程序的典型用法是:

>>> import pdb
>>> import mymodule
>>> mymodule.test()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "./mymodule.py", line 4, in test
    test2()
  File "./mymodule.py", line 3, in test2
    print(spam)
NameError: spam
>>> pdb.pm()
> ./mymodule.py(3)test2()
-> print(spam)
(Pdb)

模块定义了以下函数;每个函数以稍微不同的方式进入调试器:

pdb.run(statement, globals=None, locals=None)

执行 陈述 (作为字符串或代码对象提供)在调试器控制下。调试器提示出现在执行任何代码之前;您可以设置断点和类型 continue 或者您可以使用 stepnext (所有这些命令解释如下)。可选的 globalslocals 参数指定执行代码的环境;默认情况下,模块的字典 __main__ 使用。(参见内置的说明 exec()eval() 函数。

pdb.runeval(expression, globals=None, locals=None)

评价 表达 (作为字符串或代码对象提供)在调试器控制下。什么时候? runeval() 返回,它返回表达式的值。否则,此函数与 run() .

pdb.runcall(function, *args, **kwds)

调用给 function (函数或方法对象,不是字符串)具有给定参数。什么时候? runcall() 返回,它返回函数调用返回的任何内容。只要输入函数,就会出现调试器提示。

pdb.set_trace(*, header=None)

在调用堆栈帧处输入调试器。这对于在程序的给定点硬编码断点很有用,即使代码没有被调试(例如,断言失败)。如果给予, *header*在调试开始前打印到控制台。

在 3.7 版更改: 仅关键字参数 header.

pdb.post_mortem(traceback=None)

输入给定的 追溯 对象。如果没有 追溯 如果给定,则使用当前正在处理的异常之一(如果要使用默认值,则必须处理异常)。

pdb.pm()

输入在中找到的回溯的事后调试 sys.last_traceback .

这个 run* 功能和 set_trace() 是用于实例化 Pdb 类并调用同名的方法。如果要访问其他功能,您必须自己执行此操作:

class pdb.Pdb(completekey='tab', stdin=None, stdout=None, skip=None, nosigint=False, readrc=True)

Pdb 是调试器类。

这个 completekeystdin*和 *stdout 参数传递给基础 cmd.Cmd 类;参见那里的描述。

这个 skip 参数(如果给定)必须是全局样式模块名称模式的iterable。调试器不会单步进入源自与这些模式之一匹配的模块的帧中。 1

默认情况下,pdb为sigint信号设置一个处理程序(当用户按 Ctrl-C 在控制台上)当您 continue 命令。这允许您通过按 Ctrl-C . 如果希望pdb不接触sigint处理程序,请设置 小号 成真。

这个 读写器 参数默认为true,并控制pdb是否从文件系统加载.pdbrc文件。

启用跟踪的示例调用 skip ::

import pdb; pdb.Pdb(skip=['django.*']).set_trace()

提出一个 auditing event pdb.Pdb 没有参数。

3.1 新版功能: 这个 skip 参数。

3.2 新版功能: 这个 小号 参数。以前,pdb从未设置sigint处理程序。

在 3.6 版更改: 这个 读写器 参数。

run(statement, globals=None, locals=None)
runeval(expression, globals=None, locals=None)
runcall(function, *args, **kwds)
set_trace()

有关上述功能,请参阅文档。

调试器命令

下面列出了调试器识别的命令。如图所示,大多数命令可以缩写为一个或两个字母;例如 h(elp) 也就是说 hhelp 可用于输入帮助命令(但不能 hehel 也不 HHelpHELP )命令的参数必须用空格(空格或制表符)分隔。可选参数括在方括号中 ([] )在命令语法中,不能键入方括号。命令语法中的选项由竖线分隔 (|

输入空行将重复输入的最后一个命令。异常:如果最后一个命令是 list 命令,下面列出11行。

调试器无法识别的命令被假定为python语句,并在被调试程序的上下文中执行。python语句也可以以感叹号作为前缀 (! )这是检查正在调试的程序的强大方法;甚至可以更改变量或调用函数。当这种语句中发生异常时,将打印异常名称,但不会更改调试器的状态。

调试器支持 aliases . 别名可以有一些参数,这些参数允许人们对所检查的上下文有一定程度的适应性。

可以在一行中输入多个命令,用分隔符分隔 ;; . (单个) ; 不使用,因为它是传递给python解析器的一行中多个命令的分隔符。)不应用智能来分隔命令;输入在第一行被拆分 ;; 对,即使它在引用字符串的中间。

如果一个文件 .pdbrc 存在于用户的主目录或当前目录中,它被读入并执行,就好像它是在调试器提示下键入的一样。这对于别名特别有用。如果两个文件都存在,则首先读取主目录中的文件,并且在主目录中定义的别名可以被本地文件覆盖。

在 3.2 版更改: .pdbrc 现在可以包含继续调试的命令,例如 continuenext . 以前,这些命令没有效果。

h(elp) [command]

不带参数,打印可用命令列表。用一个 命令 作为参数,打印关于该命令的帮助。 help pdb 显示完整的文档(文档字符串 pdb 模块)。自从 命令 参数必须是标识符, help exec 必须输入才能获得有关 ! 命令。

w(here)

打印堆栈跟踪,最新帧位于底部。箭头表示当前帧,该帧决定大多数命令的上下文。

d(own) [count]

移动当前帧 计数 (默认值为1)在堆栈跟踪中降低级别(到较新的帧)。

u(p) [count]

移动当前帧 计数 (默认值为1)在堆栈跟踪中向上升级(到较旧的帧)。

b(reak) [([filename:]lineno | function) [, condition]]

用一个 林诺 参数,在当前文件中设置一个中断。用一个 function 参数,设置该函数中第一个可执行语句的中断。行号前面可以加上文件名和冒号,以指定另一个文件中的断点(可能是尚未加载的断点)。在上搜索文件 sys.path .注意,每个断点都被分配了一个数字,其他所有断点命令都指向这个数字。

如果存在第二个参数,则它是一个表达式,必须在遵守断点之前计算为true。

不带参数,列出所有中断,包括每个断点的中断次数、中断点被命中的次数、当前忽略计数以及关联的条件(如果有)。

tbreak [([filename:]lineno | function) [, condition]]

临时断点,在第一次命中时自动删除。参数与for相同 break .

cl(ear) [filename:lineno | bpnumber ...]

用一个 文件名:林诺 参数,清除此行的所有断点。使用以空格分隔的断点编号列表,清除这些断点。无需参数,清除所有中断(但首先要求确认)。

disable [bpnumber ...]

禁用以空格分隔的断点编号列表形式给出的断点。禁用断点意味着它不能导致程序停止执行,但与清除断点不同,它仍保留在断点列表中,并且可以(重新)启用。

enable [bpnumber ...]

启用指定的断点。

ignore bpnumber [count]

设置给定断点编号的忽略计数。如果忽略计数,则忽略计数设置为0。当忽略计数为零时,断点变为活动状态。当非零时,每次到达断点时,计数都会递减,并且不会禁用断点,并且任何关联条件的计算结果都为true。

condition bpnumber [condition]

设置一个新的 条件 对于断点,表达式的值必须为true,然后才能使用断点。如果 条件 如果不存在,则删除任何现有条件;即,断点是无条件的。

commands [bpnumber]

指定断点编号的命令列表 BP-数 . 命令本身出现在下面的行中。键入仅包含 end 终止命令。示例:

(Pdb) commands 1
(com) p some_variable
(com) end
(Pdb)

要从断点中删除所有命令,请键入 commands 然后立即跟随它 end 也就是说,不要发出命令。

没有 BP-数 论证, commands 引用最后一个断点集。

可以使用断点命令重新启动程序。简单地使用 continue 命令,或 step 或任何其他恢复执行的命令。

指定恢复执行的任何命令(当前 continuestepnextreturnjumpquit 以及它们的缩写)终止命令列表(就像该命令后面紧跟着end一样)。这是因为无论何时恢复执行(即使是简单的下一步或步骤),都可能遇到另一个断点,该断点可能有自己的命令列表,从而导致要执行的列表模糊不清。

如果在命令列表中使用“silent”命令,则不会打印有关在断点处停止的常规消息。对于要打印特定消息然后继续的断点,这可能是可取的。如果没有其他命令打印任何内容,则不会看到到达断点的迹象。

s(tep)

执行当前行,在第一个可能的情况下停止(在调用的函数中或在当前函数的下一行中)。

n(ext)

继续执行,直到到达当前函数的下一行或返回。(两者之间的区别 nextstep 那是 step 在被调用函数内停止,而 next 以(接近)全速执行被调用函数,仅在当前函数的下一行停止。)

unt(il) [lineno]

不带参数,继续执行,直到到达大于当前行的行。

对于行号,继续执行,直到达到大于或等于该行号的行。在这两种情况下,当当前帧返回时也停止。

在 3.2 版更改: 允许给出明确的行号。

r(eturn)

继续执行,直到当前函数返回。

c(ont(inue))

继续执行,仅在遇到断点时停止。

j(ump) lineno

设置将执行的下一行。仅在最下面的框架中可用。这允许您向后跳并再次执行代码,或者向前跳以跳过不想运行的代码。

应该注意的是,并非所有的跳跃都是允许的——例如,不可能跳到 for 循环或退出 finally 条款。

l(ist) [first[, last]]

列出当前文件的源代码。如果没有参数,请在当前行周围列出11行,或者继续上一个列表。用 . 作为参数,列出当前行周围的11行。用一个参数,列出该行的11行。使用两个参数,列出给定的范围;如果第二个参数小于第一个参数,则将其解释为计数。

当前帧中的当前行由 -> . 如果正在调试异常,则异常最初引发或传播的行由 >> ,如果它与当前行不同。

3.2 新版功能: 这个 >> 标记。

ll | longlist

列出当前函数或框架的所有源代码。有趣的行标记为 list .

3.2 新版功能.

a(rgs)

打印当前函数的参数列表。

p expression

评价 表达 在当前上下文中并打印其值。

注解

print() 也可以使用,但不是调试器命令---这将执行python print() 功能。

pp expression

p 命令,但表达式的值使用 pprint 模块。

whatis expression

打印的类型 表达 .

source expression

尝试获取给定对象的源代码并显示它。

3.2 新版功能.

display [expression]

每次在当前帧中停止执行时,显示表达式的值(如果更改)。

如果没有表达式,请列出当前帧的所有显示表达式。

3.2 新版功能.

undisplay [expression]

在当前框架中不再显示表达式。如果没有表达式,则清除当前帧的所有显示表达式。

3.2 新版功能.

interact

启动交互式解释程序(使用 code 模块),其全局命名空间包含当前作用域中找到的所有(全局和本地)名称。

3.2 新版功能.

alias [name [command]]

创建一个名为 name 执行 命令 . 命令必须 not 用引号括起来。可替换参数可通过以下方式表示: %1%2 等等,而 %* 替换为所有参数。如果未给出任何命令,则为 name 如图所示。如果没有给出参数,则列出所有别名。

别名可以嵌套,并且可以包含在pdb提示下合法键入的任何内容。注意内部PDB命令 can 被别名覆盖。这样的命令将被隐藏,直到别名被删除。别名递归地应用于命令行的第一个字;行中的所有其他字都是单独存在的。

例如,这里有两个有用的别名(尤其是在 .pdbrc 文件):

# Print instance variables (usage "pi classInst")
alias pi for k in %1.__dict__.keys(): print("%1.",k,"=",%1.__dict__[k])
# Print instance variables in self
alias ps pi self
unalias name

删除指定的别名。

! statement

执行(一行) 陈述 在当前堆栈帧的上下文中。除非语句的第一个字类似于调试器命令,否则感叹号可以省略。要设置全局变量,可以在赋值命令前面加上 global 语句位于同一行,例如:

(Pdb) global list_options; list_options = ['-l']
(Pdb)
run [args ...]
restart [args ...]

重新启动调试后的python程序。如果提供了一个参数,它将被拆分为 shlex 结果被用作新的 sys.argv . 保留历史记录、断点、操作和调试器选项。 restart 是一个别名 run .

q(uit)

从调试器中退出。正在执行的程序被中止。

debug code

输入一个递归调试器,该调试器逐步遍历代码参数(这是要在当前环境中执行的任意表达式或语句)。

retval

打印函数最后一次返回的返回值。

脚注

1

帧是否被视为源自某个模块,由 __name__ 在帧全局中。