使用中斷點

中斷點會在程式碼執行時停止執行。如要建立中斷點,請使用 break 指令,並提供中斷位置。

舉例來說,如要在 main 函式上建立中斷點:

break main
Breakpoint 3 (Software) on Global, Enabled, stop=All, @ main
   180
 ◉ 181 int main(int argc, char**argv) {
   182     fbl::unique_fd dirfd;

在 zxdb 中,您可以透過多種方式表示中斷點。例如:

函式名稱

您可以指定函式名稱,與任何命名空間中的函式名稱相符:

break main

成員函式

您可以在特定命名空間或類別中指定成員函式:

break my_namespace::MyClass::MyFunction
[zxdb] break ::OtherFunction

來源和線條

您也可以指定來源檔案和要中斷的行號:

break mymain.cc:22

行號

您可以在目前畫面的目前來源檔案中指定行號。這項功能在逐行執行程式碼時非常實用:

break 23

記憶體位址

您可以指定記憶體位址:

break 0xf72419a01

運算式

您可以指定運算式,如要進一步瞭解 zxdb 中的運算式,請參閱「評估運算式」。在前面加上 *,系統會將後續輸入內容視為可評估為特定位址的表式。這在使用硬體中斷點時非常實用。

break --type=write *&foo

列出中斷點

如要查看所有中斷點,請使用 breakpoint

breakpoint
  # scope  stop enabled type     #addrs hit-count location
▶ 3 global all  false   software      1         0 machine.h:7

移除中斷點

如要移除特定中斷點,請將該中斷點索引設為 breakpoint <index> rm 的內容。

例如,要清除 breakpoint 3

breakpoint 3 rm
Removed Breakpoint 3 enabled=false @ machine.h:7

清除中斷點

如要移除特定位置的所有中斷點,您不需要指定索引:

clear

當您在暫停點上建立或停止時,該暫停點會自動成為預設值。無論您在沒有特定索引的情況下執行 clear 時,指令都會清除您觸及的最新中斷點。

clear 也可以採用選用位置,就像 break 指令一樣。這樣一來,系統就會嘗試清除該位置的所有中斷點,並忽略預設中斷點內容。

停用中斷點

舉例來說,如要停用中斷點 3

breakpoint 3 disable
Disabled Breakpoint 3 enabled=false @ machine.h:7
   35   static constexpr SizeType InitialStackPointer(SizeType base, SizeType size) {
   36     // Stacks grow down on most machines.
 ◯ 37     return (base + size) & -kStackAlignment<SizeType>;
   38   }
   39 };

如要停用目前的中斷點,請按照下列步驟操作:

disable
Disabled Breakpoint 2 enabled=false @ main.rs:5
   24
   25 enum Services {
 ◯ 26     ComponentRunner(frunner::ComponentRunnerRequestStream),
   27     StarnixManager(fstarnixrunner::ManagerRequestStream),
   28     AttributionProvider(fattribution::ProviderRequestStream),

啟用中斷點

停用中斷點後,您可能會想要重新啟用已停用的中斷點。

舉例來說,如要啟用中斷點 3

breakpoint 3 enable
Enabled Breakpoint 3 @ machine.h:7
   35   static constexpr SizeType InitialStackPointer(SizeType base, SizeType size) {
   36     // Stacks grow down on most machines.
 ◉ 37     return (base + size) & -kStackAlignment<SizeType>;
   38   }
   39 };

設定及取得中斷點屬性

您也可以使用 getset 指令修改中斷點屬性。

舉例來說,如要從中斷點 4 擷取 location 屬性:

breakpoint 4 get location
location (locations)

  The location (symbol, line number, address, or expression) where this
  breakpoint will be set. See "help break" for documentation on how to specify.

location = machine.h:7

舉例來說,如要將 location 屬性從中斷點 4 設為 machine.h:8

breakpoint 4 set location = machine.h:8
Set breakpoint 4 location = machine.h:8

條件中斷點

您也可以設定中斷點,讓中斷點包含條件。條件是評估結果為 truefalse 的運算式。設定條件時,除非條件為 true,否則中斷點不會觸發停止動作。

舉例來說,如果您要對 cobalt.cm 元件進行偵錯:

舉例來說,如要新增 main.cc:352 的有條件中斷點位置,請按照下列步驟操作:

  [zxdb] b main.cc:352 if command_line.has_argv0 == false
  Created Breakpoint 1 condition="command_line.has_argv0 == false" @ ../../src/myapp/bin/app/main.cc:352
    351   }
  ◉ 352   inspector.Health().Ok();
    353   loop.Run();
    354   FX_LOGS(INFO) << "Cobalt will now shut down.";

硬體資料中斷點

在 zxdb 中,硬體中斷點會以中斷點類型呈現,而非個別的「觀察點」

您可以設定處理器,在讀取或寫入特定位址時中斷執行作業。這對追蹤記憶體損毀情況很有幫助。

您可以為 break 指令的 type 屬性使用下列任何值,建立硬體中斷點。

  • execute
  • write
  • read-write

例如,如要設定 execute 類型的中斷點:

break --type=execute myfile.rs:123

watch 與使用 break --type=read-write 相同。請參閱 watch 指令

watch 指令

watch 指令可做為捷徑,用來取得變數內容或運算式的結果,並在其範圍內設定資料寫入中斷點:

watch i
[zxdb] watch foo[5]->bar

如果您在堆疊上 watch 變數,但沒有人觸碰該變數,那麼當堆疊記憶體重複使用時,您經常會在程式的其他部分看到該變數。如果您意外地觸及中斷點,請確認執行作業仍在預期的框架中。

程式輔助中斷點

在某些情況下,您可能會想在程式碼中擷取特定條件。如要執行此操作,您可以在程式碼中插入硬式編碼的中斷點。

Clang 內建:

__builtin_debugtrap();

如果 zxdb 已連結至程序,則會停止,就像觸及一般中斷點一樣。接著,您可以stepcontinue。如果未附加偵錯工具,這會導致應用程式當機。