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 跟踪器启用流程总览

下图展示了从内核配置到跟踪数据读取的完整操作流程,帮助建立全局视角。

ftrace 配置与启用流程 ftrace 配置与启用流程 1. 内核配置 CONFIG_FTRACE=y 2. 编译 & 启动 内核加载 ftrace 模块 3. 挂载 tracefs mount -t tracefs 4. 选择跟踪器 echo function_graph > current_tracer 5. 设置过滤规则 set_ftrace_filter 6. 启用跟踪 echo 1 > tracing_on 7. 读取跟踪数据 cat trace / trace_pipe 8. 禁用跟踪 echo 0 > tracing_on 提示:步骤 5(设置过滤规则)为可选步骤,但强烈建议在生产环境中使用以降低性能开销

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 支持 重新编译内核或使用发行版默认内核