Appearance
perf probe —— 动态探针
更新时间:2026-08-06
perf probe 在运行中的内核或用户程序里动态添加追踪点(probe),无需重新编译即可在任意函数入口/出口或代码行插入探针,收集变量值和调用上下文。
关联:uprobe 原理篇、perf probe 动手实验、perf-trace.md(syscall 追踪)、ftrace(内核追踪)
一、perf probe 能回答什么问题
| 问题 | 操作 |
|---|---|
| 某个内核函数被调用了几次? | 在函数入口加 probe |
| 内核函数某参数的值是多少? | probe 该函数并记录参数 |
| 用户态函数被调用时某个局部变量是啥? | uprobe + %REG 寄存器引用 / DWARF |
| 某内核函数的返回值是什么? | 在函数返回处(%return)加 probe |
| 某行代码是否被执行到? | probe 源码行号 |
二、基本使用
2.1 内核探针(kprobe)
bash
# 在 vfs_read 入口添加探针
perf probe --add vfs_read
# 添加探针并记录参数
perf probe --add 'vfs_read file->f_path.dentry->d_name.name:string'
# 在函数返回处添加探针(记录返回值)
perf probe --add 'vfs_read%return $retval'
# 查看已添加的探针
perf probe -l
# 删除探针
perf probe --del vfs_read
# 删除全部探针
perf probe --del '*'2.2 用户态探针(uprobe)
bash
# 在可执行文件的某函数入口添加探针
perf probe -x ./your_program --add hot_function
# 在用户态函数的某一行添加探针
perf probe -x ./your_program --add 'hot_function:15'
# 记录用户态函数参数
perf probe -x ./your_program --add 'hot_function n=%di len=%si:u32'2.3 使用探针采集数据
bash
# 用 perf record 采集探针事件
perf record -e probe:vfs_read -a -- sleep 10
# 查看事件输出
perf script
# 用 perf stat 统计探针事件
perf stat -e probe:vfs_read -a -- sleep 10三、常用选项
| 选项 | 含义 | 示例 |
|---|---|---|
--add <probe> | 添加探针 | --add vfs_read |
--del <probe> | 删除探针 | --del vfs_read |
-l | 列出所有探针 | perf probe -l |
-x <file> | 指定用户态程序 | -x ./your_program |
-L | 列出函数可 probe 的行号 | perf probe -x ./prog -L hot_function |
-F | 列出可 probe 的函数 | perf probe -x ./prog -F |
-V | 列出函数可访问的变量 | perf probe -x ./prog -V hot_function |
-d | 同 --del | — |
-f | 强制添加(替换已有) | — |
四、探针语法详解
4.1 基本格式
bash
[EVENT=]FUNC[@SRC][:RLN|+OFFS|%return|;PTN] [ARG ...]| 部分 | 含义 | 示例 |
|---|---|---|
FUNC | 函数名 | vfs_read |
@SRC | 源文件名 | @fs/read_write.c |
:RLN | 相对行号 | :15(函数内第 15 行) |
+OFFS | 字节偏移 | +20 |
%return | 函数返回处 | vfs_read%return |
ARG | 要记录的参数/变量 | $retval, n=%di |
4.2 参数指定
bash
# 内核探针:直接引用变量名
perf probe --add 'vfs_read file->f_path.dentry->d_name.name:string count=%si:u64'
# 用户态探针:用寄存器引用(x86_64 调用约定)
# %di/%si/%dx/%cx/%r8/%r9 = 第 1-6 个参数
perf probe -x ./prog --add 'hot_func n=%di len=%si:u32'
# 返回值
$retval五、实战场景
场景 1:追踪内核函数调用频率
bash
# 添加探针
perf probe --add tcp_sendmsg
# 统计 10 秒内的调用次数
perf stat -e probe:tcp_sendmsg -a -- sleep 10场景 2:调试内核函数参数
bash
# 在 vfs_write 入口记录 fd 和写入字节数
perf probe --add 'vfs_write count=%si file->f_path.dentry->d_name.name:string'
perf record -e probe:vfs_write -a -- sleep 5
perf script场景 3:用户态函数调试
bash
# 列出可 probe 的函数
perf probe -x ./prog -F
# 列出某函数可 probe 的行号和变量
perf probe -x ./prog -L hot_function
perf probe -x ./prog -V hot_function
# 添加探针
perf probe -x ./prog --add 'hot_function n=%di buf=%si'
# 采集
perf record -e probe_prog:hot_function ./prog
perf script场景 4:确认某内核路径是否被执行
bash
perf probe --add 'some_rare_path'
perf stat -e probe:some_rare_path -a -- sleep 10
# 如果计数为 0 → 该路径未被执行六、注意事项
- 需要调试符号:内核需要
CONFIG_DEBUG_INFO=y,用户态需要-g编译。 - 权限:通常需要 root。
- 性能开销:探针本身有一定开销。高频路径上的探针可能导致性能下降。
- 清理:用完记得
perf probe --del '*'清理。 - uprobe 与 ASLR:如果程序启用地址随机化(PIE),uprobe 需要在内核加载后添加,perf probe 会自动处理。
七、与相关文档的交叉引用
| 场景 | 文档 |
|---|---|
| uprobe 原理深入 | uprobe 原理篇 |
| perf probe 动手实验 | perf probe 演示 |
| syscall 追踪(低开销替代) | perf-trace.md |
| 内核追踪(ftrace 替代) | ftrace 指南 |
八、一句话总结
perf probe是内核与用户态的"外科手术刀"——无需重启或重编译,即可在任意函数入口/出口甚至源码行精确插入探针,让你看到程序内部变量的实时值和调用模式。