Lab4: System Call - signal

依據 IMPLEMENTATION OF SIGNAL HANDLING 的指引實作 signal

一般 signal 流程

  1. process 註冊 signal handler
  2. 對該 process 發出 signal, eg. kill()
  3. 輪到該 process 時執行 signal

Signal Mechanism

signal 機制如下

  1. signal registration: 更新 process 的 signal handler
  2. signal generation: kernel 更新接收 signal 的 process 的資料結構,來紀錄被發送的 signal
  3. signal delivery: kernel 強制 process 做出回應,也就是呼叫 signal handler

Pending & Blocked Bit-vector

process 各有一個 pending bit-vector 和 blocked bit-vector,用來維護不同 signal

  • pending bit-vector: process 已經接收到 signal,但還沒有做出回應
  • blocked bit-vector: 不允許 process 對 signal 做出回應。
    • 如果 signal 被 unblocked,process 會立刻做出回應。
    • signal handler 執行當下,該種 signal 會被 blocked,防止 signal handler interrupt 自身

可能出現一種 signal 有可能同時是 pending 又是 blocked 的情況。

此外,多個同種的 signal 觸發,process 只會看到其中一個。

Implementation

實作前回答投影片第 7 頁的以下問題

  1. kernel 要如何提供 signal handling 給 user process
    • 提供 signal() 註冊特定 signal 的 signal handler
  2. signal handler 何時執行
    • reschedule 之後要切換到 user space 前
  3. process 要如何處理多個 pending signals
    • 只會實作一種 SIGNAL: SIGKILL,因此沒有這問題

Process Signal Data Structures

每個 process 都會有這樣的資料結構

  • pending bit-vectors
  • pending signal linked list
  • array of signal action
    • 用來紀錄如何 handle signal
      • default action: ignore, terminate…
      • user space handler

SIGACTION(2) 提及 SIGKILL 是不被允許給 user process overwrite,且目前實作的只會有這麼一種 signal,所以就不提供 signal() 供使用者自訂 signal handler。

Some predefined signals (such as SIGKILL) have locked behavior that is handled by the system and cannot be overridden by such system calls.

此外 wiki - sigaction 也提及 sigaction() 被用來取代 signal() ,原因在於 signal() 執行 signal handler 後,會再掛載 signal handler 回去,在 signal handler 執行中、尚未掛載 handler 前如果收到同種類的 signal,會有不可信賴的情況發生。

Delivering Signals

不用考慮 user signal handler 情況下簡單許多,我們只需要實作kill() syscall,在對應的 process strcuture 設置 bit-vector。並在 reschedule 後、切換到該 process 前檢查 bit-vector 執行對應的 signal handler。

Demo

第 3 次 kill 時目標 process 已經不存在所以失敗,於是離開交給 zombie reaper 釋放資源