3. ftrace配置与启用
ftrace 作为 Linux 内核内置的跟踪框架,其功能集合由内核编译选项控制,运行时通过 tracefs 虚拟文件系统暴露接口。本章将系统讲解从内核配置到跟踪器启用的完整链路,确保你能够独立搭建 ftrace 运行环境。
3.1 内核配置选项:裁剪与开启 ftrace 核心功能
ftrace 的绝大多数功能默认集成在主流发行版内核中,但在嵌入式或定制内核场景下,需要手动确认以下关键配置项。配置通过 make menuconfig 或直接编辑 .config 文件完成。
| 配置宏 | 功能描述 | 推荐状态 |
|---|---|---|
CONFIG_FTRACE |
ftrace 框架总开关,必须开启 | y |
CONFIG_FUNCTION_TRACER |
函数级跟踪器,支持记录内核函数调用 | y |
CONFIG_FUNCTION_GRAPH_TRACER |
函数调用图跟踪器,显示调用层级与耗时 | y |
CONFIG_STACK_TRACER |
内核栈回溯跟踪器,用于分析栈溢出 | y |
CONFIG_DYNAMIC_FTRACE |
动态插桩,允许运行时启用/禁用函数跟踪点 | y |
CONFIG_FTRACE_SYSCALLS |
系统调用跟踪支持 | y |
CONFIG_HIST_TRIGGERS |
直方图触发,用于聚合统计 | 按需 |
验证当前内核配置: 使用
cat /boot/config-$(uname -r) | grep CONFIG_FTRACE 快速检查目标配置是否已开启。若输出为 y 或 m,则表示已集成。
3.2 挂载 tracefs:访问 ftrace 控制接口
ftrace 通过 tracefs 虚拟文件系统与用户空间交互,默认挂载点为 /sys/kernel/tracing。若该目录不存在或为空,需要手动挂载。
3.2.1 检查当前挂载状态
# 查看 tracefs 是否已挂载
mount | grep tracefs
# 典型输出示例
# tracefs on /sys/kernel/tracing type tracefs (rw,relatime)
3.2.2 手动挂载 tracefs
# 创建挂载点(如果不存在)
sudo mkdir -p /sys/kernel/tracing
# 挂载 tracefs
sudo mount -t tracefs tracefs /sys/kernel/tracing
# 验证挂载
ls /sys/kernel/tracing/
挂载成功后,/sys/kernel/tracing/ 目录下会出现一系列控制文件和跟踪输出文件,核心文件清单如下:
| 文件/目录 | 作用 |
|---|---|
available_tracers |
列出当前内核支持的所有跟踪器 |
current_tracer |
写入跟踪器名称以启用,读取以查看当前跟踪器 |
tracing_on |
全局跟踪开关:写入 1 启用,0 暂停 |
trace |
输出跟踪结果(人类可读格式) |
trace_pipe |
流式输出跟踪结果,支持实时查看 |
set_ftrace_filter |
设置函数过滤白名单 |
set_ftrace_notrace |
设置函数过滤黑名单 |
buffer_size_kb |
每个 CPU 的跟踪缓冲区大小(KB) |
生产环境建议: 将
tracefs 挂载写入 /etc/fstab,确保系统重启后自动挂载:tracefs /sys/kernel/tracing tracefs defaults 0 0
3.3 启用与禁用跟踪器:从 current_tracer 到 tracing_on
ftrace 的跟踪器启用分为两个层面:选择跟踪器类型 和 控制全局开关。以下通过完整流程演示如何启用 function_graph 跟踪器。
3.3.1 查看可用跟踪器
cat /sys/kernel/tracing/available_tracers
# 输出示例(不同内核版本有差异)
# function_graph function nop
其中 nop 表示空跟踪器(不执行任何跟踪),function 为函数调用跟踪器,function_graph 为函数调用图跟踪器。
3.3.2 启用指定跟踪器
# 切换到 function_graph 跟踪器
echo function_graph > /sys/kernel/tracing/current_tracer
# 验证当前跟踪器
cat /sys/kernel/tracing/current_tracer
# 输出: function_graph
3.3.3 控制全局跟踪开关
# 启用跟踪(开始记录数据)
echo 1 > /sys/kernel/tracing/tracing_on
# 执行目标负载(例如触发一个驱动操作)
# ...
# 暂停跟踪(停止记录,但保留缓冲区数据)
echo 0 > /sys/kernel/tracing/tracing_on
3.3.4 读取跟踪结果
# 查看跟踪输出
cat /sys/kernel/tracing/trace
# 实时流式输出(按 Ctrl+C 退出)
cat /sys/kernel/tracing/trace_pipe
性能影响提示: 启用
function_graph 跟踪器会对内核整体性能产生显著影响(可能降低 30%~50% 吞吐量)。在生产环境中,建议先使用 set_ftrace_filter 限定跟踪范围,再开启 tracing_on。
3.4 跟踪器启用流程总览
下图展示了从内核配置到跟踪数据读取的完整操作流程,帮助建立全局视角。
3.5 快速启用/禁用脚本模板
以下脚本封装了 ftrace 的启用与禁用流程,适用于驱动性能分析的快速迭代场景。
3.5.1 启用跟踪脚本
#!/bin/bash
# enable_ftrace.sh - 启用 function_graph 跟踪器并限定跟踪范围
TRACING_DIR="/sys/kernel/tracing"
# 切换到 function_graph 跟踪器
echo function_graph > $TRACING_DIR/current_tracer
# 设置过滤:只跟踪指定驱动模块的函数
echo "my_driver_*" > $TRACING_DIR/set_ftrace_filter
# 设置缓冲区大小(每个 CPU 4MB)
echo 4096 > $TRACING_DIR/buffer_size_kb
# 清空历史跟踪数据
echo > $TRACING_DIR/trace
# 启用全局跟踪
echo 1 > $TRACING_DIR/tracing_on
echo "ftrace 已启用,跟踪范围:my_driver_*"
3.5.2 禁用跟踪脚本
#!/bin/bash
# disable_ftrace.sh - 停止跟踪并保存结果
TRACING_DIR="/sys/kernel/tracing"
# 暂停跟踪
echo 0 > $TRACING_DIR/tracing_on
# 保存跟踪结果到文件
cp $TRACING_DIR/trace ./ftrace_output_$(date +%Y%m%d_%H%M%S).log
# 恢复默认跟踪器(nop)
echo nop > $TRACING_DIR/current_tracer
echo "ftrace 已禁用,跟踪结果已保存"
关键检查点: 每次启用跟踪前,务必执行
echo > trace 清空缓冲区,避免旧数据干扰分析结果。同时确认 tracing_on 初始值为 0,防止启用瞬间产生大量无用记录。
3.6 常见问题与排查
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
current_tracer 写入失败 |
内核未开启对应跟踪器配置 | 检查 CONFIG_FUNCTION_GRAPH_TRACER 等配置 |
trace 文件为空 |
tracing_on 未置 1,或缓冲区被清空 |
确认 echo 1 > tracing_on 已执行 |
| 跟踪数据量过大导致系统卡顿 | 未设置过滤规则,跟踪了全部内核函数 | 使用 set_ftrace_filter 限定范围 |
tracefs 挂载点不存在 |
内核未编译 CONFIG_TRACING 支持 |
重新编译内核或使用发行版默认内核 |