`strace` 是一個功能強大的 Linux 診斷、除錯和安全工具,用於追蹤程式執行的**系統呼叫 (System Calls)** 和接收到的訊號。
這是一個完整的 `strace` 教學,涵蓋了基本用法、常見參數和安全檢查。
---
## 🛠️ `strace` 教學:系統呼叫追蹤
### 核心觀念:什麼是系統呼叫?
當一個應用程式需要執行特權操作(例如讀寫檔案、連線網路、建立新程序或存取記憶體)時,它不能直接執行,而是必須透過一個特殊的機制向 **Linux 核心 (Kernel)** 請求服務。這個請求就是 **系統呼叫 (System Call)**。
`strace` 的作用就是攔截並顯示應用程式與核心之間的所有這些互動。
### 一、基本用法
#### 1. 執行並追蹤新程序
在程式名稱前加上 `strace`,它會執行該程式並顯示程式運行期間進行的所有系統呼叫。
**語法:**
```bash
strace <command> [arguments]
```
**範例:追蹤 `ls` 指令**
```bash
strace ls -l
```
* **輸出結果:** 您會看到數百行輸出,顯示 `ls` 嘗試打開設定檔 (`openat`), 讀取目錄內容 (`getdents64`), 寫入標準輸出 (`write`) 等等。
#### 2. 追蹤正在運行的程序
您可以使用 `-p` 參數將 `strace` 附加到一個已經在運行的程序 ID (PID) 上。
**語法:**
```bash
strace -p <PID>
```
**範例:追蹤 KMonad 的網路行為** (正如我們之前討論的)
1. 找到 KMonad 的 PID:`pgrep kmonad`
2. 追蹤該 PID:
```bash
strace -p 12345
```
### 二、常見且實用的參數
| 參數 | 說明 | 範例 |
| --- | --- | --- |
| **`-o <filename>`** | 將輸出結果寫入檔案,而不是顯示在終端機。 | `strace -o output.log ls` |
| **`-c`** | 僅顯示**系統呼叫摘要**:每個呼叫的次數、百分比和耗時。 | `strace -c ls` |
| **`-e trace=<set>`** | **過濾**要追蹤的系統呼叫類別。最常用於安全或性能分析。 | `strace -e file ls` |
| **`-e network`** | 專門過濾所有**網路相關**的呼叫 (`socket`, `connect`, `sendto`, `recvfrom` 等)。 | `strace -e network curl google.com` |
| **`-e file`** | 專門過濾所有**檔案 I/O 相關**的呼叫 (`openat`, `read`, `write`, `close` 等)。 | `strace -e file ls` |
| **`-e open`** | 專門過濾所有**檔案開啟**的呼叫,可檢查程式嘗試存取哪些檔案。 | `strace -e open cat /etc/passwd` |
| **`-f`** | 追蹤目標程序及其**所有子程序** (`fork`, `vfork`)。對於複雜應用程式很有用。 | `strace -f make` |
| **`-T`** | 顯示每個系統呼叫實際花費的**時間**。可用於性能除錯。 | `strace -T ls` |
### 三、安全與除錯應用範例
#### 範例 1:檢查應用程式是否嘗試連線網路
這是最常見的安全檢查,用於判斷一個工具(如 KMonad)是否有不該有的網路行為。
```bash
strace -e network -o /tmp/net_check.log kmonad /path/to/config.kbd
```
* **分析:** 執行 KMonad 一段時間後,按下 `Ctrl+C` 停止 `strace`。檢查 `/tmp/net_check.log` 檔案。如果檔案內容為空或只包含與網路無關的輸出,則表示該程式沒有嘗試連線網路。
#### 範例 2:檢查程式從哪裡讀取設定檔
您想知道一個程式(例如 `htop`)啟動時嘗試讀取哪些設定檔。
```bash
strace -e openat htop 2>&1 | grep -E '\.(conf|rc|json)'
```
* **分析:** `openat` 追蹤檔案開啟。我們將標準錯誤 (`2`) 重新導向到標準輸出 (`1`),再用 `grep` 過濾常見的設定檔副檔名。
#### 範例 3:診斷程式為什麼執行緩慢
使用 `-c` 和 `-T` 參數來診斷性能瓶頸。
```bash
strace -c -T sleep 3
```
* **輸出:** 會顯示所有系統呼叫的總耗時。對於 `sleep 3`,大部分時間會花在 `nanosleep` 呼叫上。
`strace` 是一個強大的診斷工具,學會靈活運用 `-e` 參數進行過濾,能讓您事半功倍。