總覽
Just In Time Debugging (JITD) 可讓 Fuchsia 暫停停止運作的程序,讓感興趣的相關方日後可以偵錯/處理程序。這樣做可允許有趣的流程,例如在未附加/執行偵錯工具的情況下,將 zxdb 附加至一個夜晚當機的程式。
方法是將程序儲存在名為「Process Limbo」的特殊位置中。此時,這些程序會保持暫停使用狀態,直到其他代理程式推出並釋出為止。
如要進一步瞭解運作原理,請參閱「導入」一文。
如何啟用
程序 Limbo 的一大優點,就是能夠在野外偵測當機程序,而無需執行偵錯工具。偵錯工具「無法」執行時 (例如驅動程式庫啟動) 特別實用。在此情況下,使用有效的 Process Limbo 就能提供重要的偵錯資訊來源。
啟用 Process Limbo 的方法有兩種:
手動啟動
以下的 ffx 外掛程式可讓使用者查詢 Limbo 的目前狀態:
$ ffx debug limbo --help
Usage: ffx debug limbo <command> [<args>]
control the process limbo on the target
Options:
--help display usage information
Commands:
status query the status of the process limbo.
enable enable the process limbo. It will now begin to capture
crashing processes.
disable disable the process limbo. Will free any pending processes
waiting in it.
list lists the processes currently waiting on limbo. The limbo
must be active.
release release a process from limbo. The limbo must be active.
See 'ffx help <command>' for more information on a specific command.
啟動時啟用
只有在能夠將指令傳送至系統時,才能使用手動啟動功能。但是,有些開發環境會提早執行,供使用者進行互動 (或執行偵錯工具) 的軟體。驅動程式就是很好的範例對於這類情況,只要將 Process Limbo 從一開始就啟用,即可在驅動驅動程式庫啟動時掌握驅動程式庫當機,通常是最困難的部分。
為此,必須設為建構作業的一項設定:
fx set <YOUR CONFIG> --with-base //src/developer/forensics:exceptions_enable_jitd_on_startup
也可以在建構引數中的 base_package_labels
加上這個標籤。您之後仍然可以使用 Process Limbo CLI 工具停用及操控 Limbo。然後,您必須將更新推送至裝置,此設定才會生效。
注意:驅動程式初始化是未完成且凍結的當機程序,可能會導致系統處於未定義的狀態並「停止運作」,因此使用此功能時里程數可能會有所不同,尤其是對於非常早期的駕駛人而言。
使用方式
Zxdb
JITD 的主要使用者是 zxdb,其可附加至 limbo 中的處理程序中。啟動 zxdb 時,會自動附加至 limbo 中的程序:
$ ffx debug connect
Connecting (use "disconnect" to cancel)...
Connected successfully.
👉 To get started, try "status" or "help".
Processes attached from limbo:
48487: crasher
Type "detach <pid>" to send back to Process Limbo if attached,
type "detach <pid>" again to terminate the process if not attached, or
type "process <process context #> kill" to terminate the process if attached.
See "help jitd" for more information on Just-In-Time-Debugging.
Process "crasher" (48487) crashed and has been automatically attached.
Type "status" for more information.
Attached Process 1 state=Running koid=48487 name=crasher component=sshd-host.cm
Loading 9 modules for crasher Done.
23
24 int blind_write(volatile unsigned int* addr) {
▶ 25 *addr = 0xBAD1DEA;
26 return 0;
27 }
════════════════════════════════════════════════════════════════════════════
Data fault writing address 0x0 (translation fault level 2) (second chance)
════════════════════════════════════════════════════════════════════════════
Process 1 (koid=48487) thread 1 (koid=48489)
Faulting instruction: 0x642ff060
🛑 blind_write(volatile unsigned int*) • crasher.c:25
[zxdb] thread
# state koid name
▶ 1 Blocked (Exception) 58692 initial-thread
[zxdb] frame
▶ 0 blind_write(…) • crasher.c:25
1 main(…) • crasher.c:356
2…4 «libc startup» (-r expands)
[zxdb] list
20 int (*func)(volatile unsigned int*);
21 const char* desc;
22 } command_t;
23
24 int blind_write(volatile unsigned int* addr) {
▶ 25 *addr = 0xBAD1DEA;
26 return 0;
27 }
28
29 int blind_read(volatile unsigned int* addr) { return (int)(*addr); }
30
31 int blind_execute(volatile unsigned int* addr) {
32 void (*func)(void) = (void*)addr;
33 func();
34 return 0;
35 }
在 zxdb 中也可以執行 help jitd
,進一步瞭解使用方式。
程序 Limbo FIDL 服務
程序 Limbo 將本身顯示為 FIDL 服務,也就是 Process Limbo CLI 工具和 zxdb 使用的服務。FIDL 通訊協定是在 //sdk/fidl/fuchsia.exception/process_limbo.fidl
中定義。
實作
當機服務
程序擲回例外狀況時,Zircon 會產生相關聯的 exception handle
。然後查看任何相關例外狀況管道中是否有任何事件監聽器,以便處理該例外狀況。透過這種方式,zxdb 等偵錯工具會從執行中的程序取得例外狀況。詳情請參閱例外狀況處理。
不過,如果因為沒有任何例外狀況處理常式或全部決定傳遞該處理常式,根工作就會擁有名為 crashsvc
的專屬處理常式。一旦達到例外狀況,系統會瞭解發生「當機」情形,且沒有任何程式能夠處理例外狀況。當機服務隨後會將當機的堆疊追蹤轉儲到記錄中,並將例外狀況傳遞至 Exception Broker
。
例外狀況仲介
例外狀況代理程式會根據實際的系統設定,決定要如何處理當機例外狀況。這可能會決定建立 minidump 檔案並轉儲當機報告、將例外狀況傳送至 Process Limbo,或結束程序。
例外狀況代理確認處理 Process Limbo,指出該程序是否有效。收到例外狀況時,檢查程序是否已啟用 Process Limbo。如果是的話,系統會將例外狀況處理傳送給它。這就是由 FIDL 服務公開的 Process Limbo。