pdb --- Python 偵錯器¶
原始碼:Lib/pdb.py
pdb 模組定義了一個 Python 程式的互動式原始碼偵錯器。它支援在原始碼列層級 (source line level) 設定(條件式的)斷點 (breakpoint) 和單步執行、檢視 stack frame(堆疊框)、列出原始碼、以及在任何 stack frame 情境 (context) 中為任意 Python 程式碼求值 (evaluation)。它還支援事後偵錯 (post-mortem debugging),並可以在程式控制下呼叫。
偵錯器是可擴充的 —— 偵錯器實際被定義為 Pdb 類別。該類別目前沒有文件,但可以很容易地透過閱讀原始碼來理解它。擴充套件介面使用了 bdb 和 cmd 模組。
也參考
faulthandler模組用於在出現故障時、超時 (timeout) 後或於接收到使用者訊號時,顯式地轉儲 (dump) Python 回溯 (traceback)。
traceback模組用於提取、格式化和印出 Python 程式 stack trace(堆疊追蹤)的標準介面。
自一個執行中程式切入偵錯器的典型用法為插入:
import pdb; pdb.set_trace()
或:
breakpoint()
到你想切入偵錯器的位置,然後執行程式,就可以單步執行上述陳述式之後的程式碼,並可以使用 continue 命令來離開偵錯器、繼續執行。
在 3.7 版的變更: 當使用預設值呼叫時,可以使用內建的 breakpoint() 來取代 import pdb; pdb.set_trace()。
def double(x):
breakpoint()
return x * 2
val = 3
print(f"{val} * 2 is {double(val)}")
偵錯器的提示字元是 (Pdb),這表示你處於偵錯模式:
> ...(2)double()
-> breakpoint()
(Pdb) p x
3
(Pdb) continue
3 * 2 is 6
在 3.3 版的變更: 透過 readline 模組達成的 tab 補全可用於補全本模組的命令和命令的引數,例如會提供目前的全域和區域名稱以作為 p 命令的引數。
命令列介面¶
你還可以從命令列叫用 pdb 來偵錯其他腳本。例如:
python -m pdb [-c command] (-m module | -p pid | pyfile) [args ...]
當作為模組叫用時,如果被偵錯的程序不正常地退出,pdb 將自動進入事後偵錯。事後偵錯後(或程式正常退出後),pdb 將重新啟動程式。自動重新啟動會保留 pdb 的狀態(例如斷點),並且在大多數情況下比在程式退出時退出偵錯器更有用。
- -m <module>¶
以類似於
python -m的方式來執行模組。與腳本一樣,偵錯器將在模組的第一列之前暫停執行。在 3.7 版的變更: 新增了
-m選項。
- -p, --pid <pid>¶
Attach to the process with the specified PID.
在 3.14 版被加入.
To attach to a running Python process for remote debugging, use the -p or
--pid option with the target process's PID:
python -m pdb -p 1234
備註
Attaching to a process that is blocked in a system call or waiting for I/O will only work once the next bytecode instruction is executed or when the process receives a signal.
在偵錯器控制下執行陳述式的典型用法是:
>>> import pdb
>>> def f(x):
... print(1 / x)
>>> pdb.run("f(2)")
> <string>(1)<module>()
(Pdb) continue
0.5
>>>
檢查一個損壞程式的典型用法:
>>> import pdb
>>> def f(x):
... print(1 / x)
...
>>> f(0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in f
ZeroDivisionError: division by zero
>>> pdb.pm()
> <stdin>(2)f()
(Pdb) p x
0
(Pdb)
本模組定義了下列函式,每個函式進入偵錯器的方式略有不同:
- pdb.run(statement, globals=None, locals=None)¶
在偵錯器控制下執行 statement(以字串或程式碼物件形式給定)。偵錯提示字元會在執行任何程式碼前出現;你可以設定斷點並輸入
continue,或也可以使用step或next逐步執行陳述式(這些命令在下面都有說明)。可選引數 globals 和 locals 指定程式碼執行的環境;預設使用__main__模組的字典。(請參閱內建函式exec()或eval()的說明。)
- pdb.runeval(expression, globals=None, locals=None)¶
在偵錯器控制下為 expression 求值(以字串或程式碼物件形式給定)。當
runeval()回傳時,它回傳 expression 的值。除此之外,該函式與run()類似。
- pdb.runcall(function, *args, **kwds)¶
使用給定的引數呼叫 function(只可以是函式或方法物件,不能是字串)。
runcall()回傳的是所呼叫函式的回傳值。偵錯器提示字元將在進入函式後立即出現。
- pdb.set_trace(*, header=None, commands=None)¶
在呼叫此函式的 stack frame 進入偵錯器。用於在程式中給定之處寫死 (hard-code) 一個斷點,即便該程式碼不在偵錯狀態(如斷言失敗時)。如有給定 header,它將在偵錯正要開始前被印出到控制台。如果給定了 commands 引數,它會是在偵錯器啟動時要執行的命令清單。
在 3.7 版的變更: 僅限關鍵字引數 header。
在 3.13 版的變更:
set_trace()將立即進入偵錯器,而不是在下一列要執行的程式碼中。在 3.14 版被加入: commands 引數。
- awaitable pdb.set_trace_async(*, header=None, commands=None)¶
async version of
set_trace(). This function should be used inside an async function withawait.async def f(): await pdb.set_trace_async()
awaitstatements are supported if the debugger is invoked by this function.在 3.14 版被加入.
- pdb.post_mortem(t=None)¶
進入所給定例外或回溯物件的事後偵錯。如果沒有給定,預設使用目前正在處理的例外,或如果沒有例外則會引發
ValueError。在 3.13 版的變更: 新增對例外物件的支援。
- pdb.pm()¶
進入在
sys.last_exc中發現的例外的事後偵錯。
- pdb.set_default_backend(backend)¶
There are two supported backends for pdb:
'settrace'and'monitoring'. Seebdb.Bdbfor details. The user can set the default backend to use if none is specified when instantiatingPdb. If no backend is specified, the default is'settrace'.備註
breakpoint()andset_trace()will not be affected by this function. They always use'monitoring'backend.在 3.14 版被加入.
- pdb.