對處理程序、元件或當機傾印進行偵錯

透過篩選器附加至處理程序

在 Fuchsia 上執行程序比其他系統更為複雜,因為沒有預設環境 (請參閱下方「啟動器環境的注意事項」一節)。

如要可靠地對所有類型的程序進行偵錯,唯一的方法是透過「附加」建立篩選器,然後依照在偵錯工具以外執行該程序的一般方式啟動該程序。偵錯工具支援下列篩選條件。

  • 元件路徑名稱 (v2 元件)。
  • 元件網址 (v2 元件)。
  • 程序名稱、完全比對或部分比對。

「Attach」指令會根據格式,以不同的方式解讀輸入。例如,attach /core/feedback 會解讀為元件對話方塊,因此會建立符合該元件中「所有」程序的篩選器,而 attach fuchsia-boot:///#meta/archivist.cm 則會解譯為元件網址,並可能比對多個元件中的程序。

為了方便起見,您可以只將元件網址的最後部分傳遞至「Attach」指令。因此,attach archivist.cm 的運作方式與 attach fuchsia-boot:///#meta/archivist.cm 相同。

如果輸入內容看起來不像某些元件,Google 會將其解讀為程序名稱。程序的啟動器可以自由設定程序名稱。如要確認這是什麼,請在偵錯工具或系統殼層中使用「ps」。

此範例會在 main 上設定在執行開始時停止的待處理中斷點,並等待「my_app.cm」元件中的程序開始:

[zxdb] attach my_app.cm
Waiting for process matching "my_app.cm".

[zxdb] break main
Created Breakpoint 1 @ main
Pending: No current matches for location. It will be matched against new
         processes and shared libraries.

接著,請以平常使用的方式執行程序,也就是直接透過指令列執行,或透過 fx testffx component run /core/... fuchsia-pkg://... 或其他方式執行。偵錯工具應該會立即在 main 上中斷 (載入符號可能需要一些時間,因此您可能會在顯示原始碼前看到延遲):

Attached Process 1 [Running] koid=51590 my_app.cm
🛑 on bp 1 main(…) • main.cc:222
   220 }
   221
 ▶ 222 int main(int argc, const char* argv[]) {
   223   foo::CommandLineOptions options;
   224   cmdline::Status status = ParseCommandLine(argc, argv, &options);

接著就能執行與 GDB 類似的基本指令:

next
step
print argv[1]
continue
quit

直接在偵錯工具中啟動

您可以直接在偵錯工具中啟動執行檔、元件或測試。

啟動執行檔

使用 run <executable> 從偵錯工具啟動執行檔。請注意,在 Fuchsia 中,所有程序都必須在命名空間中執行。run 會在 debug_agent 的命名空間中啟動程序,這表示只有 debug_agent 套件中的執行檔和 Bootfs 的執行檔。由於這些程序是在 debug_agent 的命名空間中執行,因此程序也會共用 debug_agent 的功能。

由於有上述限制,run 只能用來執行部分示範程式。

啟動元件

請使用 run-component <component url> 啟動元件。V2 元件將在 ffx-laboratory 集合中建立,類似於 ffx component run --recreate 的行為。元件的輸出內容「不會」重新導向。由於已套用 ffx-laboratory 的所有限制,因此 run-component 通常只會用於啟動示範程式。

啟動測試

使用 run-test <test url> 啟動測試,與 ffx test run 類似。您可以提供選用的案例篩選器,以指定要執行的測試案例。

由於 Fuchsia 測試執行器為每個測試案例啟動一項程序,因此偵錯工具中可能有許多啟動的程序。這些程序將將其名稱替換為測試案例的名稱,以便瀏覽不同的測試案例。系統會在偵錯工具中重新導向這些程序的輸出內容,且可由 stdoutstderr 重播。

附加至現有程序

您可以根據程序的 koid,連接大部分執行中的程序 (套用至程序的「核心物件 ID」,等同於其他系統上的程序 ID)。您可以在目標 Fuchsia 系統上執行 ps,或使用 zxdb 的內建 ps 指令來取得 koid:

[zxdb] ps
j: 1030 root
  j: 1079 zircon-drivers
    p: 1926 driver_host
...

在此清單中,「j:」表示工作 (用於程序的容器),「p:」表示程序。類型前置字串後的數字就是物件的 koid。

然後,即可附加:

[zxdb] attach 3517
Process 1 Running koid=1249 pwrbtn-monitor

完成後,您可以選擇 detach (繼續執行) 或 kill (終止) 程序。

附加至特定工作的程序

您可以將篩選器的範圍限制在特定工作。在這種情況下,篩選器可以留空,也就是附加至所有套用的程序。例如:

[zxdb] ps
 j: 1033 root
   j: 2057
     p: 2274 foobar.cm
     j: 2301
       p: 2307 foo
       p: 2318 bar

attach -j 2301 foo 只會附加至程序 2307。attach -j 2057 會連接至全部 3 個程序。

偵錯驅動程式

目前無法在系統啟動時提早設定偵錯工具,無法對大部分的驅動程式庫初始化進行偵錯。由於 zxdb 本身使用網路和檔案系統,因此任何與網路通訊相關的驅動程式無法偵錯,而且儲存體或其他重要系統功能都不算是多個驅動程式。

如要對執行中的驅動程式進行偵錯,您可以連接至驅動程式庫主機,該主機可由 ffx driver list-hosts 列出。由於驅動程式庫不受偵錯工具依附,您可以呼叫 WaitForDebugger() 來延遲驅動程式的初始化作業。在 C++ 中,請使用

// Add //src/lib/debug to the dependency.
#include "src/lib/debug/debug.h"

debug::WaitForDebugger();

在 Rust 中:

// Add //src/lib/debug/rust to the dependency.
debug::wait_for_debugger(60);

附加偵錯工具後,WaitForDebugger() 會觸發軟體中斷點。執行必要設定後,請輸入 continue 繼續執行。

對當機傾印進行偵錯

Zxdb 支援載入當機報告產生的 minidump。使用「opendump」動詞並提供傾印的本機檔案名稱。偵錯工具不得附加至其他傾印或正在執行的系統 (如果有的話,請先使用「disconnect」)。

[zxdb] opendump upload_file_minidump-e71256ba30163a0.dmp
Opening dump file
Dump loaded successfully.

現在,您可以使用執行緒、堆疊及記憶體指令檢查程式的狀態。請使用 disconnect 關閉傾印。

您也可以使用 ffx debug core 指令,例如:

ffx debug core upload_file_minidump-e71256ba30163a0.dmp

正在下載符號

Zxdb 會自動搜尋在 symbol-index 中註冊的伺服器,尋找在任何本機設定符號目錄中找不到的符號。您可以使用下列指令,查看符號索引中註冊的符號伺服器完整清單:

ffx debug symbol-index list -a

以遞迴方式掃遍並解析包含在全域符號索引中的所有符號索引檔案。詳情請參閱關於符號設定

顯示的伺服器會用來下載符號檔案,並以非同步方式將其載入偵錯工具。針對特別大型的 debuginfo 檔案,您可以在 zxdb 中看見 sym-stat 的輸出內容:

[zxdb] sym-stat
...
    Base: 0xc37e9000
    Build ID: ba17ef8c43bccf5fb6bf84f9a8d83d9cf3be8976 (Downloading...)
    Symbols loaded: No
...

表示下載正在進行中。下載檔案後,zxdb 會從新下載的檔案建立索引,並繼續偵錯。

對多個程序進行偵錯

您可以同時對多個程序進行偵錯。當已在偵錯工具中執行程序時,附加或執行時,只會平行建立新的程序。

回想一下「互動模型」部分,您可以使用下列方式列出目前的程序:

[zxdb] process
  # State       Koid Name
▶ 1 Running     1249 pwrbtn-monitor
  2 Not running 7235 pwrbtn-monitor

提供其中一個索引 (而非 koid) 做為預設選項:

[zxdb] process 2

或者,您也可以透過下列指令,將指令套用至特定程序 (即使非預設程序也包括在內):

[zxdb] process 2 pause