bp, bu, bm (設定斷點)
bp、bu 和 bm 命令會設定一或多個軟體斷點。 您可以結合位置、條件和選項來設定不同類型的軟體斷點。
使用者模式
[~Thread] bp[ID] [Options] [Address [Passes]] ["CommandString"]
[~Thread] bu[ID] [Options] [Address [Passes]] ["CommandString"]
[~Thread] bm [Options] SymbolPattern [Passes] ["CommandString"]
內核模式
bp[ID] [Options] [Address [Passes]] ["CommandString"]
bu[ID] [Options] [Address [Passes]] ["CommandString"]
bm [Options] SymbolPattern [Passes] ["CommandString"]
參數
線
指定斷點所套用的線程。 如需語法的詳細資訊,請參閱 線程語法。 您只能在使用者模式中指定線程。 如果您未指定線程,斷點會套用至所有線程。
標識碼
指定識別斷點的十進位數。
調試程式會在建立斷點時指派標識符,但您可以使用 br (Breakpoint Renumber) 命令加以變更。 您可以使用識別碼,在稍後的調試程式命令中參考斷點。 若要顯示斷點的識別碼,請使用 bl (斷點清單) 命令。
當您在命令中使用 識別碼 時,請勿在命令 (bp 或 bu) 與識別符之間輸入空格。
ID 參數一律為選擇性。 如果您未指定 標識碼,調試程式會使用第一個可用的斷點號碼。 在核心模式中,您只能設定 32 個斷點。 在使用者模式中,您可以設定任意數目的斷點。 不論是哪一種情況,標識碼的值都沒有限制。 如果您以方括弧 ([]] 括住標識符,ID 可以包含任何運算式。 如需語法的詳細資訊,請參閱 數值表達式語法。
選項 指定斷點選項。 您可以指定下列任何數目的選項,但如所示:
/1
建立「單次」斷點。 觸發此斷點之後,它會從斷點清單中刪除。
/p EProcess
(僅限內核模式)指定與此斷點相關聯的進程。 EProcess 應該是 EPROCESS 結構的實際位址,而不是 PID。 只有在在此進程的內容中遇到斷點時,才會觸發斷點。
/t EThread
(僅限內核模式)指定與此斷點相關聯的線程。 EThread 應該是 ETHREAD 結構的實際位址,而不是線程標識碼。 只有在此線程的內容中遇到斷點時,才會觸發斷點。 如果您使用 /p EProcess 和 /t EThread,您可以依任何順序輸入它們。
/c MaxCallStackDepth
只有在呼叫堆疊深度小於 MaxCallStackDepth 時,才會啟動斷點。 您無法搭配 /C 使用此選項。
/C MinCallStackDepth
只有在呼叫堆疊深度大於 MinCallStackDepth時,才會啟動斷點。 您無法搭配 /c 使用此選項。
/一個
(僅適用於 bm ) 會設定所有指定位置的斷點,無論是數據空間還是程式代碼空間。 因為數據上的斷點可能會導致程序失敗,因此請只在已知安全的位置使用此選項。
/d
(僅適用於 bm) 將斷點位置轉換為位址。 因此,如果移動程式代碼,斷點會維持在相同的位址,而不是根據 SymbolPattern 進行設定。 使用 /d 避免在載入或卸除模組時重新評估斷點的變更。
/(
(僅限 bm) 在 SymbolString 定義的符號字串中包含參數清單資訊。
此功能可讓您在具有相同名稱但不同參數清單的多載函式上設定斷點。 例如,bm /( myFunc 會在 myFunc(int a) 和 myFunc(char a) 上設定斷點。 如果沒有 「/(」,myFunc 上設定的斷點會失敗,因為它不會指出斷點所要使用的 myFunc 函式。
/w dx 對象表示式根據 dx 物件表示式所傳回的布爾值,設定條件斷點。 自變數是數據模型 (dx) 表示式,其評估為 true(符合條件 – 中斷) 或 false (不符合條件 – 不中斷)。
此範例會根據localVariable的值設定條件斷點。
bp /w "localVariable == 4" mymodule!myfunction
此範例示範如何使用 JavaScript 設定斷點。
bp /w "@$scriptContents.myFunc(localVariable)" @rip
如需調試程式對象的詳細資訊,請參閱 dx (顯示除錯程式物件模型表達式)。
如需條件斷點的詳細資訊,請參閱 設定條件斷點。
位址
指定設定斷點之指令的第一個字節。 如果您省略 Address,則會使用目前的指令指標。 如需語法的詳細資訊,請參閱 地址和地址範圍語法。
通過
指定啟動斷點的執行傳遞數目。 調試程式會略過斷點位置,直到到達指定的傳遞為止。 Passes 的值可以是任何 16 位或 32 位值。
根據預設,斷點會在應用程式第一次執行包含斷點位置的程序代碼時使用中。 此預設情況相當於傳遞的值為 1。 若要只在應用程式執行程式代碼至少一次之後啟動斷點,請輸入 2 或更多值。 例如,值 2 會在第二次執行程式代碼時啟動斷點。
此參數會建立一個計數器,在每次通過程式代碼時遞減。 若要查看 Passes 計數器的初始和目前值,請使用 bl (斷點清單) 。
只有在應用程式執行超過斷點以回應 g (Go) 命令時,傳遞計數器才會遞減。 如果您要逐步執行程式代碼或追蹤,則計數器不會遞減。 當 Passes 計數器達到 1 時,您只能藉由清除並重設斷點來重設它。
CommandString
指定每次遇到斷點時所執行的命令清單指定次數。 您必須以引弧括 住 CommandString 參數。 使用分號來分隔多個命令。
CommandString 中的調試程式命令可以包含參數。 您可以使用標準 C 控制字元(例如 \n 和 \“)。 包含在第二層引號 (\“) 中的分號會解譯為內嵌引號字串的一部分。
只有在應用程式執行以回應 g (Go) 命令時到達斷點時,才會執行 CommandString 命令。 如果您要逐步執行程式代碼或追蹤超過這個點,則不會執行命令。
在斷點 (例如 g 或 t) 結束命令清單執行之後繼續執行程式的任何命令。
SymbolPattern
指定模式。 調試程式會嘗試將此模式比對現有的符號,並在所有模式相符項目上設定斷點。 SymbolPattern 可以包含各種通配符和規範。 如需此語法的詳細資訊,請參閱 字串通配符語法。 由於這些字元會比對符號,因此比對不區分大小寫,而單一前置底線 (_) 代表任何數量的前置底線。
Environment
項目 | 說明 |
---|---|
模式 | 使用者模式、核心模式 |
目標 | 僅限即時偵錯 |
平台 | 全部 |
其他資訊
如需如何使用斷點、控制斷點的其他斷點命令和方法,以及如何從核心調試程式在用戶空間中設定斷點的詳細資訊,請參閱 使用斷點。 如需條件斷點的詳細資訊,請參閱 設定條件斷點。
備註
bp、bu 和 bm 命令會設定新的斷點,但它們有不同的特性:
bp (設定斷點) 命令會在命令中指定的斷點位置位址設定新的斷點。 如果調試程式在設定斷點時無法解析斷點位置的位址表達式, 則 bp 斷點會自動轉換成 bu 斷點。 使用 bp 命令建立斷點,如果卸除模組,該斷點不再作用中。
bu (Set Unresolved Breakpoint) 命令會設定延遲或未解決的斷點。 bu 斷點是在命令中指定之斷點位置的符號參考上設定的,且會在解析具有參考的模塊時啟動。 如需這些斷點的詳細資訊,請參閱無法解析的斷點(bu 斷點)。
bm (設定符號斷點) 命令會在符合指定模式的符號上設定新的斷點。 此命令可以建立多個斷點。 根據預設,比對模式之後, bm 斷點會與 bu 斷點相同。 也就是說, bm 斷點是符號參考上設定的延後斷點。 不過,bm /d 命令會建立一或多個 bp 斷點。 每個斷點都會設定在相符位置的位址上,而且不會追蹤模塊狀態。
如果您不確定用來設定現有斷點的命令,請使用 .bpcmds (顯示斷點命令) 來列出所有斷點,以及用來建立斷點的命令。
bp 斷點和 bu 斷點之間有三個主要差異:
bp 斷點位置一律會轉換成位址。 如果模組變更移動 bp 斷點設定所在的程式代碼,斷點會維持在相同的位址。 另一 方面,bu 斷點仍與使用的符號值(通常是符號加位移)相關聯,即使其位址變更,也會追蹤此符號位置。
如果在載入的模組中找到 bp 斷點位址,而且稍後卸除該模組,則會從斷點清單中移除斷點。 另一方面, bu 斷點會在重複卸除和載入之後保存。
您使用 bp 設定的斷點不會儲存在 WinDbg 工作區中。 使用 bu 設定的斷點會儲存在工作區中。
當您想要在斷點的符號模式中使用通配符時,bm 命令很有用。 bm SymbolPattern 語法相當於使用 x SymbolPattern,然後在每個結果上使用 bu。 例如,若要設定以字串 「mem」 開頭之 Myprogram 模組中所有符號的斷點,請使用下列命令。
範例
0:000> bm myprogram!mem*
4: 0040d070 MyProgram!memcpy
5: 0040c560 MyProgram!memmove
6: 00408960 MyProgram!memset
由於 bm 命令會設定軟體斷點(而非處理器斷點),因此它會在設定斷點以避免損毀數據時自動排除數據位置。
使用 bp 或 bm /a 命令時,可以指定資料位址,而不是程式位址。 不過,即使指定數據位置,這些命令也會建立軟體斷點,而不是處理器斷點。 如果軟體斷點放在程序數據中,而不是可執行的程式代碼,可能會導致數據損毀。 因此,只有當您確定儲存在該位置中的記憶體將做為可執行程序代碼,而不是程序數據時,才應該在數據位置使用這些命令。 否則,您應該改用 ba (Break on Access) 命令。 如需詳細資訊,請參閱處理器斷點(ba 斷點)。
如需如何在更複雜的語法所指定位置設定斷點的詳細資訊,例如C++公用類別的成員,或包含其他限制字元的任意文字字串,請參閱 斷點語法。
如果單一邏輯來源行跨越多個實體行,斷點會在語句或呼叫的最後一個實體行上設定。 如果調試程式無法在要求的位置設定斷點,它會將斷點置於下一個允許的位置。
如果您指定 Thread,則會在指定的線程上設定斷點。 例如,~*bp 命令會在所有線程上設定斷點,~#bp 會在造成目前例外狀況的線程上設定斷點,而 ~123bp 會在線程 123 上設定斷點。 ~bp 和 ~.bp 命令會在目前的線程上設定斷點。
當您在核心模式中偵錯多處理器系統時,使用 bp 或 ba 設定的斷點會套用至所有處理器。 例如,如果目前的處理器是 3,而且您輸入 bp MemoryAddress 將斷點 放在 MemoryAddress。 在該位址執行的任何處理器(不只處理器 3)都會造成斷點陷阱。
bp、bu 和 bm 命令會藉由以中斷指令取代處理器指令來設定軟體斷點。 若要偵錯無法變更的唯讀程式代碼或程序代碼,請使用ba e命令,其中 e 代表僅限執行存取。
下列命令會設定超過函式 MyTest 開頭的斷點 12 個字節。 前六次通過程式代碼時會忽略這個斷點,但執行會在第七次通過程式代碼時停止。
0:000> bp MyTest+0xb 7
下列命令會在 RtlRaiseException 設定斷點、顯示 eax 快取器、顯示符號 MyVar 的值,然後繼續。
kd> bp ntdll!RtlRaiseException "r eax; dt MyVar; g"
下列兩 個 bm 命令會設定三個斷點。 執行命令時,顯示的結果不會區分以 /d 參數建立的斷點,以及未建立的斷點。 .bpcmds (顯示斷點命令) 可用來區分這兩種類型。 如果斷點是由沒有 /d 參數的 bm 所建立,.bpcmds 顯示會指出斷點類型為 bu,後面接著以 @!“” 標記括住的已評估符號(這表示它是常值符號,而不是數值表達式或緩存器)。 如果斷點是由 bm 使用 /d 參數所建立,.bpcmds 顯示會指出斷點類型為 bp。
0:000> bm myprog!openf*
0: 00421200 @!"myprog!openFile"
1: 00427800 @!"myprog!openFilter"
0:000> bm /d myprog!closef*
2: 00421600 @!"myprog!closeFile"
0:000> .bpcmds
bu0 @!"myprog!openFile";
bu1 @!"myprog!openFilter";
bp2 0x00421600 ;