SystemTap (stap) 是 Linux 核心級動態追蹤框架,允許使用者編寫腳本探測核心/使用者空間函數進出、變數存取、效能計數器等,無需重新編譯核心或重啟系統。類似 DTrace (Solaris/BSD) 與 eBPF (現代 Linux)。
# 1. 確認核心版本
uname -r
# 例: 3.10.0-1160.el7.x86_64
# 2. 安裝核心開發套件與除錯符號 (關鍵!版本必須精確匹配)
yum install -y kernel-devel-$(uname -r) kernel-debuginfo-$(uname -r)
# 或手動下載對應版本 rpm:
# https://debuginfo.centos.org/
# 3. 安裝 SystemTap
yum install -y systemtap systemtap-runtime
# 4. 驗證
stap -v -e 'probe begin { println("Hello SystemTap") exit() }'
Missing kernel debuginfo:debuginfo-install kernel 或手動安裝匹配版本 kernel-debuginfo/kernel-debuginfo-common。Kernel version mismatch:確認 uname -r 與 kernel-devel 版本完全一致。stapdev/stapusr 群組。# 探針定義
probe <探針點> {
// 處理邏輯 (C 風格語法)
}
# 常用探針點類型
kernel.function("func_name") // 核心函數進入
kernel.function("func_name").return // 核心函數返回
kernel.statement("file.c:123") // 特定行號
process("/path/to/bin").function("foo") // 使用者空間 (需 uprobes 支援)
timer.ms(100) // 定時器
begin / end // 腳本啟動/結束
# syscall_count.stp
global syscalls
probe syscall.* {
syscalls[name]++
}
probe timer.s(5) {
foreach (name in syscalls- limit 10)
printf("%s: %d\n", name, syscalls[name])
delete syscalls
}
stap syscall_count.stp
# trace_io.stp
probe syscall.open.return {
if (pid() == target())
printf("open(%s) = %d\n", user_string($filename), $return)
}
probe syscall.read.return {
if (pid() == target())
printf("read(%d, %p, %ld) = %ld\n", $fd, $buf, $count, $return)
}
probe syscall.write.return {
if (pid() == target())
printf("write(%d, %p, %ld) = %ld\n", $fd, $buf, $count, $return)
}
stap trace_io.stp -x $(pidof myapp)
# func_latency.stp
global entry_time
probe kernel.function("vfs_read") {
entry_time[tid()] = gettimeofday_us()
}
probe kernel.function("vfs_read").return {
if (entry_time[tid()]) {
latency = gettimeofday_us() - entry_time[tid()]
printf("vfs_read latency: %d us\n", latency)
delete entry_time[tid()]
}
}
# kmalloc_profile.stp
global alloc_sizes
probe kernel.function("kmalloc") {
alloc_sizes[$bytes]++
}
probe timer.s(10) {
foreach (size in alloc_sizes- limit 20)
printf("size=%d count=%d\n", size, alloc_sizes[size])
exit()
}
if (pid() == 1234 || execname() == "nginx") 減少開銷。global stats 配合 ++, @sum, @avg, @hist_log 統計。arr[key] = value,支援字串/整數鍵。stap -g 允許 Guru 模式 (嵌入 C 程式碼),需謹慎使用。stap -m mymod script.stp 產生 .ko,可 insmod 長期載入。| 特性 | SystemTap | eBPF/BCC |
|---|---|---|
| 核心版本需求 | 較舊也支援 (RHEL 6+) | 需 4.1+ (完整功能 5.2+) |
| 語言 | 專用腳本語言 | C (核心) + Python/Lua (使用者) |
| 安全性 | Guru 模式可注入 C 碼 (風險高) | 驗證器保證安全,無法死循環/崩潰核心 |
建議:新環境 (Kernel ≥ 4.14) 優先用 eBPF/BCC/bpftrace;舊企業級 Linux (RHEL/CentOS 6/7) SystemTap 成熟穩定。
SystemTap 是深入核心觀測的利器,掌握探針點類型、聚合統計、條件過濾三大核心技巧,即可解決 90% 的效能診斷、死鎖分析、I/O 熱點追蹤問題。記住:精確匹配核心除錯符號是成功前提。