即時偵錯

總覽

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。