bdb
--- 偵錯程式框架¶
原始碼: Lib/bdb.py
bdb
模組處理基本的偵錯程式功能,例如設定斷點或透過偵錯程式管理執行。
定義了以下異常:
bdb
模組還定義了兩個類:
- class bdb.Breakpoint(self, file, line, temporary=False, cond=None, funcname=None)¶
這個類實現了臨時斷點、忽略次數、停用和(重新)啟用以及條件斷點。
斷點透過名為
bpbynumber
的列表按編號索引,並透過(file, line)
對透過bplist
索引。前者指向Breakpoint
類的單個例項。後者指向一個這類例項的列表,因為每行可能有多個斷點。建立斷點時,其關聯的
檔名
應為規範形式。如果定義了funcname
,則當該函式的第一行被執行時,斷點命中
將被計數。一個條件
斷點總是會計算一次命中
。Breakpoint
例項具有以下方法:- deleteMe()¶
從與檔案/行關聯的列表中刪除斷點。如果它是該位置的最後一個斷點,它還會刪除檔案/行的條目。
- enable()¶
將斷點標記為啟用。
- disable()¶
將斷點標記為停用。
- bpformat()¶
返回一個包含所有關於斷點資訊的字串,並進行良好格式化:
斷點編號。
臨時狀態(del 或 keep)。
檔案/行位置。
中斷條件。
要忽略的次數。
命中次數。
在 3.2 版本加入。
- bpprint(out=None)¶
將
bpformat()
的輸出列印到檔案 *out*,如果 *out* 為None
,則列印到標準輸出。
Breakpoint
例項具有以下屬性:- file¶
Breakpoint
的檔名。
- line¶
file
中Breakpoint
的行號。
- temporary¶
如果位於(檔案,行)的
Breakpoint
是臨時的,則為True
。
- cond¶
評估位於(檔案,行)的
Breakpoint
的條件。
- funcname¶
函式名,用於定義進入該函式時是否命中
Breakpoint
。
- enabled¶
如果
Breakpoint
已啟用,則為True
。
- bpbynumber¶
單個
Breakpoint
例項的數字索引。
- bplist¶
以 (
file
,line
) 元組為索引的Breakpoint
例項的字典。
- ignore¶
忽略一個
Breakpoint
的次數。
- hits¶
一個
Breakpoint
被命中的次數計數。
- class bdb.Bdb(skip=None, backend='settrace')¶
Bdb
類作為一個通用的 Python 偵錯程式基類。這個類負責處理跟蹤工具的細節;派生類應該實現使用者互動。標準偵錯程式類 (
pdb.Pdb
) 就是一個例子。如果提供了 *skip* 引數,它必須是一個 glob 風格模組名模式的可迭代物件。偵錯程式將不會進入源自於匹配這些模式之一的模組的幀。一個幀是否被認為源自某個特定模組是由該幀的全域性變數中的
__name__
決定的。*backend* 引數指定用於
Bdb
的後端。它可以是'settrace'
或'monitoring'
。'settrace'
使用sys.settrace()
,它具有最好的向後相容性。'monitoring'
後端使用 Python 3.12 中引入的新sys.monitoring
,它可以更高效,因為它能停用未使用的事件。我們試圖為兩個後端保持完全相同的介面,但存在一些差異。鼓勵偵錯程式開發者使用'monitoring'
後端以獲得更好的效能。在 3.1 版本發生變更: 添加了 *skip* 形參。
在 3.14 版本發生變更: 添加了 *backend* 形參。
以下
Bdb
的方法通常不需要被重寫。- canonic(filename)¶
返回 *filename* 的規範形式。
對於真實的檔名,規範形式是一個依賴於作業系統、
大小寫規範化
的絕對 路徑
。一個帶有尖括號的 *filename*,例如在互動模式下生成的"<stdin>"
,會原樣返回。
- start_trace(self)¶
開始跟蹤。對於
'settrace'
後端,此方法等同於sys.settrace(self.trace_dispatch)
。在 3.14 版本加入。
- stop_trace(self)¶
停止跟蹤。對於
'settrace'
後端,此方法等同於sys.settrace(None)
。在 3.14 版本加入。
- trace_dispatch(frame, event, arg)¶
此函式作為被除錯幀的跟蹤函式被安裝。它的返回值是新的跟蹤函式(在大多數情況下,就是它本身)。
預設實現根據即將執行的事件型別(作為字串傳遞)來決定如何分派一個幀。*event* 可以是以下之一:
"line"
: 即將執行一行新程式碼。"call"
: 即將呼叫一個函式,或進入另一個程式碼塊。"return"
: 一個函式或其他程式碼塊即將返回。"exception"
: 發生了一個異常。"c_call"
: 即將呼叫一個 C 函式。"c_return"
: 一個 C 函式已返回。"c_exception"
: 一個 C 函式引發了異常。
對於 Python 事件,會呼叫專門的函式(見下文)。對於 C 事件,不採取任何操作。
*arg* 引數取決於前一個事件。
有關跟蹤函式的更多資訊,請參閱
sys.settrace()
的文件。有關程式碼和幀物件的更多資訊,請參閱 標準型別層級結構。
- dispatch_line(frame)¶
如果偵錯程式應該在當前行停止,則呼叫
user_line()
方法(應在子類中重寫)。如果quitting
標誌被設定(可以從user_line()
中設定),則引發BdbQuit
異常。返回對trace_dispatch()
方法的引用,以便在該作用域中進行進一步的跟蹤。
- dispatch_call(frame, arg)¶
如果偵錯程式應該在此函式呼叫處停止,則呼叫
user_call()
方法(應在子類中重寫)。如果quitting
標誌被設定(可以從user_call()
中設定),則引發BdbQuit
異常。返回對trace_dispatch()
方法的引用,以便在該作用域中進行進一步的跟蹤。
- dispatch_return(frame, arg)¶
如果偵錯程式應該在此函式返回處停止,則呼叫
user_return()
方法(應在子類中重寫)。如果quitting
標誌被設定(可以從user_return()
中設定),則引發BdbQuit
異常。返回對trace_dispatch()
方法的引用,以便在該作用域中進行進一步的跟蹤。
- dispatch_exception(frame, arg)¶
如果偵錯程式應該在此異常處停止,則呼叫
user_exception()
方法(應在子類中重寫)。如果quitting
標誌被設定(可以從user_exception()
中設定),則引發BdbQuit
異常。返回對trace_dispatch()
方法的引用,以便在該作用域中進行進一步的跟蹤。
通常派生類不會重寫以下方法,但如果它們想重新定義停止和斷點的定義,則可以這樣做。
- is_skipped_line(module_name)¶
如果 *module_name* 匹配任何跳過模式,則返回
True
。
- stop_here(frame)¶
如果 *frame* 在堆疊中低於起始幀,則返回
True
。
- break_here(frame)¶
如果此行存在有效斷點,則返回
True
。檢查是否存在行或函式斷點並且生效。根據來自
effective()
的資訊刪除臨時斷點。
- break_anywhere(frame)¶
如果 *frame* 的檔名存在任何斷點,則返回
True
。
派生類應重寫這些方法以控制偵錯程式操作。
- user_call(frame, argument_list)¶
如果中斷可能在被呼叫函式內部停止,則從
dispatch_call()
中呼叫。*argument_list* 不再使用,將始終為
None
。保留此引數是為了向後相容。
- user_line(frame)¶
當
stop_here()
或break_here()
返回True
時,從dispatch_line()
中呼叫。
- user_return(frame, return_value)¶
當
stop_here()
返回True
時,從dispatch_return()
中呼叫。
- user_exception(frame, exc_info)¶
當
stop_here()
返回True
時,從dispatch_exception()
中呼叫。
- do_clear(arg)¶
處理當一個斷點是臨時斷點時,必須如何移除它。
此方法必須由派生類實現。
派生類和客戶端可以呼叫以下方法來影響單步執行狀態。
- set_step()¶
在執行一行程式碼後停止。
- set_next(frame)¶
在給定幀之內或之下的下一行停止。
- set_return(frame)¶
從給定幀返回時停止。
- set_until(frame, lineno=None)¶
當達到行號大於當前行的行,或從當前幀返回時停止。
- set_trace([frame])¶
從 *frame* 開始除錯。如果未指定 *frame*,則從呼叫者的幀開始除錯。
在 3.13 版本發生變更:
set_trace()
將立即進入偵錯程式,而不是在下一行待執行的程式碼處。
- set_continue()¶
僅在斷點處或完成時停止。如果沒有斷點,將系統跟蹤函式設定為
None
。
派生類和客戶端可以呼叫以下方法來操作斷點。如果出現問題,這些方法返回包含錯誤訊息的字串;如果一切正常,則返回
None
。- set_break(filename, lineno, temporary=False, cond=None, funcname=None)¶
設定一個新斷點。如果作為引數傳遞的 *filename* 中不存在 *lineno* 行,則返回錯誤訊息。*filename* 應為規範形式,如
canonic()
方法中所述。
- clear_break(filename, lineno)¶
刪除 *filename* 和 *lineno* 中的斷點。如果未設定任何斷點,則返回錯誤訊息。
- clear_bpbynumber(arg)¶
刪除在
Breakpoint.bpbynumber
中索引為 *arg* 的斷點。如果 *arg* 不是數字或超出範圍,則返回錯誤訊息。
- clear_all_file_breaks(filename)¶
刪除 *filename* 中的所有斷點。如果未設定任何斷點,則返回錯誤訊息。
- clear_all_breaks()¶
刪除所有現有的斷點。如果沒有設定斷點,則返回錯誤訊息。
- get_bpbynumber(arg)¶
返回由給定編號指定的斷點。如果 *arg* 是字串,它將被轉換為數字。如果 *arg* 是非數字字串,或者給定的斷點從未存在或已被刪除,則引發
ValueError
。在 3.2 版本加入。
- get_break(filename, lineno)¶
如果在 *filename* 的 *lineno* 處存在斷點,則返回
True
。
- get_breaks(filename, lineno)¶
返回 *filename* 中 *lineno* 處的所有斷點,如果未設定則返回空列表。
- get_file_breaks(filename)¶
返回 *filename* 中的所有斷點,如果未設定則返回空列表。
- get_all_breaks()¶
返回所有已設定的斷點。
派生類和客戶端可以呼叫以下方法來停用和重啟事件,以獲得更好的效能。這些方法僅在使用
'monitoring'
後端時有效。- disable_current_event()¶
停用當前事件,直到下次呼叫
restart_events()
。當偵錯程式對當前行不感興趣時,這很有用。在 3.14 版本加入。
- restart_events()¶
重新啟動所有已停用的事件。此函式在呼叫
user_*
方法之後,會在dispatch_*
方法中自動呼叫。如果dispatch_*
方法沒有被重寫,已停用的事件將在每次使用者互動後重新啟動。在 3.14 版本加入。
派生類和客戶端可以呼叫以下方法來獲取表示堆疊跟蹤的資料結構。
- get_stack(f, t)¶
返回堆疊跟蹤中的 (frame, lineno) 元組列表和一個大小。
最近呼叫的幀在列表的最後。大小是偵錯程式被呼叫處的幀以下的幀數。
- format_stack_entry(frame_lineno, lprefix=': ')¶
返回一個包含堆疊條目資訊的字串,堆疊條目是一個
(frame, lineno)
元組。返回的字串包含:包含該幀的規範檔案名。
函式名或
"<lambda>"
。輸入引數。
返回值。
程式碼行(如果存在)。
以下兩個方法可以由客戶端呼叫,以使用偵錯程式來除錯一個以字串形式給出的 語句。
- run(cmd, globals=None, locals=None)¶
透過
exec()
函式除錯一個語句。*globals* 預設為__main__.__dict__
,*locals* 預設為 *globals*。
- runcall(func, /, *args, **kwds)¶
除錯單個函式呼叫,並返回其結果。
最後,該模組定義了以下函式:
- bdb.checkfuncname(b, frame)¶
根據
Breakpoint
*b* 的設定方式,返回是否應該在此處中斷。如果它是透過行號設定的,它會檢查
b.line
是否與 *frame* 中的行號相同。如果斷點是透過函式名
設定的,我們必須檢查我們是否在正確的 *frame*(正確的函式)中,以及我們是否在其第一個可執行行上。