首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

pdb

源代码: Lib / pdb.py

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

调试器是可扩展的 - 它实际上被定义为类Pdb。这是目前没有记录,但通过阅读来源容易理解。扩展接口使用模块bdbcmd

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

代码语言:javascript
复制
>>> import pdb
>>> import mymodule
>>> pdb.run('mymodule.test()')
> <string>(0)?()
(Pdb) continue
> <string>(1)?()
(Pdb) continue
NameError: 'spam'
> <string>(1)?()
(Pdb)

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

代码语言:javascript
复制
python -m pdb myscript.py

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

2.4版新增:重新启动验尸行为。

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

代码语言:javascript
复制
import pdb; pdb.set_trace()

在你想要进入调试器的位置。然后,您可以按照此语句遍历代码,并在没有调试器的情况下使用该c命令继续运行。

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

代码语言:javascript
复制
>>> import pdb
>>> import mymodule
>>> mymodule.test()
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  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[, locals]])

在调试器控制下执行语句(以字符串形式给出)。调试器提示出现在任何代码执行之前; 你可以设置断点和类型continue,或者你可以使用step或者next(所有这些命令在下面解释)通过语句。可选的全局变量局部变量指定代码执行的环境; 默认情况下__main__使用模块的字典。(请参阅说明execeval()内置函数的说明。)

pdb.runeval(expression[, globals[, locals]])

在调试器控制下评估表达式(以字符串形式给出)。当runeval()返回时,它返回表达式的值。否则这个功能类似于run()

pdb.runcall(function[, argument, ...])

用给定的参数调用函数(函数或方法对象,而不是字符串)。当runcall()返回时,它返回无论函数调用返回。只要输入该函数,调试器提示符就会出现。

pdb.set_trace()

在调用堆栈帧输入调试器。即使代码没有被调试(例如断言失败),这对于在程序中的给定点处对断点进行硬编码也很有用。

pdb.post_mortem([traceback])

输入给定追踪对象的验尸调试。如果没有给出回溯,它将使用当前正在处理的异常(如果要使用默认值,则必须处理异常)。

pdb.pm()

输入发现的回溯的调试sys.last_traceback

这些run*函数set_trace()是用于实例化Pdb类并调用相同名称的方法的别名。如果你想访问更多的功能,你必须自己去做:

class pdb.Pdb(completekey='tab', stdin=None, stdout=None, skip=None)

Pdb 是调试器类。

completekey标准输入标准输出参数被传递到底层cmd.Cmd阶级; 看到那里的描述。

跳跃的说法,如果有,一定要全域式的模块名称模式的迭代。调试器不会进入与匹配其中一种模式的模块相关的帧。[1]

使用跳过启用跟踪的示例调用:

代码语言:javascript
复制
import pdb; pdb.Pdb(skip=['django.*']).set_trace()

2.7版本中的新功能:跳过参数。

run(statement[, globals[, locals]])runeval(expression[, globals[, locals]])runcall(function[, argument, ...])set_trace()

请参阅上述功能的文档。

调试器识别下列命令。大多数命令可以缩写为一个或两个字母; 例如h(elp)意味着可以hhelp可以用来输入帮助命令(但不是he或者helH或者HelpHELP)。命令的参数必须用空格(空格或制表符)分隔。可选参数[]在命令语法中用方括号()括起来; 方括号不能输入。命令语法中的替代方法由垂直条(|)分隔。

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

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

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

调试器支持别名。别名可以有一个参数,使其对被检查的上下文具有一定的适应性。

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

h(elp)命令如果没有参数,请输出可用命令的列表。用命令作为参数,打印关于该命令的帮助。help pdb显示完整的文档文件; 如果PAGER定义了环境变量,则该文件将通过该命令进行传送。由于命令参数必须是标识符,因此help exec必须输入以获取有关!command.w的帮助(此处)打印堆栈跟踪,最近的框架位于底部。一个箭头表示当前帧,它决定了大多数命令的上下文。(自己)将当前帧向下移动一个层级到堆栈轨迹中(向新的帧).u(p)将当前帧向上移动一级堆栈跟踪(到较旧的帧).b(reak)[ 文件名lineno | 功能条件 ]

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

如果存在第二个参数,那么它是一个表达式,它必须在断点被赋予之前评估为true。

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

tbreak [ 文件名lineno | 函数条件 ]临时断点,它在首次命中时被自动删除。参数与break.cl(ear)相同[ filename:lineno | bpnumber bpnumber ... ]使用文件名:lineno参数,清除此行的所有断点。用空格分隔的断点数列表清除这些断点。如果没有参数,请清除所有中断(但首先请确认).disable [ bpnumber bpnumber ...]禁用以空格分隔的断点编号列表给出的断点。禁用断点意​​味着它不会导致程序停止执行,但与清除断点不同,它将保留在断点列表中并且可以(重新)启用。[ bpnumber bpnumber ... ]启用指定的断点.ignore bpnumber 计数设置给定断点编号的忽略计数。如果省略计数,忽略计数设置为0.当忽略计数为零时,断点变为活动状态。非零时,每次到达断点时都会减少计数,并且不禁 用断点,并且任何关联条件的计算结果为true 。条件bpnumber 条件条件是一个表达式,它必须在断点被赋予之前评估为true。如果条件不存在,则删除任何现有条件; 即断点被设置为无条件的命令bpnumber

指定断点编号bpnumber的命令列表。命令本身出现在以下几行。输入只包含'end'的行来终止命令。一个例子:

代码语言:javascript
复制
(Pdb) commands 1
(com) print some_variable
(com) end
(Pdb)

要从断点删除所有命令,请键入命令并立即结束; 也就是说,不给命令。

没有bpnumber参数,命令引用最后一个断点集。

您可以使用断点命令再次启动程序。只需使用continue命令或步骤或恢复执行的任何其他命令即可。

指定恢复执行的任何命令(当前的继续,步骤,下一个,返回,跳转,退出和它们的缩写)终止命令列表(就像该命令紧接着结束)。这是因为,无论何时恢复执行(即使是简单的下一步或步骤),都可能遇到另一个断点 - 它们可能有自己的命令列表,从而导致关于执行哪个列表的歧义。

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

2.5版本中的新功能。

s(tep)执行当前行,在第一个可能的场合停止(在被调用的函数中或在当前函数的下一行中).n(ext)继续执行,直到到达当前函数中的下一行或者它返回。(之间的差nextstepstep一个被调用的函数内停止,而next执行在(几乎)全速,仅在当前函数的下一行停止调用的函数。)UNT(IL)

继续执行,直到到达行号大于当前行的行或从当前帧返回时为止。

2.6版本中的新功能。

r(eturn)继续执行,直到当前函数返回..c(ont(inue))继续执行,只有遇到断点时才停止.jumplineno

设置将要执行的下一行。仅在最底部的框架中可用。这可以让您跳回来并再次执行代码,或者跳转到跳过您不想运行的代码。

应该注意的是,并不是所有的跳转都是允许的 - 例如跳到for循环中或跳出finally子句是不可能的。

l(ist)[ firstlast ]列出当前文件的源代码。如果没有参数,请在当前行的周围列出11行或继续之前的列表。用一个参数,在该行列出11行。有两个参数,列出给定的范围; 如果第二个参数小于第一个参数,则它被解释为一个count.a(rgs)打印当前function.p 表达式的参数列表

评估当前上下文中的表达式并打印其值。

注意

print也可以使用,但不是调试器命令 - 它执行Python print语句。

pp expression_Like p命令,除了使用pprintmodule.alias [_name命令] 漂亮地打印表达式的值

创建一个别名叫做名称,执行命令。该命令不得包含在引号中。可替换参数可以用%1%2等等来表示,而%*被所有参数替代。如果未给出命令,则会显示当前名称的别名。如果没有给出参数,则会列出所有别名。

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

作为一个例子,这里有两个有用的别名(特别是当放在.pdbrc文件中时):

代码语言:javascript
复制
#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_Deletes the specified alias.!_statement

在当前堆栈帧的上下文中执行(单行)语句。除非语句的第一个单词类似于调试器命令,否则感叹号可以省略。要设置全局变量,您可以global在同一行上使用命令作为赋值命令的前缀,例如:

代码语言:javascript
复制
(Pdb) global list_options; list_options = ['-l']
(Pdb)

运行参数 ...

重新启动调试的Python程序。如果提供了一个参数,它将被分割为“shlex”,并将结果用作新的sys.argv。历史记录,断点,动作和调试器选项均被保留。“重新启动”是“运行”的别名。

2.6版本中的新功能。

q(uit)退出调试器。正在执行的程序被中止。

脚注

1

帧是否被认为起源于某个模块是由globals中的__name__决定的。

扫码关注腾讯云开发者

领取腾讯云代金券