追蹤程式碼的執行#
監控和追蹤工具讓你能從任意程式的執行中取得類似日誌的資料。相較於應用程式層級的日誌記錄,這種方式有幾個優勢:
- 即使應用程式缺乏日誌功能,你也能取得資料
- 不需要準備 debug 版本的軟體(debug 版本可能混淆或隱藏原始問題)
- 相較於 GUI debugger,這種方式輕量級,適合在精簡的生產環境使用
系統呼叫與函式庫呼叫追蹤#
許多效能問題和 bug 涉及第三方函式庫或與作業系統的互動。透過檢查你的程式對外部元件的呼叫,可以精確定位效能問題和 bug。
常用的 call tracing 工具:
| 工具 | 用途 | 平台 |
|---|---|---|
ltrace | 追蹤函式庫呼叫 | Unix |
strace | 追蹤系統呼叫 | Linux |
ktrace | 追蹤系統呼叫 | BSD |
truss | 追蹤系統呼叫 | Solaris |
| JProfile | 追蹤 Java 程式 | 跨平台 |
| Process Monitor | 追蹤 DLL 呼叫 | Windows |
你也可以用
-p選項將追蹤工具附加到已在運行的程式上。GUI 工具則允許你直接點擊選擇要追蹤的程序。
實際案例:strace 定位效能問題#
作者遇到一個程式處理輸入異常緩慢的案例。用 strace 追蹤後發現,程式對每個字元都發出兩個系統呼叫:一個讀取 8191 bytes,一個將檔案 seek pointer 回退 8190 bytes。問題出在 tellg 方法的呼叫導致 I/O library 的 buffer 未被使用。
處理 strace 輸出#
結合 Unix 工具處理 strace 的輸出可以大幅提升除錯能力。例如,找出程式開啟的哪些設定檔包含特定字串:
# 將 strace 輸出導入管道
strace -fo >(
# 提取每個開啟的檔案路徑
sed -n 's/.*open("\(\/[^"]*\)".*= [^-].*/\1/p' |
# 移除特殊裝置檔案
egrep -v '^/(proc|dev|tmp)/' |
# 每個路徑只輸出一次
sort -u |
# 在每個檔案中搜尋目標字串
xargs fgrep xyzzy) prog各語言的追蹤方式#
- Perl:
perl -d:Trace - Python:
python -m trace --trace - Ruby:
ruby -r tracer - Unix shell:
sh -x、bash -x、csh -x等
其他監控方式#
- JavaScript tracing backend:spy-js
- 網路封包監控
- 資料庫 SQL 語句記錄(例如 MySQL 的
set global general_log = 1)
DTrace:統一的動態追蹤框架#
DTrace 是由 Sun 開發的動態追蹤框架,提供統一的機制來全面且無侵入地監控作業系統、應用伺服器、runtime 環境、函式庫和應用程式。
- 可用平台:Solaris、OS X、FreeBSD、NetBSD
- Linux 替代方案:SystemTap、LTTng
DTrace 使用名為 D 的領域特定語言,由 pattern/action pairs 組成:
# 追蹤所有系統呼叫的進入點
dtrace -n 'syscall:::entry'
# 追蹤所有開啟的檔案名稱
dtrace -n 'syscall::open:entry {trace(copyinstr(arg0));}'
# 統計每個程序的執行次數
# proc:::exec-success { @proc[execname] = count()}DTrace 擁有數以萬計的預定義 probes,涵蓋 system calls、kernel functions、I/O events、process creation 等各個層面。
JVM 追蹤:Byteman#
Byteman 可以將 Java 程式碼注入 runtime system 的方法中,無需重新編譯。優勢包括:
- 不需要存取原始碼,可追蹤第三方程式碼
- 可注入 faults 來驗證程式碼的回應
- 可撰寫測試腳本,在應用程式內部狀態偏離預期時讓測試失敗
Windows Performance Toolkit#
Windows 生態系統提供 Windows Performance Toolkit(屬於 Windows Assessment and Deployment Kit),包含:
- Windows Performance Recorder:記錄系統事件
- Windows Performance Analyzer:圖形化分析結果
重點回顧#
- 系統呼叫和函式庫呼叫追蹤讓你無需存取原始碼就能監控程式行為
- 學習使用 Windows Performance Toolkit(Windows)、SystemTap(Linux)或 DTrace(OS X、Solaris、FreeBSD)