strace 追蹤用戶空間進程發出的系統調用與信號,顯示參數與返回值(符號形式),無需修改內核即可使用。配合 ltrace(庫函數調用)與 truss(System V 風格),構成「鐵三角」調試工具集。
| 參數 | 說明 |
|---|---|
-f | 跟蹤 fork/vfork 產生的子進程 |
-F | 跟蹤 vfork(Linux 下通常與 -f 同效) |
-o file | 輸出至檔案而非 stderr |
-e expr | 過濾表達式,如 -e open,read、-e trace=file |
-p PID | 附加到運行中的進程 |
-tt | 顯示微秒級時間戳 |
-T | 顯示每次系統調用耗時 |
-s N | 字串顯示最大長度(預設 32) |
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
│ │ │ │
│ │ │ └─ 返回值(fd=3)
│ │ └─ 參數(旗標符號化)
│ └─ 系統調用名
└─ 調用參數(路徑、標誌等)
環境:FreeBSD 5.2.1,clint 為 C++ 靜態分析工具。
現象:執行 clint foo.cpp 直接 Segmentation fault (core dumped)。
診斷:
# truss -f -o clint.truss clint
# tail clint.truss
...
stat("/root/.clint/plugins", 0xbfbfe680) ERR#2 'No such file or directory'
SIGNAL 11
SIGNAL 11
根因:程式嘗試 stat 不存在的目錄 /root/.clint/plugins,未做錯誤處理直接導致段錯誤。
修復:
mkdir -p /root/.clint/plugins
# 再次執行仍報錯,繼續追蹤發現需 /root/.clint/plugins/python
mkdir -p /root/.clint/plugins/python
# 程式正常運行
環境:FreeBSD 5.2.1,vim 6.2.154,無錯誤輸出。
診斷:使用 truss -f -D -o vim.truss vim(-D 顯示相對時間戳)。
關鍵發現:
735: 0.000021511 socket(0x2,0x1,0x0) = 4
735: 0.000014248 setsockopt(0x4,0x6,0x1,0xbfbfe3c8,0x4) = 0
...
735: 29.876543 connect(0x4, {...}) = -1 ERR#145 'Connection timed out'
...
# 大量時間花在連接某個網路地址超時
根因:vim 配置或插件嘗試連接網路(如檢查更新、同步配置),DNS 解析或防火牆導致超時阻塞。
修復:檢查 .vimrc、插件配置,禁用自動更新或修正網路策略。
通用排查步驟:
strace -f -o app.log ./app 記錄完整啟動過程。ENOENT(檔案不存在)、EACCES(權限不足)、ETIMEDOUT(超時)、EAGAIN(資源暫不可用)。open、access、connect、read/write 失敗行。diff 或 meld)。strace -e trace=open,stat -e fault=inject:error=ENOENT:when=3 ./app(注入故障測試)。strace -c -f ./app 輸出調用次數、總耗時、平均耗時排行。strace -p $(pidof nginx) -o nginx_trace.log -tt -T -s 1024。strace 是「看得見的內核」,能將黑盒進程變為透明盒。掌握 -f -o -e -p -tt -T 組合拳,配合 grep/awk 過濾,可在幾分鐘內定位 90% 的「疑難雜症」。