pdb
python
的官方调试工具; 默认下载的模块
参考文档
- pdb
pdb
有官方文档, 也有源码, 可能阅读python
源码更容易理解;
和gdb
非常相似,也支持扩展; 基于bdb,cmd
拓展;
代码中设置调试点(一次性调试)
好处是可以源码级别的调试, 对于刚了解pdb
又想调试子进程的比较友好;
pdb
模块显式调用进入调试
即源码级别的支持; gdb
目前无法做到;
# 在想要调试前的位置设置断点
import pdb; pdb.set_trace()
breakpoint
内置函数也可以:更推荐, 不用import pdb
, 但这是一次性调试, 需要手动指定左右的点, 一般要在最开始加;
从头调试:强烈推荐
格式
python -m pdb myscript.py
说明
和import pdb; breakpoint
并非是非此即彼, 水火不容的关系, 建议结合使用效果更佳;
调试指令说明
- 全称和缩写(常用): 缩写有单个字母或两个字母;
h(elp)
- 指令补全(常用): 指令可以补全;
- 空白行(常用): 重复执行上一条,
list
指令特殊; - 非法指令: 当成
python
脚本解析(不推荐这种); - 执行脚本(常用): 后面的内容强行当成
python
脚本执行, 交互式的执行一些函数; - 执行多条
pdb
指令:;;
进行分隔两个指令,string
也会影响, 建议拆分';'';'
(解析器不够智能?);;
不合法, 且不补全, 不推荐; .pdbrc
: 配置
h(elp) [command]
- 未指定
[command]
参数, 输出pdb
支持指令 - 指定
[command]
参数, 输出参数帮助文档;
(Pdb) helpDocumented commands (type help <topic>):
========================================
EOF c d h list q rv undisplay
a cl debug help ll quit s unt
alias clear disable ignore longlist r source until
args commands display interact n restart step up
b condition down j next return tbreak w
break cont enable jump p retval u whatis
bt continue exit l pp run unalias where Miscellaneous help topics:
==========================
exec pdb(Pdb) help c
c(ont(inue))Continue execution, only stop when a breakpoint is encountered.
- 也可以使用
!help(xxx)
查看函数或类之类;(python内置help指令)
堆栈操作
w[here], bt
: 输出当前栈, >
表示当前栈帧
(Pdb) bt/usr/lib/python3.10/bdb.py(597)run()
-> exec(cmd, globals, locals)<string>(1)<module>()
> /home/ch/ch/pyfile/debug/test.py(2)<module>()
-> re.match("xxx", "")
(Pdb) where/usr/lib/python3.10/bdb.py(597)run()
-> exec(cmd, globals, locals)<string>(1)<module>()
> /home/ch/ch/pyfile/debug/test.py(2)<module>()
-> re.match("xxx", "")
调整栈帧:d(own) [count]
向下移动栈帧; [count]
表示移动数量, 未指定默认用1
;
调整栈帧:u(p) [count]
向上移动栈帧; [count]
表示移动数量, 未指定默认用1
;
栈帧移动: gdb
则是用f num
的形式移动到指定
断点操作
断点设置: b(reak) [([filename:]lineno | function) [, condition]]
tb(reak) [([filename:]lineno | function) [, condition]]
- 一次性断点:
b(reak)
永久,tbreak
一次性; [filename:]lineno
: 行级别指定断点, 可以指定文件, 否则以当前文件为准; 从sys.path
目录下搜索function
: 函数, 这种需要import
了之后才可以生效;condition
: 表达式为True
的时候才会中断;
删除断点: cl(ear) [filename:lineno | bpnumber ...]
- 无参数清理所有
filename:lineno
: 清理所在行的所有断点;bpnumber ...
: 空格分隔, 删除对应编号的断点;b
查看;
禁用断点: disable bpnumber [bpnumber ...]
禁用指定编号的断点(同时指定多个), 可用b
指令查看所有;
启动断点: enable bpnumber [bpnumber ...]
启用指定编号的断点(同时指定多个), 可用b
指令查看所有;
跳过断点: ignore bpnumber [count]
- 忽略某个断点
count
,未指定默认0次, 即指令就像未生效; 可用b
指令查看所有;
对某个断点添加触发条件: condition bpnumber [condition]
- 添加
bool
表达式, 用于判断断点是否触发; - 无条件则表示删除;
断点触发时执行额外指令: commands [bpnumber]
- 对指定
bpnumber
或刚才指定的断点添加额外指令;end
结束; - 删除则相当于添加新的, 但是空;
silent
则不输出断点信息;
(Pdb) commands 1
(com) p some_variable
(com) end
(Pdb)
commands
中有一下任意一个都恢复执行, 就好像同时加了command, end
:continue, step, next, return, jump, quit and their abbreviations
;
调试代码
下一条指令: s(tep)
遇到函数就跳到函数里, 否则就下一条指令;
下一条和下一行有很大区别;
下一行指令: n(ext)
一行有多个指令也下一行
unt(il) [lineno]
: 一直执行直到, 中间有断点也停止;
until
有点类似一次性断点;
r(eturn)
执行完当前函数后, 返回并暂停调试;
c(ont(inue))
恢复执行
j(ump) lineno
: 同一帧的跳转, 类似c goto
;
直接跳转到指定行执行; 可以往回, 也可以往后;
调试时查看源码
l(ist) [first[, last]]
- 无参: 当前行往后
11
行, 累加; first
:.
当前往后11
行; 或者指定行后11
行;first, last
: 输出区间的代码
->
: 表示当前行;
>>
: 异常抛出位置;
ll | longlist
当前函数或当前栈帧的所有代码;
变量查看
a(rgs)
: 当前函数参数
(Pdb) b re.match
Breakpoint 1 at /usr/lib/python3.10/re.py:187
(Pdb) c
> /usr/lib/python3.10/re.py(190)match()
-> return _compile(pattern, flags).match(string)
(Pdb) a
pattern = 'xxx'
string = ''
flags = 0
p expression
, pp expression
指定表达式值, 类似print(expression)
whatis expression
输出表达式类型, 表达式可以是一个变量, 也可以是函数执行返回类型;
source expression
查看表达式源码定义;
display [expression]
每次执行, 查看值的前后变化;
retval
:查看函数上次返回值;
interact
进入交互式, 即成当前上下文;
q(uit)
退出整个程序