要在 Linux 内核或模块的函数 入口和退出点 添加 perf probe 探针,可以使用 %return 后缀来跟踪函数返回。以下是详细步骤和示例:


1. 基本语法

# 添加函数入口探针
sudo perf probe -m <模块名,必须路径加ko,不然会报不在.text段> --add <函数名>

# 添加函数退出探针(使用 %return)
sudo perf probe -m <模块名,必须路径加ko> --add <函数名>%return

2. 完整示例

示例目标:跟踪内核函数 my_module_add的入口和退出
# 添加入口探针
sudo perf probe -m ./bin/my_module.ko --add my_module_add

# 添加退出探针
sudo perf probe -m ./bin/my_module.ko --add my_module_add%return

# 查看已添加的探针
sudo perf probe -l

输出示例:

probe:my_module_add      (on my_module_add)
probe:my_module_return    (on my_module_add%return)

3. 记录并分析数据

# 记录探针事件(按 Ctrl+C 停止)
sudo perf record -e 'probe:my_module_add*' -aR

# 查看记录的数据
perf script

输出示例:

perf 1234 [000] 5678.901234: probe:my_module_add: (ffffffff81234560)
perf 1234 [000] 5678.902345: probe:my_module_add_return: (ffffffff81234560 <- ffffffff81234980)
  • 入口事件:probe:my_module_add。

  • 退出事件:probe:my_module_add_return(名称可能不同)。

  • 时间差:计算 退出时间 - 入口时间 即为函数执行耗时。


4. 计算函数耗时(脚本化)

# 生成耗时统计(需手动处理或借助脚本)
perf script | awk '/probe:my_module_add/ {start[$1]=$3} /probe:my_module_add_return/ {print $1, $3 - start[$1]}'

输出示例:

1234 0.001234  # 进程 PID 和耗时(秒)

5. 清理探针

sudo perf probe --del my_module_add
sudo perf probe --del my_module_add%return

6. 跟踪用户空间函数退出

如果是用户态程序(如 libc 的 malloc):

# 添加 malloc 的入口和退出探针
sudo perf probe -x /lib/x86_64-linux-gnu/libc.so.6 malloc
sudo perf probe -x /lib/x86_64-linux-gnu/libc.so.6 malloc%return

# 记录事件
sudo perf record -e 'probe_libc:malloc*' -aR

常见问题

Q1: 报错 %return is not supported?

  • 原因:目标函数可能被内联优化或没有返回指令。

  • 解决:

    • 使用 --no-inlines 禁用内联:

      sudo perf probe --no-inlines --add vfs_read%return
    • 改用 ftrace function_graph:

      echo function_graph > /sys/kernel/tracing/current_tracer
      echo vfs_read > /sys/kernel/tracing/set_graph_function

Q2: 如何查看函数的返回值和参数?

# 显示返回值(需调试符号)
sudo perf probe --add 'vfs_read%return $retval'

# 显示参数(入口时)
sudo perf probe --add 'vfs_read fd buf count pos'

Q3: 如何跟踪内核模块的函数退出?

确保模块已加载,并通过 /proc/kallsyms 获取地址:

# 查找模块函数地址
sudo cat /proc/kallsyms | grep my_module_function

# 使用地址添加探针
sudo perf probe --add my_module_function=0xffffffffa0123450
sudo perf probe --add my_module_function%return=0xffffffffa0123450

总结

场景命令
内核函数退出跟踪sudo perf probe --add <函数名>%return
用户函数退出跟踪sudo perf probe -x <二进制> <函数名>%return
显示返回值sudo perf probe --add '<函数名>%return $retval'
解决内联问题sudo perf probe --no-inlines --add ...

通过 %return 可以方便地分析函数执行耗时,适用于性能调优和问题诊断!

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐