4. Ftrace基础使用:挂载tracefs、查看可用tracer、切换tracer、读取trace输出
Ftrace 是 Linux 内核内置的跟踪框架,其用户态接口通过 tracefs 虚拟文件系统暴露。本章将带领你完成 Ftrace 的初始化配置与基本操作流程,包括挂载文件系统、查看可用跟踪器、切换跟踪器以及读取跟踪输出。这些操作是后续深入分析函数调用链与中断上下文的基础。
4.1 挂载 tracefs
tracefs 通常自动挂载于 /sys/kernel/tracing,但在某些发行版中需要手动挂载。挂载后,所有 Ftrace 控制文件与输出文件均位于该目录下。
挂载命令
# 检查是否已挂载
mount | grep tracefs
# 手动挂载 tracefs 到标准路径
mount -t tracefs tracefs /sys/kernel/tracing
# 或挂载到自定义路径(不推荐)
mount -t tracefs tracefs /mytrace
验证挂载
挂载成功后,/sys/kernel/tracing 目录下应包含以下关键文件与目录:
| 文件/目录 | 说明 |
|---|---|
available_tracers |
列出当前内核支持的所有跟踪器 |
current_tracer |
当前激活的跟踪器名称(可写) |
trace |
跟踪输出(人类可读格式) |
tracing_on |
跟踪开关(1=开启,0=关闭) |
set_ftrace_filter |
函数过滤白名单 |
set_ftrace_notrace |
函数过滤黑名单 |
提示: 如果
/sys/kernel/tracing 不存在,请确认内核编译时启用了 CONFIG_TRACING 和 CONFIG_TRACEFS。使用 zcat /proc/config.gz | grep TRACING 检查内核配置。
4.2 查看可用 tracer
通过读取 available_tracers 文件,可以获取当前内核支持的所有跟踪器列表。不同内核版本或配置下,可用跟踪器可能有所不同。
cat /sys/kernel/tracing/available_tracers
典型输出示例:
hwlat blk mmiotrace function_graph wakeup_dl wakeup_rt wakeup function nop
常用跟踪器说明
| 跟踪器名称 | 用途 | 适用场景 |
|---|---|---|
| nop | 空跟踪器(不执行任何跟踪) | 关闭跟踪、重置状态 |
| function | 跟踪内核函数调用(仅记录函数入口) | 函数调用统计、调用频次分析 |
| function_graph | 跟踪函数调用图(入口+出口,显示调用深度) | 函数调用链分析、延迟定位 |
| wakeup | 跟踪进程唤醒延迟 | 实时性分析、调度延迟测量 |
| wakeup_rt | 跟踪实时进程唤醒延迟 | RT 任务调度性能 |
| wakeup_dl | 跟踪 Deadline 调度类唤醒延迟 | SCHED_DEADLINE 分析 |
| hwlat | 检测硬件延迟(SMIs、NMIs 等) | 硬件干扰排查 |
| blk | 块设备 I/O 跟踪 | 存储性能分析 |
| mmiotrace | MMIO 内存映射 I/O 跟踪 | 驱动调试、硬件寄存器访问跟踪 |
关键点:
function_graph 是函数调用链分析的核心跟踪器,它不仅能记录函数进入和退出,还能通过缩进直观展示调用深度。本课程后续章节将大量使用该跟踪器。
4.3 切换 tracer
通过向 current_tracer 文件写入跟踪器名称,即可动态切换当前激活的跟踪器。切换前建议先关闭跟踪(tracing_on = 0),以避免数据混乱。
切换步骤
- 关闭跟踪:
echo 0 > /sys/kernel/tracing/tracing_on - 清空缓冲区(可选):
echo > /sys/kernel/tracing/trace - 写入跟踪器名称:
echo function_graph > /sys/kernel/tracing/current_tracer - 验证切换:
cat /sys/kernel/tracing/current_tracer - 开启跟踪:
echo 1 > /sys/kernel/tracing/tracing_on
# 完整切换示例:切换到 function_graph
echo 0 > /sys/kernel/tracing/tracing_on
echo > /sys/kernel/tracing/trace
echo function_graph > /sys/kernel/tracing/current_tracer
cat /sys/kernel/tracing/current_tracer
echo 1 > /sys/kernel/tracing/tracing_on
注意: 写入
current_tracer 时,跟踪器名称必须与 available_tracers 中的名称完全一致(包括大小写)。如果写入无效名称,系统会静默失败并保留当前跟踪器。建议写入后立即 cat 验证。
4.4 读取 trace 输出
跟踪数据通过 trace 文件以人类可读的文本格式输出。读取该文件即可获取当前缓冲区中的所有跟踪记录。
基本读取命令
# 读取全部跟踪输出
cat /sys/kernel/tracing/trace
# 实时跟踪(类似 tail -f)
cat /sys/kernel/tracing/trace_pipe
输出字段解析(以 function_graph 为例)
# tracer: function_graph
#
# CPU DURATION FUNCTION CALLS
# | | | | | | |
0) 1.234 us | __fdget();
0) 2.345 us | __fget_light();
0) | __fget_files() {
0) 0.567 us | __rcu_read_lock();
0) 0.890 us | __rcu_read_unlock();
0) 3.802 us | }
| 字段 | 说明 |
|---|---|
| CPU | 执行该函数的 CPU 编号 |
| DURATION | 函数执行耗时(仅 function_graph 在函数退出时显示) |
| FUNCTION CALLS | 函数调用链,缩进表示调用深度,{ 表示函数入口,} 表示函数出口 |
| # 注释行 | 以 # 开头的行为元信息,包括当前跟踪器名称、字段标题等 |
trace_pipe vs trace
| 特性 | trace | trace_pipe |
|---|---|---|
| 读取方式 | 一次性读取全部缓冲区 | 阻塞读取,持续输出新数据 |
| 缓冲区影响 | 读取后数据保留 | 读取后数据从缓冲区移除 |
| 适用场景 | 离线分析、快照查看 | 实时监控、流式处理 |
技巧: 使用
trace_pipe 进行实时跟踪时,可以配合 Ctrl+C 中断。如果希望同时保存输出,可以使用 cat /sys/kernel/tracing/trace_pipe > trace.log 重定向到文件。
4.5 完整操作示例
以下是一个完整的操作序列,演示从挂载 tracefs 到读取 function_graph 输出的全过程:
# 1. 挂载 tracefs(如未自动挂载)
mount -t tracefs tracefs /sys/kernel/tracing
# 2. 查看可用跟踪器
cat /sys/kernel/tracing/available_tracers
# 3. 切换到 function_graph
echo 0 > /sys/kernel/tracing/tracing_on
echo > /sys/kernel/tracing/trace
echo function_graph > /sys/kernel/tracing/current_tracer
echo 1 > /sys/kernel/tracing/tracing_on
# 4. 等待几秒,产生一些内核活动
# 5. 读取跟踪输出
cat /sys/kernel/tracing/trace | head -50
# 6. 恢复为 nop 跟踪器
echo 0 > /sys/kernel/tracing/tracing_on
echo nop > /sys/kernel/tracing/current_tracer
总结: 本章完成了 Ftrace 的四个基础操作——挂载、查看、切换、读取。掌握这些操作后,你已经具备了使用 Ftrace 进行内核跟踪的基本能力。下一阶段将深入
function_graph 的过滤与配置,实现精准的函数调用链捕获。