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)
退出整個程序