ftrace与perf是Linux内核级系统调用追踪的两大核心工具:ftrace适用于轻量级函数级静态/动态追踪,perf侧重事件采样与高精度分析。

如果您需要深入理解程序在内核层面的行为,例如系统调用的触发频率、耗时分布或调用路径,则必须借助内核内置的追踪机制。perf 与 ftrace 是 Linux 系统中两种互补且高效的底层性能分析工具,分别适用于事件采样与函数级静态/动态追踪。以下是使用这两种工具进行系统调用追踪的具体操作步骤:
一、使用ftrace追踪系统调用入口
ftrace 通过挂载 debugfs 并配置 tracing_options 来启用 syscall_enter 事件,可精确捕获每个系统调用的发起时刻及参数。该方法不依赖用户态符号,适合轻量级、低开销的长期监控。
1、执行 mount -t debugfs nodev /sys/kernel/debug 挂载 debugfs 文件系统。
2、执行 echo function_graph > /sys/kernel/debug/tracing/current_tracer 切换至函数调用图模式。
3、执行 echo sys_enter_* > /sys/kernel/debug/tracing/set_ftrace_filter 过滤所有系统调用进入点。
4、执行 echo 1 > /sys/kernel/debug/tracing/tracing_on 启动追踪。
5、运行目标程序,例如 ./test_program。
6、执行 echo 0 > /sys/kernel/debug/tracing/tracing_on 停止追踪。
7、执行 cat /sys/kernel/debug/tracing/trace_pipe 实时读取追踪输出。
二、使用perf record捕获系统调用事件
perf record 可基于内核 perf_event 子系统对 sys_enter 和 sys_exit 事件进行采样,支持按 PID 或 CPU 范围过滤,并生成可离线分析的二进制数据文件。该方式适合高精度计数与火焰图生成。
1、执行 perf list | grep syscall 确认系统支持的系统调用事件名,如 syscalls:sys_enter_read。
2、执行 perf record -e 'syscalls:sys_enter_*' -p $(pidof test_program) -g 对指定进程的所有系统调用入口事件进行带调用图记录。
3、等待程序运行结束后,自动保存至 perf.data 文件。
4、执行 perf script 解析原始事件流,显示每条系统调用的 PID、时间戳、参数值及用户态调用栈。
5、执行 perf report --sort comm,symbol --no-children 汇总各命令触发的系统调用次数分布。
三、启用ftrace的syscall插件并导出结构化日志
ftrace 提供 syscall 插件(需内核配置 CONFIG_FTRACE_SYSCALLS=y),可将系统调用事件格式化为字段对齐的日志行,便于后续用 awk 或 Python 解析。该方式避免了 trace_pipe 的实时性限制,适合批量处理。
1、确认内核支持:执行 ls /sys/kernel/debug/tracing/events/syscalls/ 应列出 sys_enter_* 和 sys_exit_* 子目录。
2、执行 echo 1 > /sys/kernel/debug/tracing/events/syscalls/sys_enter_openat/enable 单独启用 openat 调用追踪。
3、执行 echo 1 > /sys/kernel/debug/tracing/options/latency-format 开启延迟格式以包含时间戳。
4、执行 echo 1 > /sys/kernel/debug/tracing/options/event-fork 启用子进程事件继承。
5、运行目标程序后,执行 cat /sys/kernel/debug/tracing/trace 获取结构化输出,每行含时间、CPU、PID、系统调用名、参数十六进制值。
四、结合perf probe动态添加系统调用参数解析
默认 perf 仅显示系统调用号与原始寄存器值,无法识别语义化参数。perf probe 可基于内核头文件或 vmlinux 符号,在 sys_enter_* 探针处注入参数解析逻辑,将 raw_syscall_args 映射为 filename、flags 等可读字段。
1、执行 perf probe -l 查看当前已定义探针,确认无冲突。
2、执行 perf probe 'sys_enter_openat filename:string flags:u32 mode:u32' 根据系统调用 ABI 定义参数类型与名称。
3、执行 perf record -e probe:sys_enter_openat -p $(pidof test_program) 记录增强型事件。
4、执行 perf script -F comm,pid,tid,event,trace 输出含解析后参数的完整调用记录。
5、若提示找不到 vmlinux,需先执行 perf buildid-cache -v /usr/lib/debug/lib/modules/$(uname -r)/vmlinux 注入调试符号。
五、禁用ftrace动态过滤器并重置状态
多次实验后,ftrace 的 filter 设置可能残留影响后续追踪。必须显式清空所有过滤规则并关闭 tracer,否则新会话仍将沿用旧配置,导致事件丢失或误匹配。
1、执行 echo > /sys/kernel/debug/tracing/set_ftrace_filter 清空函数过滤器。
2、执行 echo > /sys/kernel/debug/tracing/set_event 清空事件过滤器。
3、执行 echo nop > /sys/kernel/debug/tracing/current_tracer 切回空 tracer。
4、执行 echo 0 > /sys/kernel/debug/tracing/tracing_on 确保追踪已停止。
5、执行 echo > /sys/kernel/debug/tracing/trace 清空 trace 缓冲区内容。











