| RFC-0281:架構例外狀況和工作偵錯工具例外狀況管道 | |
|---|---|
| 狀態 | 已接受 |
| 區域 |
|
| 說明 | 建議更新 Job Debugger 例外狀況管道,以接收架構和政策例外狀況類型,同時繼續允許許多用戶端 |
| 問題 | |
| Gerrit 變更 | |
| 作者 | |
| 審查人員 | |
| 提交日期 (年-月-日) | 2026-04-21 |
| 審查日期 (年-月-日) | 2026-04-21 |
問題陳述
各種開發人員工具需要存取 Zircon 提供的例外狀況通道,才能監控作業、程序和執行緒 (統稱為「工作」) 的例外狀況,這些例外狀況可能會在執行期間發生。這類工具目前可能會聲明任何 Zircon Task 物件的例外狀況通道,以達成此目的。不過,這並非總是可行。舉例來說,監控同一個父項工作中的多個同層級程序時,工具必須聲明每個程序的例外狀況管道。如果大規模執行這項作業 (例如自動測試基礎架構,或監控功能齊全的 Starnix 容器),成本會非常高昂。相反地,工具會偏好使用 Job 的例外狀況管道,監控該工作下的所有程序。由於 Job 例外狀況管道具有專屬性,且 Job Debugger 例外狀況管道無法接收例外狀況,因此目前無法這麼做。
摘要
這項 RFC 建議變更 Zircon 的例外狀況傳送機制,將 Job Debugger 例外狀況管道納入傳送路徑,同時維持多個使用者空間實體繫結至相同 Job 的能力。這項異動可讓 Job Debugger 例外狀況管道與 Zircon 工作階層中一般化例外狀況傳送架構的設計保持一致,並讓工具能充分利用這項功能,確保可同時有效監控多個程序。
提振精神
例外狀況傳播
源自 Zircon 執行緒的例外狀況會按照精確的傳送順序,傳送至使用者空間進行處理。處理常式會透過 Task 控制代碼上的 zx_task_create_exception_channel 註冊,並有兩種形式:
- 一般 - 稱為「例外狀況管道」。
- 偵錯工具 - 稱為「偵錯工具例外狀況管道」。
向 Zircon 註冊時,處理常式必須透過 zx_task_create_exception_channel 選項,指定自己是「一般」還是「偵錯工具」例外狀況處理常式。這兩種管道在語意上沒有差異。收到例外狀況時,處理常式應先將 zx::exception 物件上的 ZX_PROP_EXCEPTION_STATE 屬性設為適當值,再將例外狀況的控制代碼釋出,將處理作業標示為「完成」。處理常式可能會將例外狀況標示為 ZX_EXCEPTION_STATE_HANDLED,這會終止走訪並繼續執行執行緒,ZX_EXCEPTION_STATE_TRY_NEXT 則會將例外狀況傳送至下一個處理常式,ZX_EXCEPTION_STATE_THREAD_EXIT 則會立即終止執行緒 (因此也會終止走訪)。
這兩種例外狀況管道的主要差異有兩點。第一個差異來自 Zircon 定義的走訪順序。系統會根據走訪順序,決定哪些例外狀況管道會看到例外狀況,以及看到例外狀況的順序。如為架構和政策例外狀況,則定義的走訪順序如下:
| 步驟 | 版本 | 傳送類型 |
|---|---|---|
| 1 | 程序偵錯工具 | First-chance |
| 2 | 執行緒 | First-chance |
| 3 | 程序 | First-chance |
| 4 | 程序偵錯工具 | Second-chance |
| 5 | 工作 | First-chance |
| 6 | 上層工作 | First-chance |
| 7 | 祖父母工作 | First-chance |
| ... | 在工作樹中向上移動,直到抵達根工作為止 |
產生例外狀況時,Zircon 會先將例外狀況傳送至程序偵錯工具例外狀況管道,然後等待處理常式關閉例外狀況管道或例外狀況控制代碼。如果例外狀況仍未處理,系統會將其傳遞至走訪順序中的下一個處理常式,而 Zircon 會再次等待控制代碼關閉,再移至下一個處理常式。每個例外狀況管道只能有一個處理常式。如果另一個處理常式嘗試在相同工作上呼叫 zx_task_create_exception_channel,系統會傳回 ZX_ERR_ALREADY_BOUND,且不會收到任何例外狀況。
第二個差異是傳送至各個管道的例外狀況類型。一般來說,Zircon 定義了兩種類型的例外狀況:
- 架構 - 例如區隔錯誤、頁面錯誤或未定義的指令。
- 合成 - 例如違反政策,或是各種開始和停止通知。
為方便說明,本文的分類方式稍有不同:
- 重大例外狀況 - 所有架構例外狀況和政策違規事項。如果例外狀況處理常式未處理這些例外狀況,保證程序會終止。
- 非致命例外狀況 - 除了政策違規事項以外的所有合成例外狀況。 這些例外狀況只會傳送至「偵錯工具」版本的例外狀況管道,如果未處理,程序不會終止。
這表示非致命例外狀況的例外狀況傳播走訪順序有顯著差異:
| 步驟 | 版本 | 傳送類型 |
|---|---|---|
| 1 | 程序偵錯工具 | First-chance |
| 2 | 工作偵錯工具 | First-chance |
| 3 | 程序偵錯工具 | Second-chance |
| 4 | 工作偵錯工具 | Second-chance |
傳送至 Job Debugger 例外狀況管道後,系統會終止走訪,且不會考慮其他例外狀況管道。從技術上來說,這些合成的非致命例外狀況支援第二次機會例外狀況,但實際上並未使用。
從嚴格篩選模式傳播例外狀況
在受限模式下運作的執行緒 (請參閱 RFC-0261),例外狀況傳播方式有所不同。zx_restricted_enter 的呼叫端會做為執行受限模式時發生例外狀況的執行緒內處理常式。這個處理常式會以邏輯方式插入上表,如下所示:
| 步驟 | 版本 | 傳送類型 |
|---|---|---|
| 1 | 程序偵錯工具 | First-chance |
| 2 | 討論串內 | First-chance |
| 3 | 執行緒 | First-chance |
| 4 | 程序 | First-chance |
| 5 | 程序偵錯工具 | Second-chance |
| 6 | 工作 | First-chance |
| 7 | 上層工作 | First-chance |
| 8 | 祖父母工作 | First-chance |
| ... | 在工作樹中向上移動,直到抵達根工作為止 |
不過,這種「執行緒內」處理方式的缺點是,例外狀況無法再透過典型的 Zircon 例外狀況管道進一步傳播。換句話說,從 Zircon 的角度來看,傳送至執行緒內處理常式的任何例外狀況,一律視為已處理。
因此,當架構或政策例外狀況源自受限模式時,實際的例外狀況傳送資料表如下所示:
| 步驟 | 版本 | 傳送類型 |
|---|---|---|
| 1 | 程序偵錯工具 | First-chance |
| 2 | 討論串內 | First-chance |
| 3 | 不適用 | 不適用 |
換句話說,當嚴格模式發生例外狀況時,執行緒內處理常式可視為一律會將例外狀況標示為已處理的例外狀況處理常式。也就是說,一般例外狀況傳播清單中的其他實體不會看到例外狀況。這也表示,雖然程序偵錯工具處理常式仍可在執行緒內處理常式之前接收例外狀況,但之後會失去註冊「第二次機會」例外狀況處理的能力。這是可接受的取捨,因為程序偵錯工具仍有機會在執行緒內處理常式看到並處理例外狀況之前,檢查及處理例外狀況。
注意:上述情況僅限於執行緒以受限模式執行時。如果該執行緒因任何原因 (例如處理系統呼叫) 在正常模式下運作,並在正常模式下引發例外狀況,系統會將其視為任何其他完全沒有受限狀態的 Zircon 執行緒。
非致命例外狀況類型不會傳送至執行緒內例外狀況處理常式,因此會保留與「例外狀況傳播」所述相同的傳送順序。
第二次機會例外狀況處理
處理例外狀況時,透過「程序偵錯工具」例外狀況管道註冊的例外狀況處理常式可能會將 ZX_PROP_EXCEPTION_STRATEGY 屬性設為 ZX_EXCEPTION_STRATEGY_SECOND_CHANCE,以便稍後有機會再次處理同一例外狀況 (如果「程序偵錯工具」取得第一次機會後,其他處理常式仍未處理該例外狀況)。如上所述,處理常式應注意,如果例外狀況來自嚴格模式下的執行緒,可能不會發生這種情況。如果例外狀況源自於受限模式,在例外狀況中設定這項屬性時,Zircon 不會傳回錯誤。
Job Exception Channel Contention
目前的 Zircon 例外狀況機制規定,Job Exception 管道只能由單一實體聲明。如果多個系統元件有正當理由需要觀察工作層級的例外狀況,這就會造成問題。舉例來說,偵錯工具可能需要攔截工作內一組程序的軟體中斷點例外狀況,而當機診斷服務則需要觀察未處理的例外狀況,以進行診斷和回報;此外,工作的部分子程序需要開啟工作例外狀況管道,以處理父項工作內其他程序的錯誤。這三種情況都是在特定程序的父項工作中建立例外狀況管道的合理用途,但只有其中一個實體可以聲明。
目前,元件可能會使用元件資訊清單中的 job_with_available_exception_channel 標記建構,但這只適用於該元件工作中的程序,偵錯和當機報告工具無法假設會有工作階層,因此在程序父項上方的某些工作中,會有可用的例外狀況管道。
Job Debugger Exception Channel
在 RFC-0178 中,工作偵錯工具例外狀況管道的用途已擴大,允許在單一工作下註冊多個 (ZX_EXCEPTION_CHANNEL_JOB_MAX_COUNT) 例外狀況管道,前提是這是「僅供通知」的管道。換句話說,它不會收到架構例外狀況,只會收到「程序啟動」事件。
目前,Job Debugger 例外狀況管道在例外狀況傳送管道中扮演的角色很奇怪。這是例外狀況管道的第二個差異。Process Debugger 例外狀況管道與 Job Debugger 例外狀況管道類似,但傳送至該管道的例外狀況類型有所不同:
| 例外狀況類型 | 工作例外狀況管道 | Job Debugger 例外狀況管道 | 處理例外狀況管道 | 處理偵錯工具例外狀況管道 |
|---|---|---|---|---|
| 架構和政策例外狀況 | ✅ | ❌ | ✅ | ✅ |
| 「子項」起始事件 | ❌ | ✅ (程序) | ❌ | ✅ (Threads) |
| 「子項」結束事件 | ❌ | ⚠️ (僅限 Signal) | ❌ | ✅ (Threads) |
目前 Job Debugger 例外狀況管道只會接收「程序啟動」和「程序結束」事件,前者屬於 zx::exception 類型,後者則屬於 zx::signal 類型。架構和政策例外狀況不會傳送至 Job Debugger 例外狀況管道。
傳送「子項」開始和結束事件
Zircon 定義的工作樹狀結構相當明確:工作有子項,子項可能包含零或多個工作,以及零或多個程序。程序也有子項,由一或多個執行緒組成。執行中系統中的其他實體可區分不同工作,因此可能會聲明工作除錯工具例外狀況管道,以接收「程序啟動」事件,也可能會聲明任何程序的除錯工具例外狀況管道,以接收「執行緒啟動」和「執行緒結束」事件。Zircon 目前尚未提供 Zircon 作業的同等概念通知,且超出本 RFC 的範圍。
所有這些事件的傳送方式都相同:zx::exception 控制代碼會傳送至父項的偵錯工具例外狀況管道。這可讓繫結至偵錯工具例外狀況管道的用戶端執行任意動作,同時保證「子項」實體會暫停,例如偵錯工具可設定程序物件控制代碼上的 ZX_PROP_PROCESS_BREAK_ON_LOAD,或在執行緒毀損前,為執行緒的毀損進行必要的會計作業。
目前的程序結束事件很特別:這類事件會以信號 ZX_PROCESS_TERMINATED 形式傳送,而不是以 zx::exception 形式傳送至 Job Debugger 例外狀況管道。這種差異不只是語意上的不同,因為程序終止是做為 Zircon 信號傳送,而非例外狀況,因此完全是非同步。在傳送訊號時,接聽這個訊號的實體不會獲得任何保證,因為程序物件可能已遭 Zircon 毀損。請與傳送至 Process Debugger 例外狀況管道的 ThreadExiting 事件比較,後者可從 Zircon 提供額外保證,確保執行緒的狀態仍可存取。因此,如要讓監控實體在程式結束時正確停止程序,以便檢查最終程式狀態 (主要是控制代碼表和記憶體) 和執行緒狀態,就必須正確計算所有執行緒的啟動和結束事件,並明確注意到最後一個執行緒結束時,傳送 zx::exception 通知給實體,讓實體盡可能保留通知,而非只是信號。
請注意,雖然 Zircon 保證可防範一般執行緒終止機制,但無法保證其他程序在這段期間可能對執行緒或其父項程序執行的動作,例如發出 zx_task_kill 系統呼叫,這會立即終止程序及其所有執行緒,無論程序偵錯工具例外狀況管道狀態為何。換句話說,處理特定執行緒的例外狀況,無法防止其程序透過 zx_task_kill 立即終止。
利害關係人
協助人員:
- abarth@google.com
審查者:
- mcgrathr@google.com
- maniscalco@google.com
- jamesr@google.com
已諮詢:
- abarth@google.com
- cpu@google.com
- lindkvist@google.com
公共平台:
這份 RFC 的早期版本已在 fuchsia-zircon-discuss 郵寄清單中發布,並由 Debug 和 Testing Architecture 團隊討論。
需求條件
設計必須確保架構和政策例外狀況 (如「Zircon Exception Types」所述) 會傳送至 Job Debugger 例外狀況管道,且 Job Debugger 例外狀況管道會繼續允許多個註冊者 (如 RFC-0178 所述)。
設計
將架構和政策例外狀況傳送至 Job Debugger 頻道
我們建議擴充現有的 Job Debugger Exception 管道,除了目前收到的 ZX_EXCP_PROCESS_STARTING 事件外,也能接收架構和政策例外狀況。
例外狀況管道步行順序
這項變更需要修改 Zircon 傳播例外狀況的順序。根據例外狀況管道類型說明文件,架構和政策例外狀況的新遞送順序如下:
| 步驟 | 版本 | 傳送類型 |
|---|---|---|
| 1 | 程序偵錯工具 | First-chance |
| 2 | 工作偵錯工具 | 第一次機會,N 次 |
| 3 | 執行緒 | First-chance |
| 4 | 程序 | First-chance |
| 5 | 程序偵錯工具 | Second-chance |
| 6 | 工作偵錯工具 | 第二次機會,N 次 |
| 7 | 工作 | First-chance |
| 8 | 祖系工作偵錯工具 | 第一次機會,N 次 |
| 9 | 祖系工作 | First-chance |
| ... | 在工作樹狀結構中,繼續使用 Job Debugger 和 Job Exception 管道,直到抵達根工作為止 |
主要異動是 Job Debugger 例外狀況管道現在會接收這些例外狀況,最多 N 次,其中 N 等於 ZX_EXCEPTION_CHANNEL_JOB_MAX_COUNT。在逐步執行中,程序偵錯工具例外狀況管道後方緊接著就是程序父項工作的 Job Debugger 例外狀況管道,這表示附加至例外執行緒最近父項工作的用戶端,將有第一次和第二次機會處理例外狀況,就像程序偵錯工具例外狀況管道一樣。
接著,系統會繼續向上追蹤工作樹狀結構,從 Job Debugger 到 Job 例外狀況管道,一路追蹤到根工作。這項功能可讓偵錯工具實作自由選擇要在工作階層中的哪個位置附加自身,以因應各種用途。
如果附加至 Job Debugger 例外狀況管道,只有父項工作有機會收到第二次例外狀況,父項工作上方的祖先工作只會有第一次機會檢查例外狀況。
交付架構和政策例外狀況
根據 Zircon 例外狀況類型,Job Debugger 例外狀況管道是唯一不會接收架構例外狀況的例外狀況管道,因此顯得不必要地獨特。這項做法的原因可追溯至 RFC-0178 之前,但動機簡述如下:
不過,這裡的「debug 工作」很特別,因為這是僅限通知的管道,唯一可接收的例外狀況類型是
ZX_EXCP_PROCESS_STARTING,且會忽略ZX_PROP_EXCEPTION_STATE。因此,您可以在一個工作中允許多個偵錯例外狀況通道,而不必擔心不一致的問題。
此處的「不一致」是指架構例外狀況傳送至這類例外狀況管道的順序,這類管道可能有多個已註冊的用戶端。由於適用於所有其他例外狀況管道的獨占原則不適用於 Job Debugger 例外狀況管道,因此在同一層級中,哪個例外狀況管道會先看到例外狀況事件,並沒有明確的順序。
這項 RFC 提案指出這並非問題。針對特定工作,例外狀況傳送至 Job Debugger 處理常式的順序是由 Zircon 定義的實作項目,處理常式有責任瞭解同一層級的其他處理常式可能會先傳送例外狀況,並將例外狀況標示為已處理。同樣地,處理常式也必須知道,他們已收到後續實體的例外狀況,但該實體附加至相同工作的 Job Debugger 例外狀況管道。
這表示,如果處理常式預期在工作樹狀結構的特定層級擁有例外狀況的專屬存取權,這個機制就無法發揮效用。這類處理常式應繼續使用 Job 的例外狀況管道,並處理該管道已由其他處理常式聲明的情況,例如 zx_task_create_exception_channel 傳回 ZX_ERR_ALREADY_BOUND 時。
開啟嚴格篩選模式
以受限模式執行的執行緒需要特別謹慎處理。在受限模式下執行時觸發例外狀況的執行緒會留在受限模式,而例外狀況會傳送至 RFC-0261 中指定的 Process Debugger 例外狀況管道。只有在「程序偵錯工具」管道完成例外狀況的業務,且例外狀況未經處理後,執行緒才會退出受限模式,進入正常模式,透過受限模式的特殊執行緒內例外狀況處理常式進行處理。其他例外狀況管道不會發生例外狀況,且如「受限模式的例外狀況傳播」一文所述,不會有第二次例外狀況。
這項 RFC 並未提議變更受限模式例外狀況的處理方式。後續的 RFC 會詳細說明這個程序,以及程序與 Job Debugger 例外狀況管道的互動方式。
處理邏輯
系統會根據 Job Debugger 管道的註冊順序,依先到先得原則傳送例外狀況。Job Debugger 通道中第一個將例外狀況標示為已處理的用戶端 (也就是在例外狀況控制代碼上設定 ZX_EXCEPTION_STATE_HANDLED 屬性),會終止該工作在 Job Debugger 例外狀況通道清單中的逐步執行,並防止例外狀況進一步向上傳播至工作樹狀結構。
連線至 Job Debugger 管道的用戶端必須注意,其他已註冊的用戶端可能會先處理例外狀況。這會編碼至 Job Debugger 管道的合約中,因此不適合用來接收一般系統當機處理常式的例外狀況,因為這類常式預期會在正式環境中運作。
| 例外狀況類型 | 工作例外狀況管道 | Job Debugger 例外狀況管道 | 處理例外狀況管道 | 處理偵錯工具例外狀況管道 |
|---|---|---|---|---|
| 架構和政策例外狀況 | ✅ | ✅ (N 次) | ✅ | ✅ |
| 「子項」起始事件 | ❌ | ✅ (程序) | ❌ | ✅ (Threads) |
| 「子項」結束事件 | ❌ | ⚠️ (僅限程序和信號) | ❌ | ✅ (Threads) |
ProcessExiting 事件
ProcessExiting 例外狀況事件的建立和傳送作業,將留待日後的 RFC。ZX_PROCESS_TERMINATED 信號的傳送方式維持不變。
實作
這項提案不會變更 zx_task_create_exception_channel 的系統呼叫 API 和 ABI。根據 RFC-0178,zx_task_create_exception_channel 會繼續允許建立最多 ZX_EXCEPTION_CHANNEL_JOB_MAX_COUNT 個頻道,而不是在第一個頻道建立後傳回 ZX_ERR_ALREADY_BOUND。
使用 ZX_EXCEPTION_CHANNEL_DEBUGGER 選項的zx_task_create_exception_channel使用者必須瞭解,他們現在也可能會收到工作子程序的架構和政策例外狀況。這個管道目前只有少數使用者,因此可以輕鬆地隨著 Zircon 的變更進行更新。如要進一步瞭解這些使用者,請參閱下文。
效能
如果多個實體都聲明 Job Debugger 例外狀況管道,例外狀況傳送效能就會受到阻礙,因為例外狀況必須先傳送至 (可能有多個) 其他用戶端,才會傳送至根層級工作,而執行緒和/或程序會在該處終止。儘管如此,任何單一用戶端仍可能無限期保留例外狀況,如果例外狀況要傳送至多個用戶端,情況會更糟。
人體工學
使用 zx_task_create_exception_channel 的人體工學和從 Zircon 到使用者空間的例外狀況傳遞方式維持不變。
回溯相容性
系統 ABI 的影響
這項變更會修改例外狀況傳遞的系統 ABI。先前,您無法透過註冊 Job Debugger 例外狀況管道,取得架構或政策例外狀況。這項異動生效後,註冊者不僅需要留意這些例外狀況的傳遞情形,也必須瞭解他們可能不是這個工作樹狀結構層級中,第一個收到例外狀況的接收者。
截至本文撰寫時,Job Debugger 例外狀況管道只有兩位值得注意的非測試使用者:
這兩個實體都位於 fuchsia.git 來源樹狀結構中,且可輕鬆更新,不必導入明確的版本控管。
視特定用途的偵錯工具設定而定,系統可能會先收集有關執行緒的資訊,再沿著鏈結轉送例外狀況,或在偵錯工具使用者指示下,將例外狀況標示為已處理。在各種設定和設定中,偵錯工具可能會顯示其他用途,這些用途會留給偵錯工具實作,以便根據這項 ABI 變更適當處理。
以分析器來說,我們只對程序啟動通知感興趣,因此從這個管道收到的任何其他 zx::exception 物件都可以立即關閉並忽略。
對 elf_runner 的影響
elf_runner 目前會產生並聲明每個 ELF 元件的 Job 例外狀況管道,以便為 Fuchsia 的當機服務 crashsvc 提供 CrashIntrospect 通訊協定。
這項功能可改善,讓 elf_runner 現在只需要在 RootJob 上取得單一工作偵錯工具例外狀況管道,保證在例外狀況傳送至 RootJob 的例外狀況管道前收到例外狀況,確保 crashsvc 仍可存取當機元件的元件資訊,同時要求 elf_runner 聲明遠少於資源。
由於 elf_runner 目前未使用 Job Debugger 例外狀況管道,因此在初始實作中不會變更,所以不需要立即進行這些變更。
安全性考量
RFC-0178 中已說明允許的 Job Debugger 通道上限,且本提案未修改此上限,因此可防止針對核心的任何 DOS 向量。
一般來說,工程和生產環境都會提供例外狀況資訊,供聲明特定 Zircon 工作例外狀況管道的程式碼使用,因此這項提案不會公開其他敏感資訊。不過,這會增加可檢查例外狀況資訊的實體數量上限。
隱私權注意事項
這項提案不會對隱私權造成任何影響。
測試
新的測試案例將新增至 //zircon/system/utest/debugger,涵蓋這項功能。
說明文件
我們將更新「例外狀況類型」說明文件,以反映例外狀況管道的新排序方式,這些管道將接收架構例外狀況,以及關於如何處理受限模式執行緒例外狀況的新附註。
缺點、替代方案和未知事項
我們也考慮了另外兩種主要方法,做為提議解決方案的替代方案:
FIDL 例外狀況伺服器
這種做法會將例外狀況處理作業集中在元件 (例如 elf_runner) 內,然後向多個感興趣的用戶端提供新的 FIDL 通訊協定。
- 優點:可全面控管例外狀況排序和政策 (例如區分單一「處理常式」和多個「僅通知」監聽器)。
- 缺點:會為使用者空間元件 (
elf_runner) 帶來複雜性、需要反覆傳遞例外狀況處理程序 (因為無法重複),以及將篩選負擔轉移給用戶端。
Zircon 修改工作例外狀況管道
這個方法會修改 Zircon,允許多個元件在工作中成功呼叫 zx_task_create_exception_channel,但需要透過傳遞至 Zircon 系統呼叫的新選項,表示「處理常式」與「僅通知」的興趣。
- 優點:運用 Zircon 現有的例外狀況處理權限和流程。允許 Zircon 同時將例外狀況傳送至所有「僅通知」管道。系統會要求用戶端指定特定工作,藉此自動進行篩選。
- 缺點:需要對 Zircon 核心 API 進行重大變更,導入新選項來區分「處理常式」和「僅通知」用戶端。
建議使用「Job Debugger Channel」解決方案,因為這項解決方案會擴充現有的多重監聽器機制 (Job Debugger 管道),以處理新的例外狀況類型,盡量減少 Job Debugger 例外狀況管道與 Process Debugger 例外狀況管道之間的差異,並盡量減少 Zircon 中的新 API 介面區域。