strace 攔截並記錄進程發出的所有系統呼叫與信號,是無需原始碼、無需重編譯、無需重啟的動態分析神器。適用場景:
# 追蹤新啟動程式
strace -o trace.log -f -s 200 ./myapp arg1 arg2
# 依附執行中進程 (需相同 UID 或 CAP_SYS_PTRACE)
strace -p 12345 -f -o attach.log
# 只看特定系統呼叫
strace -e trace=open,openat,read,write -p 12345
strace -e trace=network -p 12345 # 所有網路相關
strace -e trace=file -p 12345 # 所有檔案相關
strace -e trace=process -p 12345 # fork/exec/exit
# 統計模式 (效能分析)
strace -c -p 12345
strace -c -f ./myapp
# 時間戳
strace -tt -T -p 12345 # -tt: 微秒時間, -T: 耗時
syscall_name(arg1, arg2, ...) = return_value (errno_message)
範例:
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 832) = 832
connect(3, {sa_family=AF_INET, sin_port=htons(3306), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 ECONNREFUSED (Connection refused)
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f8b4c000000
--- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0x0} ---
+++ killed by SIGSEGV +++
= 3 成功 (檔案描述符)、= 0 成功 (無特定返回)、= -1 ERRNO 失敗ENOENT (不存在)、EACCES (權限)、ECONNREFUSED (連線拒絕)、ETIMEDOUT (超時)、EAGAIN (非阻塞無資料)sockaddr、stat)-s 200 加長strace -e trace=open,openat,access,stat -f ./myapp 2>&1 | grep -E "ENOENT|EACCES"
# 輸出顯示嘗試路徑順序,找到預期路徑缺失即可定位
strace -e trace=connect,sendto,recvfrom,poll,epoll_wait -p
# 觀察 connect 返回 ECONNREFUSED/ETIMEDOUT,或 poll 長時間無事件
strace -p -f
# 觀察停在哪個系統呼叫:
# - futex/pthread_cond_wait → 鎖等待 (死鎖/活鎖)
# - read/poll/epoll_wait → 等待 I/O (網路/磁碟/管道)
# - nanosleep → 刻意睡眠
# - wait4 → 等待子進程
strace -c -f -p 30
# 輸出統計表:
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- -------- ----------------
45.23 0.123456 12 10245 0 read
30.12 0.082345 8 10245 0 write
15.00 0.041234 150 275 0 fsync
5.12 0.014567 200 73 12 stat
4.53 0.012345 50 247 0 mmap
# 重點看:% time 高、errors 多、usecs/call 大
# Host 上追蹤容器進程 (需 CAP_SYS_PTRACE)
docker run --cap-add=SYS_PTRACE --security-opt seccomp=unconfined ...
# 或宿主機直接
strace -p $(docker inspect --format '{{.State.Pid}}' container_name) -f
# Kubernetes
kubectl debug node/ -it --image=ubuntu -- strace -p -f
| 技巧 | 指令/說明 |
|---|---|
| 多進程樹追蹤 | -f 追蹤 fork/clone 子進程,輸出含 PID 前綴 |
| 系統呼叫篩選 | -e trace=set 只看集合,-e trace=!set 排除集合 |
| 路徑解析 | -y 顯示 fd 對應路徑,-yy 顯示完整路徑 |
| 信號追蹤 | -e signal=all 或預設即含信號 |
| 注入錯誤 (故障注入) | strace -e inject=open:error=ENOENT:when=3 ./app 第 3 次 open 失敗 |
| 輸出 JSON (機器解析) | strace --format=json -o trace.json ./app (strace 5.10+) |
| 壓縮輸出 | strace -o trace.log.zst --compress=zstd ./app |
| 工具 | 層級 | 優點 | 缺點 | 適用場景 |
|---|---|---|---|---|
| strace | 系統呼叫 | 通用、無需編譯、即時附著 | 開銷大 (10-100x)、不可看用戶態邏輯 | 配置檔、權限、網路、掛住、崩潰 |
| ltrace | 庫函數 | 看 glibc/動態庫呼叫 | 不支援靜態連結、開銷更大 | malloc/free、printf、庫級邏輯 |
| gdb | 原始碼/指令 | 完整堆疊、變數檢查、斷點 | 需符號表、侵入式、需暫停 | Core dump、邏輯錯誤、死鎖精確定位 |
| perf | CPU 取樣 | 低開銷、全系統、火焰圖 | 不看系統呼叫參數 | CPU 熱點、Cache miss、分支預測 |
| bpftrace/eBPF | 核心/用戶動態 | 可程式化、安全、低開銷、生產級 | 學習曲線、核心版本要求 | 生產環境持續觀測、自定義指標 |
| SystemTap | 核心動態 | 豐富 Tapset、腳本語言 | 需核心開發套件、編譯慢 | 核心開發者、深度核心路徑 |
-e trace 縮小範圍,降低開銷與雜訊-o file 避免終端機緩衝區爆滿、方便事後分析-tt -T 關聯日誌時間線、量化延遲bpftrace 或 perfdebuginfo/dbgsym 套件讓 gdb/perf/bpftrace 解析函數名口訣:strace 看介面 (系統呼叫),gdb 看邏輯 (堆疊/變數),perf 看熱點 (CPU),bpftrace 看一切 (生產級動態)。