Starnix 中的信號轉換

本頁說明 Starnix 如何將 Zircon 例外狀況和訊號轉換為 Linux 訊號,供未修改的 Linux 程式使用。

提振精神

Linux 程式會依賴訊號進行非同步通知 (例如 SIGALRMSIGCHLD) 和錯誤處理 (例如 SIGSEGVSIGCHLD)。由於 Starnix 會在 Zircon 程序中執行 Linux 程式,因此必須彌合 Zircon 的事件模型和 Linux 的訊號模型之間的差距。

如要進一步瞭解信號轉換背後的動機和 Starnix 設計理念,請參閱「As she is spoke」。

信號流程

Starnix 中的訊號生命週期可分為三個不同階段:

  1. 放送
  2. 處理中
  3. 執行

Starnix 訊號流程的三個階段:傳送、處理和執行

傳送方式

在 Starnix 中傳送信號時,需要將 Zircon 的例外狀況處理機制與 Linux 信號範例橋接。Starnix 會攔截事件,並確保事件以 Linux 信號的形式傳送至正確的目標工作。

放送可由多個不同來源觸發:

  • Zircon 例外狀況:最複雜的路徑涉及硬體故障。當以受限模式執行的 Linux 執行緒觸發 CPU 例外狀況 (例如區隔錯誤或除以零錯誤) 時,Zircon 會截取這項違規行為,並透過受限的結束代碼將其傳回 Starnix 核心。
  • 內部狀態轉換:Starnix 會持續監控執行環境。內部元件 (例如計時器子系統或程序管理服務) 通常會根據狀態變化自主觸發信號 (例如,計時器到期時觸發 SIGALRM,或子程序結束時觸發 SIGCHLD)。
  • 系統呼叫:工作可透過直接進行系統呼叫 (例如 kill(2)tgkill(2)),明確要求將信號傳送至其他程序或執行緒群組。

處理中

信號成功傳送並附加至工作待處理佇列後,核心必須判斷如何處理該信號。這項作業會在處理階段進行,Starnix 會評估工作已註冊的信號動作

工作會在執行階段使用 rt_sigaction(2) 定義這些動作。 視設定而定,Starnix 會執行下列三種不同路徑之一:

  • 忽略:安全捨棄信號,不會中斷執行緒的執行流程。
  • 預設動作:如果未定義任何自訂處理常式,Starnix 會針對該特定信號執行 Linux 預設解決方案。這可能表示無聲終止程序、產生核心傾印以進行偵錯、暫停執行或只是繼續執行。
  • 自訂處理常式:如果應用程式已註冊特定函式來處理信號,Starnix 必須準備執行緒的使用者空間堆疊,才能安全地中斷目前的工作負載,並將內容切換至自訂處理常式常式。

執行

需要自訂處理常式時,Starnix 會執行下列動作:

  1. 狀態保留:首先,系統會擷取並保留執行緒目前中斷的暫存器狀態,然後儲存至執行緒的使用者空間堆疊。
  2. Sigframe 建構:接著,系統會圍繞堆疊中儲存的狀態建構 sigframe 資料結構。這個影格會保留所有必要內容,以便稍後繼續執行執行緒。
  3. 重新導向:儲存備份後,Starnix 會修改執行緒的指令指標,將其重新導向至應用程式已註冊訊號處理常式函式的記憶體位址。
  4. 繼續:最後,Starnix 會將控制權交還給執行緒,在受限模式下繼續執行。處理常式內的執行緒會「喚醒」。

下列系統呼叫是工作用來設定及觸發上述信號流程的主要介面:

rt_sigaction(2)

工作會使用這個系統呼叫,為特定信號註冊自訂動作。Starnix 會在 Task 結構中維護這項對應關係,並在「處理」階段評估這項對應關係,判斷是否應忽略信號、以預設方式處理信號,或將信號傳送至使用者空間執行處理常式。

rt_sigreturn(2)

使用者空間訊號處理常式執行完畢後,會呼叫 rt_sigreturn。Starnix 會使用這項信號結束「執行」階段。這個函式會讀取先前推送到堆疊的 sigframe,還原執行緒的原始中斷狀態,並順暢地恢復正常運作。

kill(2)

這項系統呼叫可讓工作主動將信號傳送至其他程序。Starnix 會驗證必要權限,並在「傳送」階段中做為事件來源,將要求信號附加至目標程序的待處理信號佇列。