在 zxdb 中使用中斷點

執行某些程式碼時,中斷點會停止執行。如要建立中斷點,請使用 break 指令 (簡稱 b) 並指定位置:

[zxdb] 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
    
  • 特定命名空間或類別中的成員函式或函式:

    [zxdb] break my_namespace::MyClass::MyFunction
    [zxdb] break ::OtherFunction
    
  • 來源檔案 + 行號 (以冒號分隔):

    [zxdb] break mymain.cc:22
    
  • 目前頁框的目前來源檔案中的行號 (跨步時相當實用):

    [zxdb] break 23
    
  • 記憶體位址:

    [zxdb] break 0xf72419a01
    
  • 運算式:前置字串為「*」時,系統會將下列輸入視為評估位址的運算式。這最常與硬體中斷點搭配使用。

    [zxdb] break --type=write *&foo
    

如何列出所有中斷點:

[zxdb] breakpoint

如要清除特定中斷點,請提供該中斷點索引做為明確指令的背景資訊 (請參閱上方的「互動模型」)。我們採用 breakpoint (bp) 的縮寫:

[zxdb] bp 2 clear

您也可以清除目前的中斷點:

[zxdb] clear

每當您在中斷點上建立或停止時,中斷點就會自動成為預設中斷點,因此 clear 一律會清除您剛剛命中的中斷點。

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

GDB 使用者註意事項:delete <index> 對應至 bp <index> clear,而 clear <number> 在 GDB 和 zxdb 中的行為相同。

你也可以啟用或停用中斷點:

[zxdb] disable
[zxdb] bp 4 enable

其他屬性可透過「get」和「set」指令修改。

[zxdb] bp 1 set location = Frobulator::GetThing

條件式中斷點

中斷點可視需要有條件,該條件為評估為 true 或 false 的運算式。除非條件為 True,否則中斷點不會觸發停止。例如,假設有一個來源檔案

    7 void do_loop(int n) {
    8   for (int i = 0; i < n; i++) {
 ▶  9     std::cout << "Hello world!" << std::endl;
   10   }
   11 }

您可以設定僅在上次疊代時停止的中斷點。

b 9 if i == n - 1

硬體資料中斷點 (「觀察點」)

處理器可以設為在讀取或寫入特定位址時中斷執行作業。這在追蹤記憶體損毀時特別有用。在中斷指令的「類型」中指定「write」、「execute」或「read-write」,即可建立硬體中斷點 (與其他偵錯工具不同,硬體中斷點會以中斷點的形式公開,而非做為獨立的「觀察點」概念)。

[zxdb] break --type=read-write --size=4 0x12345670

簡單來說,「watch」指令會擷取變數或運算式的結果,並設定該運算式的範圍資料寫入中斷點:

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

注意:

  • CPU 僅支援數量有限的硬體觀察點,通常是 4 個左右。

  • 觀察點範圍的大小限制為 1、2、4 或 8 個位元組,且位址必須是大小的偶數。

  • 有別於 GDB,「watch」會評估運算式一次,然後設定結果的中斷點。系統不會重新評估運算式。在上述範例中,當「bar」變更時會觸發,但如果 foo[5] 變更為指向不同的「bar」,就不會觸發。

  • 如果您觀察到堆疊中的變數,但沒有任何人觸碰,則在重複使用堆疊記憶體時,您經常會在程式的其他部分中發現該變數。如果發現中斷點命中,請檢查執行作業是否仍在預期的影格中。

程式輔助中斷點

如要擷取某些特定條件,您可以在程式碼中插入硬式編碼中斷點。Clang 已內建 (不適用於 GCC Zircon 版本):

__builtin_debugtrap();

如果偵錯工具已附加至程序,就會像執行一般中斷點一樣停止。 你可以採取其他步驟,也可以繼續操作。如果尚未附加偵錯工具,可能會導致當機。