即時偵錯

總覽

即時偵錯 (JITD) 是 Fuchsia 暫停異常終止程序的方式,方便相關人員稍後偵錯/處理。這項功能可實現有趣的流程,例如在偵錯工具未附加/執行時,將 zxdb 附加至夜間當機的程式。

方法是將程序儲存在例外狀況中,並放在名為「程序暫緩區」的特殊位置。這個位置會暫停這些程序,直到其他代理程式前來釋放程序為止。

如要進一步瞭解運作方式,請參閱「實作」。

如何啟用

Process Limbo 的其中一項優點是,您可以在野外捕捉當機的程序,不必事先執行偵錯工具。如果偵錯工具無法執行 (例如驅動程式庫啟動時),這項功能就特別實用。在這種情況下,如果「程序暫緩」功能處於啟用狀態,就能提供寶貴的偵錯資訊來源。

啟用「處理程序暫緩」的方式有兩種:

手動啟用

使用者可以透過 ffx 外掛程式查詢暫時狀態:

$ 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.

在啟動時啟用

注意:這項功能目前無法正常運作。如需使用,請與 //src/developer/forensics/OWNERS 的人員聯絡。

手動啟用功能的前提是,您必須有方法向系統傳送指令。不過,有些開發環境會提早執行軟體,讓使用者可以互動 (或執行偵錯工具)。驅動程式就是一個很好的例子。在這些情況下,從一開始就啟用「Process Limbo」可讓您在驅動程式啟動時,即時偵測到驅動程式庫當機情形,這通常是最難偵錯的部分。

如要執行這項操作,必須在建構中設定以下設定:

fx set <YOUR CONFIG> --with-base //src/developer/forensics:exceptions_enable_jitd_on_startup

或者,在建構引數的 base_package_labels 中新增這個標籤。您仍可使用 Process Limbo CLI 工具停用及操控後續的 Limbo。接著,您必須將更新推送至裝置,這項設定才會生效。

注意:驅動程式初始化程序相當複雜,如果凍結或當機,可能會導致系統處於未定義狀態並「停止運作」,因此使用這項功能時,里程數可能會有所不同,尤其是非常早期的驅動程式。

使用方式

zxdb

zxdb 是 JITD 的主要使用者,能夠附加至等待中的程序。啟動 zxdb 時,系統會自動附加至處於暫停狀態的程序:

$ 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
  24 «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,進一步瞭解如何使用。

Process Limbo FIDL Service

Process Limbo 會以 FIDL 服務的形式呈現,Process Limbo CLI 工具和 zxdb 都會使用這項服務。FIDL 通訊協定定義於 //sdk/fidl/fuchsia.exception/process_limbo.fidl

實作

Crash Service

程序擲回例外狀況時,Zircon 會產生相關聯的 exception handle。然後,系統會查看任何相關聯的例外狀況管道中,是否有任何監聽器可能對處理該例外狀況感興趣。zxdb 等偵錯工具就是透過這種方式,從執行中的程序取得例外狀況。詳情請參閱例外狀況處理方式

但如果沒有例外狀況處理常式 (因為沒有任何處理常式,或所有處理常式都決定要傳遞處理作業),根工作就會有專屬的處理常式,稱為 crashsvc。一旦例外狀況傳送至當機服務,即表示該例外狀況「當機」,且沒有任何程式能夠處理。接著,當機服務會將當機堆疊追蹤記錄傾印至記錄檔,並將例外狀況傳遞至 Exception Broker

例外狀況代理程式

Exception Broker 負責根據實際系統設定,決定如何處理當機例外狀況。系統可能會決定建立小型傾印檔案並傾印當機報告、將例外狀況傳送至程序暫存區,或終止程序。

例外狀況中介服務會知道程序暫緩狀態,以及是否處於有效狀態。當接收到例外狀況時,系統會檢查是否已啟用「程序暫緩」功能。如果是,系統會將例外狀況控點傳遞給該函式。這與 FIDL 服務公開的 Process Limbo 相同。