透過篩選器附加至處理程序
在 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 test
、ffx 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 測試執行器為每個測試案例啟動一項程序,因此偵錯工具中可能有許多啟動的程序。這些程序將將其名稱替換為測試案例的名稱,以便瀏覽不同的測試案例。系統會在偵錯工具中重新導向這些程序的輸出內容,且可由 stdout
或 stderr
重播。
附加至現有程序
您可以根據程序的 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