作業系統除錯 (Operating-System Debugging)
本系列文章內容參考自經典教材 Operating System Concepts, 10th Edition (Silberschatz, Galvin, Gagne)。本文對應章節:Section 2.10 Operating-System Debugging。
廣義而言,除錯(Debugging) 是在系統中尋找並修復錯誤的活動,涵蓋硬體與軟體兩個層面。值得注意的是,效能問題也被視為一種 bug,因此除錯也包含效能調校(Performance Tuning),即透過消除處理瓶頸來提升整體效能。本章將探討 OS 如何支援三種核心除錯活動:失敗分析、效能監控,以及動態核心追蹤。
2.10.1 失敗分析 (Failure Analysis)
Process 層級的失敗:Core Dump
當一個 Process 發生錯誤而失敗時,OS 通常會做兩件事:
- 寫入 log 檔案:將錯誤資訊記錄到 log file,用於通知系統管理員或使用者問題的發生
- 產生 core dump:拍下 Process 在失敗當下的完整記憶體快照(a capture of the memory of the process),儲存到檔案中供後續分析
「core」這個詞來自早期電腦使用磁蕊記憶體(Magnetic Core Memory) 的時代,當時記憶體就被稱為「core」。雖然現代早已改用 DRAM,這個名稱卻沿用至今。
core dump 檔案可以用偵錯工具(Debugger) 開啟。Debugger 允許程式設計師探索 Process 在失敗當下的程式碼與記憶體狀態,例如查看哪個變數持有非法值、哪個指標已超出有效範圍,是定位 bug 根本原因的重要工具。
Kernel 層級的失敗:Crash Dump
除錯 user-level Process 的程式碼本身已是一大挑戰,而除錯 OS kernel 則更為複雜,原因有三:
- 規模與複雜度:kernel 程式碼量龐大、子系統高度交織
- 直接控制硬體:kernel 中的錯誤可能直接導致整台機器失去回應
- 缺乏 user-level 工具:在 user-level 可用的偵錯工具在 kernel 層級幾乎派不上用場
kernel 中的失敗稱為 crash(崩潰)。當 crash 發生時,OS 同樣會將錯誤資訊記錄到 log 檔案,並將記憶體狀態儲存到 crash dump。
然而,有一個關鍵問題:如果 crash 發生在 file-system 的程式碼裡,kernel 還能把 crash dump 寫到檔案系統嗎?
答案是不行。一旦 file-system 的程式碼本身已發生嚴重錯誤,再嘗試透過它寫入檔案,不僅可能寫入失敗,還可能造成資料損毀。
因此,kernel crash 的標準做法是:
- 寫入專用磁碟區域:crash 發生時,OS 將整個記憶體內容(或至少是 kernel 擁有的部分)直接寫入磁碟上一個不屬於任何檔案系統的保留區域(reserved disk section),完全繞過 file system。
- 系統重新啟動後再整理:系統重啟後,一個獨立的 process 讀取該保留區的原始資料,將其整理成標準的 crash dump 檔案,寫入正常的 file system 供後續分析。
2.10.2 效能 監控與調校 (Performance Monitoring and Tuning)
效能調校(Performance Tuning)的目標是消除處理瓶頸(Bottleneck),而要找出瓶頸在哪裡,必須先能夠量測系統行為。OS 因此需要提供一套機制來收集並展示系統的各種量測數據。
效能監控工具主要分成兩種技術路線:計數器(Counters) 與追蹤(Tracing),兩者收集資訊的方式根本不同。
計數器工具 (Counter-Based Tools)
OS 透過一系列計數器持續追蹤系統活動,例如:已執行的 system call 次數、網路裝置的傳輸次數、磁碟的讀寫次數等。計數器工具的特性是隨時可查、開銷固定低廉,適合快速掌握系統整體概況。
Linux 上常用的計數器工具分成兩類:
Process 層級(Per-Process):
| 工具 | 說明 |
|---|---|
ps | 回報單一 Process 或一組 Process 的資訊(狀態、CPU 使用、記憶體等) |
top | 即時顯示目前所有 Process 的動態統計數據,按 CPU 使用率排序 |