追蹤程式碼的執行#

監控和追蹤工具讓你能從任意程式的執行中取得類似日誌的資料。相較於應用程式層級的日誌記錄,這種方式有幾個優勢:

  • 即使應用程式缺乏日誌功能,你也能取得資料
  • 不需要準備 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

各語言的追蹤方式#

  • Perlperl -d:Trace
  • Pythonpython -m trace --trace
  • Rubyruby -r tracer
  • Unix shellsh -xbash -xcsh -x

其他監控方式#

  • JavaScript tracing backend:spy-js
  • 網路封包監控
  • 資料庫 SQL 語句記錄(例如 MySQL 的 set global general_log = 1

DTrace:統一的動態追蹤框架#

DTrace 是由 Sun 開發的動態追蹤框架,提供統一的機制來全面且無侵入地監控作業系統、應用伺服器、runtime 環境、函式庫和應用程式。

  • 可用平台:Solaris、OS X、FreeBSD、NetBSD
  • Linux 替代方案:SystemTapLTTng

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)