pdb
pdb - Python调试器
源代码:
Lib / pdb.py
该模块pdb
为Python程序定义了一个交互式源代码调试器。它支持在源代码级设置(条件)断点和单步执行,检查堆栈帧,源代码列表,以及在任何栈帧的上下文中评估任意Python代码。它也支持验尸调试,可以在程序控制下调用。
调试器是可扩展的 - 它实际上被定义为类Pdb
。这是目前没有记录,但通过阅读来源容易理解。扩展接口使用模块bdb
和cmd
。
调试器的提示符是(Pdb)
。在调试器的控制下运行程序的典型用法是:
>>> import pdb
>>> import mymodule
>>> pdb.run('mymodule.test()')
> <string>(0)?()
(Pdb) continue
> <string>(1)?()
(Pdb) continue
NameError: 'spam'
> <string>(1)?()
(Pdb)
pdb.py
也可以作为调试脚本来调用其他脚本。例如:
python -m pdb myscript.py
当作为脚本调用时,如果正在调试的程序异常退出,pdb将自动进入事后调试。在验尸调试后(或程序正常退出后),pdb将重新启动程序。自动重新启动会保留pdb的状态(如断点),并且在大多数情况下,比程序退出时退出调试器更有用。
2.4版新增:重新启动验尸行为。
从正在运行的程序中插入调试器的典型用法是插入
import pdb; pdb.set_trace()
在你想要进入调试器的位置。然后,您可以按照此语句遍历代码,并在没有调试器的情况下使用该c
命令继续运行。
检查崩溃程序的典型用法是:
>>> 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__
使用模块的字典。(请参阅说明exec
或eval()
内置函数的说明。)
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]
使用跳过
启用跟踪的示例调用:
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)
意味着可以h
或help
可以用来输入帮助命令(但不是he
或者hel
,H
或者Help
或HELP
)。命令的参数必须用空格(空格或制表符)分隔。可选参数[]
在命令语法中用方括号()括起来; 方括号不能输入。命令语法中的替代方法由垂直条(|
)分隔。
输入一个空白行重复输入的最后一个命令。例外:如果最后一条命令是一条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'的行来终止命令。一个例子:
(Pdb) commands 1
(com) print some_variable
(com) end
(Pdb)
要从断点删除所有命令,请键入命令并立即结束; 也就是说,不给命令。
没有bpnumber
参数,命令引用最后一个断点集。
您可以使用断点命令再次启动程序。只需使用continue命令或步骤或恢复执行的任何其他命令即可。
指定恢复执行的任何命令(当前的继续,步骤,下一个,返回,跳转,退出和它们的缩写)终止命令列表(就像该命令紧接着结束)。这是因为,无论何时恢复执行(即使是简单的下一步或步骤),都可能遇到另一个断点 - 它们可能有自己的命令列表,从而导致关于执行哪个列表的歧义。
如果在命令列表中使用'silent'命令,则不会打印有关在断点处停止的常用消息。这对于打印特定消息然后继续的断点可能是理想的。如果其他命令都不打印任何内容,则不会看到已达到断点的迹象。
2.5版本中的新功能。
s(tep)执行当前行,在第一个可能的场合停止(在被调用的函数中或在当前函数的下一行中).n(ext)继续执行,直到到达当前函数中的下一行或者它返回。(之间的差next
和step
是step
一个被调用的函数内停止,而next
执行在(几乎)全速,仅在当前函数的下一行停止调用的函数。)UNT(IL)
继续执行,直到到达行号大于当前行的行或从当前帧返回时为止。
2.6版本中的新功能。
r(eturn)继续执行,直到当前函数返回..c(ont(inue))继续执行,只有遇到断点时才停止.j
(ump
)lineno
设置将要执行的下一行。仅在最底部的框架中可用。这可以让您跳回来并再次执行代码,或者跳转到跳过您不想运行的代码。
应该注意的是,并不是所有的跳转都是允许的 - 例如跳到for
循环中或跳出finally
子句是不可能的。
l(ist)[ first
,last
]列出当前文件的源代码。如果没有参数,请在当前行的周围列出11行或继续之前的列表。用一个参数,在该行列出11行。有两个参数,列出给定的范围; 如果第二个参数小于第一个参数,则它被解释为一个count.a(rgs)打印当前function.p 表达式
的参数列表
评估当前上下文中的表达式
并打印其值。
注意
print
也可以使用,但不是调试器命令 - 它执行Python print
语句。
p
p
expression_Like p命令,除了使用pprintmodule.alias [_name
命令] 漂亮地打印表达式的值
创建一个别名叫做名称
,执行命令
。该命令
不得
包含在引号中。可替换参数可以用%1
,%2
等等来表示,而%*
被所有参数替代。如果未给出命令
,则会显示当前名称的
别名。如果没有给出参数,则会列出所有别名。
别名可以
嵌套并可以
包含任何可以
在pdb提示符下合法键入的内容。请注意,内部pdb命令可以
被别名覆盖。然后隐藏这样的命令,直到别名被删除。别名被递归地应用于命令行的第一个单词; 该行中的所有其他单词都是单独存在的。
作为一个例子,这里有两个有用的别名(特别是当放在.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_Deletes the specified alias.
!
_statement
在当前堆栈帧的上下文中执行(单行)语句
。除非语句
的第一个单词类似于调试器命令,否则感叹号可以省略。要设置全局变量,您可以global
在同一行上使用命令作为赋值命令的前缀,例如:
(Pdb) global list_options; list_options = ['-l']
(Pdb)
运行参数
...
重新启动调试的Python程序。如果提供了一个参数,它将被分割为“shlex”,并将结果用作新的sys.argv。历史记录,断点,动作和调试器选项均被保留。“重新启动”是“运行”的别名。
2.6版本中的新功能。
q(uit)退出调试器。正在执行的程序被中止。
脚注
1 | 帧是否被认为起源于某个模块是由globals中的__name__决定的。 |
---|