pdb — Python 调试器 — Python 文档

来自菜鸟教程
Python/docs/3.9/library/pdb
跳转至:导航、​搜索

pdb — Python 调试器

源代码: :source:`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 文件中给出的一样,请参阅 调试器命令[ X151X]。


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


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

import pdb; pdb.set_trace()

在您想要进入调试器的位置。 然后,您可以单步执行此语句后的代码,并使用 :pdbcmd:`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)
在调试器控制下执行 语句 (作为字符串或代码对象给出)。 在执行任何代码之前会出现调试器提示; 您可以设置断点并键入 :pdbcmd:`continue`,或者您可以使用 :pdbcmd:`step` 或 :pdbcmd:`next`[ X208X](所有这些命令都在下面解释)。 可选的 globalslocals 参数指定执行代码的环境; 默认情况下使用模块 __main__ 的字典。 (请参阅内置 exec()eval() 函数的说明。)
pdb.runeval(expression, globals=None, locals=None)
在调试器控制下评估 表达式 (作为字符串或代码对象给出)。 当 runeval() 返回时,它返回表达式的值。 否则这个函数类似于 run()
pdb.runcall(function, *args, **kwds)
使用给定的参数调用 函数 (函数或方法对象,而不是字符串)。 当 runcall() 返回时,它返回函数调用返回的任何内容。 一旦输入函数,调试器提示就会出现。
pdb.set_trace(*, header=None)

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

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

pdb.post_mortem(traceback=None)
进入给定的 traceback 对象的事后调试。 如果没有给出 traceback,它使用当前正在处理的异常之一(如果要使用默认值,则必须处理异常)。
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 是调试器类。

completekeystdinstdout 参数被传递给底层的 cmd.Cmd 类; 请参阅那里的说明。

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

默认情况下,当您发出 continue 命令时,Pdb 会为 SIGINT 信号(当用户在控制台上按下 Ctrl-C 时发送)设置处理程序。 这允许您通过按 Ctrl-C 再次闯入调试器。 如果您希望 Pdb 不接触 SIGINT 处理程序,请将 nosigint 设置为 true。

readrc 参数默认为 true 并控制 Pdb 是否从文件系统加载 .pdbrc 文件。

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

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

3.1 版新功能: skip 参数。

3.2 版新功能: nosigint 参数。 以前,Pdb 从未设置 SIGINT 处理程序。

3.6 版更改: readrc 参数。

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

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

调试器命令

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

输入一个空行会重复输入的最后一个命令。 例外:如果最后一个命令是 :pdbcmd:`list` 命令,则列出接下来的 11 行。

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

调试器支持 别名 。 别名可以具有允许对所检查的上下文具有一定程度的适应性的参数。

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

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

3.2 版更改:.pdbrc 现在可以包含继续调试的命令,例如 :pdbcmd:`continue` 或 :pdbcmd:`next`[ X150X]。 以前,这些命令无效。


脚注

1
帧是否被认为源自某个模块由帧全局变量中的 __name__ 决定。