4. ftrace 文件系统:挂载 tracefs、熟悉 /sys/kernel/tracing/ 目录结构及关键文件
ftrace 的所有控制接口与跟踪数据输出都通过 tracefs 伪文件系统暴露给用户空间。正确挂载并理解 /sys/kernel/tracing/ 下的关键文件,是使用 ftrace 进行驱动调试的第一步。本章将详细讲解 tracefs 的挂载方式、目录结构以及每个核心文件的作用。
4.1 挂载 tracefs 文件系统
tracefs 通常会自动挂载在 /sys/kernel/tracing/ 路径下。如果该目录为空或不存在,则需要手动挂载。挂载方式有两种:
4.1.1 自动挂载(推荐)
大多数现代 Linux 发行版(内核版本 >= 3.10)在启动时通过 configfs 或 debugfs 自动挂载 tracefs。检查是否已挂载:
# 查看挂载点
mount | grep tracefs
# 典型输出:tracefs on /sys/kernel/tracing type tracefs (rw,nosuid,nodev,noexec,relatime)
4.1.2 手动挂载
如果自动挂载失败,可以手动挂载:
# 创建挂载点(如果不存在)
mkdir -p /sys/kernel/tracing
# 挂载 tracefs
mount -t tracefs nodev /sys/kernel/tracing
# 验证挂载
ls /sys/kernel/tracing/
调试提示: 如果使用
debugfs 旧接口(/sys/kernel/debug/tracing/),建议迁移到 /sys/kernel/tracing/。新接口更安全、更规范,且与 cgroup v2 兼容性更好。
4.2 /sys/kernel/tracing/ 目录结构总览
以下 SVG 展示了 /sys/kernel/tracing/ 的核心目录与文件结构,帮助建立整体认知:
4.3 关键文件详解
以下表格按功能分类,列出最常用的核心文件及其作用:
| 分类 | 文件名 | 读写 | 功能描述 |
|---|---|---|---|
| 控制 | current_tracer |
RW | 设置或查看当前使用的跟踪器(如 function、function_graph) |
tracing_on |
RW | 全局跟踪开关:写入 1 启用,0 暂停(不丢失已有数据) |
|
set_ftrace_filter |
RW | 白名单:只跟踪列表中指定的函数(支持通配符 *) |
|
| 数据 | trace |
RO | 以人类可读格式输出当前环形缓冲区中的跟踪数据 |
trace_pipe |
RO | 流式输出跟踪数据(阻塞读取,适合实时监控) | |
| 配置 | buffer_size_kb |
RW | 设置每个 CPU 的环形缓冲区大小(单位 KB,默认约 1400 KB) |
trace_clock |
RW | 选择时间戳时钟源:local、global、counter、uptime 等 |
|
options/ |
目录 | 包含多个开关文件,用于微调跟踪行为(如 sym-offset、stacktrace) |
|
| 函数跟踪 | available_filter_functions |
RO | 列出所有可被 ftrace 跟踪的函数(约数万个) |
set_graph_function |
RW | 在 function_graph 模式下,只显示指定函数的调用图 | |
max_graph_depth |
RW | 限制 function_graph 的调用深度(防止输出过深) |
4.4 核心文件操作示例
4.4.1 查看当前跟踪器状态
# 查看当前跟踪器
cat /sys/kernel/tracing/current_tracer
# 输出:nop (表示未启用任何跟踪器)
# 查看跟踪开关状态
cat /sys/kernel/tracing/tracing_on
# 输出:1 (表示跟踪已启用)
4.4.2 设置跟踪器并查看数据
# 设置 function_graph 跟踪器
echo function_graph > /sys/kernel/tracing/current_tracer
# 设置只跟踪 my_driver_function
echo my_driver_function > /sys/kernel/tracing/set_graph_function
# 读取跟踪数据(前 20 行)
head -20 /sys/kernel/tracing/trace
4.4.3 调整缓冲区大小
# 查看当前缓冲区大小(每个 CPU)
cat /sys/kernel/tracing/buffer_size_kb
# 输出:1408
# 设置为 4096 KB(4 MB)
echo 4096 > /sys/kernel/tracing/buffer_size_kb
# 验证
cat /sys/kernel/tracing/buffer_size_kb
# 输出:4096
注意事项:
- 缓冲区大小是 每个 CPU 独立 的,总内存占用 = buffer_size_kb × CPU 数量。
- 在嵌入式系统(如 256 MB RAM)中,建议将 buffer_size_kb 设为 512 或更小,避免 OOM。
- 修改
current_tracer会自动重置缓冲区,建议在修改前先保存数据。
4.5 常用选项文件(options/ 目录)
options/ 目录下包含多个开关文件,用于微调跟踪输出。以下是最常用的几个:
| 选项文件 | 作用 | 推荐场景 |
|---|---|---|
sym-offset |
在函数名后显示偏移量(如 my_func+0x4c/0x100) |
驱动调试时定位具体指令 |
stacktrace |
在每个跟踪事件后附加内核栈回溯 | 分析函数调用路径 |
funcgraph-proc |
在 function_graph 输出中显示进程名和 PID | 多进程/多线程驱动调试 |
funcgraph-duration |
显示每个函数的执行耗时(微秒级) | 性能瓶颈分析 |
funcgraph-overhead |
标记耗时过长的函数(用 ! 或 + 符号) |
快速定位慢函数 |
启用选项示例:
# 启用 sym-offset 和 stacktrace
echo 1 > /sys/kernel/tracing/options/sym-offset
echo 1 > /sys/kernel/tracing/options/stacktrace
# 禁用选项
echo 0 > /sys/kernel/tracing/options/funcgraph-duration
4.6 per_cpu 目录:按 CPU 隔离数据
per_cpu/ 目录下包含每个 CPU 的独立跟踪缓冲区,适合在多核系统中隔离分析:
# 查看 CPU 数量
ls /sys/kernel/tracing/per_cpu/
# 输出:cpu0 cpu1 cpu2 cpu3
# 查看 CPU0 的跟踪数据
cat /sys/kernel/tracing/per_cpu/cpu0/trace
# 查看 CPU0 的缓冲区大小
cat /sys/kernel/tracing/per_cpu/cpu0/buffer_size_kb
驱动调试实战建议:
- 在调试中断处理程序或 SMP 竞态问题时,优先使用
per_cpu/cpuX/trace按 CPU 隔离分析。 - 使用
trace_pipe替代trace进行实时监控:cat /sys/kernel/tracing/trace_pipe。 - 每次调试前先执行
echo > /sys/kernel/tracing/trace清空缓冲区,避免旧数据干扰。
4.7 本章小结
通过本章学习,应掌握以下核心知识点:
- 挂载 tracefs:自动挂载于
/sys/kernel/tracing/,手动挂载使用mount -t tracefs。 - 目录结构:控制类(
current_tracer、tracing_on)、数据类(trace、trace_pipe)、配置类(buffer_size_kb、options/)。 - 函数跟踪特有文件:
available_filter_functions、set_graph_function、max_graph_depth。 - 选项微调:通过
options/目录启用sym-offset、stacktrace、funcgraph-duration等。 - per_cpu 隔离:按 CPU 独立查看跟踪数据,适合多核驱动调试。