RFC-0178:每項工作有多個偵錯例外狀況管道

RFC-0178:每個工作有多個偵錯例外狀況管道
狀態已接受
區域
  • 核心
說明

Zircon 允許工作有多個偵錯例外狀況管道。

問題
  • 97848
變更
  • 688614
作者
審查人員
提交日期 (年/月)2022-06-08
審查日期 (年/月)2022-07-12

摘要

這個 RFC 建議變更 zx_task_create_exception_channel,允許在單一工作上建立最多 32 個偵錯例外狀況管道。

提振精神

Fuchsia 上的偵錯工具需要針對工作建立偵錯例外狀況管道,以便監控程序開始,以便擷取所需的程序並立即附加至作業。偵錯例外狀況管道通常是在系統的根工作中建立,因此偵錯工具可以監控所有程序。

程序啟動時,核心會逐步引導工作階層尋找要通知的偵錯工作例外狀況管道。這項步行作業會從內含工作的新程序開始,往上階層,直到找到偵錯工作例外狀況管道或達到根工作為止。

不過,今天的實作方式有以下兩個缺點。

  • 特定工作最多只能有一個偵錯例外狀況管道,這表示最多只能有一個偵錯工具可監控工作階層的任何指定子樹狀結構。
  • 系統只會通知第一個找到的偵錯例外狀況管道,也就是說,子項工作偵錯工具會阻止父項工作的偵錯工具開始觀察程序。

相關人員

講師:cpu@google.com

審查人員:brettw@google.com、maniscalco@google.com

顧問:johngro@google.com

社交化:概念在 Fuchsia 的核心演進工作小組中討論。

設計

我們建議 Zircon 允許在同一項工作中使用多個偵錯工作例外狀況管道。

Zircon 中有 5 種例外狀況管道:偵錯工作、工作、偵錯程序、程序和執行緒。每個物件最多可以在對應的物件上建立一次。設定這項限制後,即可避免發生難以模擬的情況,例如有多個例外狀況處理常式為 ZX_PROP_EXCEPTION_STATE 設定不同的值。

不過,由於「偵錯工作」是通知專用管道,因此這裡的「偵錯工作」並不相同:它能接收的唯一例外狀況類型是 ZX_EXCP_PROCESS_STARTING,其中忽略 ZX_PROP_EXCEPTION_STATE。因此,您可以在單一工作中允許多個偵錯例外狀況管道,不必擔心不一致的問題。

在單一工作上建立多個偵錯工作例外狀況管道時,系統會依序傳送至所有管道傳送 ZX_EXCP_PROCESS_STARTING 事件,讓多個事件監聽器檢查此程序。特定程序只能附加一個偵錯工具的限制不會改變,因為「偵錯程序」例外狀況管道仍歸所有,且除了第一個偵錯工具以外的所有偵錯工具都會獲得 ZX_ERR_ALREADY_BOUND

此外,我們也建議修改 ZX_EXCP_PROCESS_STARTING 事件的事件傳播,讓一個事件全部傳播到根層級,即使子項工作上有建立的例外狀況管道也一樣。工作階層中較低層級的工作例外狀況管道,會在較高層級的工作之前收到通知。在任何層級,先前建立的管道都會在後續建立管道之前收到通知。只有在所有例外狀況管道都收到通知,且例外狀況物件關閉時,程序才會繼續執行。

請注意,任何例外狀況訊息接收器都可以單純不要關閉例外狀況物件的控制代碼,來無限期保留程序啟動。但這類程序無法直接停止程序啟動。

實作

系統呼叫不會變更 API 或 ABI。將變更 zx_task_create_exception_channel 的現有行為,以便建立最多 N 個管道,而不是在第一個管道之後傳回 ZX_ERR_ALREADY_BOUND

效能

這麼做可能會降低效能,因為事件監聽器越多,系統可能會封鎖程序啟動。不過,偵錯例外狀況管道不應用於實際工作環境,或由長時間執行的程式保留。這項功能僅適用於偵錯工具或類似的偵錯工具,因此應盡量減少影響。

一般來說,偵錯工具應在執行必要的設定後立即關閉例外狀況控制代碼。

安全性考量

為避免核心受到 DoS 攻擊,我們應限制在單一工作中建立的偵錯工作例外狀況管道數量上限。這項限制必須夠大,以便允許執行任意數量的偵錯工具,例如 32。

測試

將新增測試案例至 //zircon/system/utest/debugger,以涵蓋這項功能。

說明文件

說明例外狀況處理zx_task_create_exception_channel 的文件會更新,以反映這項變更。

缺點、替代方案和未知

替代做法:在根工作上啟動使用者空間委派程序

這個方法可避免核心變更。使用者空間委派將會保留根工作偵錯管道,並提供 FIDL 介面供偵錯工具訂閱以展開程序。委派項目可以是元件管理員本身、目前負責執行 fuchsia.kernel.RootJob 的元件管理員,也可以是獨立程式。

通訊協定看起來會像

@discoverable
protocol RootJob {
    /// Hanging get pattern
    GetProcessStartingEvent() -> (resource struct {
        process zx.handle:PROCESS;
        continue zx.handle:EVENTPAIR;  // dropping this eventpair will propagate
                                       // the event to the next listener.
    }) error zx.status;
};

這個方法的問題

  • 這僅適用於根工作。偵錯工具需要根工作和非根工作有兩個邏輯。
  • 在子工作中建立的例外狀況管道可阻止事件傳播到根層級。
  • 導入 FIDL API 時,其功能與系統呼叫類似,會令人困惑。

替代做法:debug_agent 支援多個用戶端

我們也可以讓 debug_agent 支援多個用戶端來解決今日的問題,例如, debug_agent 會變成單例模式。

問題是

  • 日後需要投入更多心力。
  • debug_agent 將成為 Fuchsia 的指定偵錯工具。其他偵錯工具則必須與 debug_agent 通訊,以便公開大型且不穩定的介面。