4. ftrace 基础配置:挂载 tracefs、可用追踪器列表、current_tracer 设置
ftrace 是 Linux 内核内置的追踪基础设施,其配置入口通过 tracefs 伪文件系统暴露。在开始追踪系统调用之前,必须完成挂载、查看可用追踪器、选择当前追踪器三个基础步骤。本节将逐一演示这些操作,并解释每个步骤背后的内核机制。
4.1 挂载 tracefs 文件系统
tracefs 通常自动挂载于 /sys/kernel/tracing,但在某些发行版或容器环境中需要手动挂载。挂载方式如下:
# 检查是否已挂载
mount | grep tracefs
# 手动挂载 tracefs
mount -t tracefs tracefs /sys/kernel/tracing
# 或使用 debugfs 兼容路径(旧内核)
mount -t debugfs debugfs /sys/kernel/debug
提示: 从内核 4.1 开始,ftrace 推荐使用独立的 tracefs,而非 debugfs。若使用 debugfs,路径为
/sys/kernel/debug/tracing,但功能完全一致。本课程统一使用 /sys/kernel/tracing 路径。
挂载成功后,/sys/kernel/tracing 目录下会出现一系列控制文件和追踪结果文件。下表列出最核心的几个文件及其用途:
| 文件/目录 | 用途 | 读写属性 |
|---|---|---|
available_tracers |
列出当前内核支持的所有追踪器 | 只读 |
current_tracer |
设置或查看当前激活的追踪器 | 读写 |
tracing_on |
全局追踪开关(1 开启,0 关闭) | 读写 |
trace |
输出追踪结果(人类可读格式) | 只读 |
trace_pipe |
流式输出追踪结果(阻塞读取) | 只读 |
set_event |
启用/禁用特定追踪事件 | 读写 |
关键概念: tracefs 是一个纯内存文件系统,所有追踪控制通过读写文件完成,无需额外的用户态工具。这种设计使得 ftrace 在嵌入式系统和最小化环境中也能直接使用。
4.2 可用追踪器列表
通过读取 available_tracers 文件,可以查看当前内核编译时启用了哪些追踪器。不同内核配置输出的列表可能不同,以下是一个典型输出:
# cat /sys/kernel/tracing/available_tracers
function_graph function nop
三个追踪器的核心差异如下表所示:
| 追踪器名称 | 输出粒度 | 典型用途 | 性能开销 |
|---|---|---|---|
| nop | 无追踪输出 | 关闭追踪、重置状态 | 几乎为零 |
| function | 每个内核函数入口 | 函数调用计数、调用频率分析 | 中等 |
| function_graph | 函数入口 + 出口 + 调用深度 | 函数调用链分析、延迟追踪 | 较高 |
注意: 如果
available_tracers 只显示 nop,说明内核编译时未开启 CONFIG_FUNCTION_TRACER 或 CONFIG_FUNCTION_GRAPH_TRACER。此时无法使用 function 和 function_graph 追踪器,需要重新编译内核。
除了上述三个基础追踪器,某些内核还支持以下扩展追踪器(取决于内核配置):
- wakeup / wakeup_rt / wakeup_dl:追踪进程唤醒延迟,用于实时性分析。
- irqsoff:追踪中断关闭时间,用于中断延迟分析。
- preemptoff:追踪抢占关闭时间,用于抢占延迟分析。
- blk:块设备 I/O 追踪,用于存储性能分析。
- mmiotrace:内存映射 I/O 追踪,用于驱动调试。
4.3 current_tracer 设置
current_tracer 文件用于查看或设置当前激活的追踪器。写入追踪器名称即可切换,写入 nop 则关闭追踪。
# 查看当前追踪器
cat /sys/kernel/tracing/current_tracer
nop
# 切换到 function 追踪器
echo function > /sys/kernel/tracing/current_tracer
# 验证切换结果
cat /sys/kernel/tracing/current_tracer
function
# 关闭追踪(重置为 nop)
echo nop > /sys/kernel/tracing/current_tracer
最佳实践: 在切换追踪器之前,建议先执行
echo 0 > tracing_on 暂停追踪,切换完成后再 echo 1 > tracing_on 恢复。这样可以避免在切换过程中产生不完整的追踪记录。
设置 current_tracer 时,内核会执行以下内部操作:
- 验证追踪器名称:检查写入的名称是否在
available_tracers列表中,若不在则返回错误。 - 停止当前追踪:自动暂停当前追踪器的数据采集(相当于内部执行
tracing_on = 0)。 - 重置缓冲区:清空旧的追踪数据,避免新旧数据混合。
- 注册新追踪器回调:将新追踪器的钩子函数挂接到内核函数追踪点。
- 恢复追踪:如果之前
tracing_on为 1,则自动恢复数据采集。
以下是一个完整的配置示例,展示如何从 nop 切换到 function_graph 并验证:
# 步骤1:确认当前状态
cat /sys/kernel/tracing/current_tracer
nop
# 步骤2:暂停追踪
echo 0 > /sys/kernel/tracing/tracing_on
# 步骤3:切换到 function_graph
echo function_graph > /sys/kernel/tracing/current_tracer
# 步骤4:验证切换
cat /sys/kernel/tracing/current_tracer
function_graph
# 步骤5:恢复追踪
echo 1 > /sys/kernel/tracing/tracing_on
# 步骤6:查看追踪输出(前20行)
head -20 /sys/kernel/tracing/trace
常见错误: 如果写入
current_tracer 时出现 write error: Invalid argument,通常是因为写入的追踪器名称不在 available_tracers 列表中,或者当前内核配置不支持该追踪器。请先检查 available_tracers 确认可用列表。
4.4 配置验证与常见问题
完成基础配置后,建议通过以下命令验证 ftrace 是否正常工作:
# 验证 tracefs 挂载
ls /sys/kernel/tracing/available_tracers
# 验证追踪器切换
echo function > /sys/kernel/tracing/current_tracer
cat /sys/kernel/tracing/current_tracer
# 验证追踪数据采集
echo 1 > /sys/kernel/tracing/tracing_on
sleep 1
echo 0 > /sys/kernel/tracing/tracing_on
cat /sys/kernel/tracing/trace | head -10
如果上述命令均正常执行,说明 ftrace 基础环境已就绪。下表列出常见问题及解决方案:
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
mount: tracefs already mounted |
tracefs 已挂载 | 直接使用 /sys/kernel/tracing 即可 |
available_tracers 只有 nop |
内核未开启 CONFIG_FUNCTION_TRACER |
重新编译内核,开启相关配置 |
写入 current_tracer 返回 Invalid argument |
追踪器名称错误或不可用 | 检查 available_tracers 确认正确名称 |
trace 文件为空 |
追踪未开启或缓冲区未刷新 | 确认 tracing_on = 1,且执行了追踪操作 |
| 权限不足 | 非 root 用户操作 | 使用 sudo 或以 root 身份执行 |
进阶提示: 在容器环境中,可能需要额外的
--privileged 标志或挂载 /sys/kernel/tracing 卷才能访问 tracefs。对于 Kubernetes 环境,可以通过 securityContext 设置 privileged: true 或添加 SYS_ADMIN 能力。