4. ftrace的挂载与接口:debugfs/tracefs的挂载,核心文件节点详解

ftrace 作为内核内置的跟踪器,其用户态交互接口主要通过虚拟文件系统(VFS)暴露。正确挂载 debugfs 或 tracefs 是使用 ftrace 的第一步。本章将详细解析挂载流程、核心文件节点的功能及其在异常定位中的实际用途。

4.1 文件系统挂载:debugfs 与 tracefs

早期内核版本中,ftrace 完全依赖于 debugfs。从内核 3.x 开始,ftrace 拥有了独立的 tracefs,专门用于管理跟踪相关文件,避免了与 debugfs 中其他调试信息的混杂。

特性 debugfs tracefs
挂载点 /sys/kernel/debug /sys/kernel/tracing
依赖 需内核开启 CONFIG_DEBUG_FS 需内核开启 CONFIG_TRACING
文件内容 包含所有调试信息(gpio、clk、regmap 等) 仅包含 ftrace 相关接口文件
推荐用法 兼容旧脚本,或需要同时访问其他 debugfs 节点 新系统首选,结构清晰,权限管理更独立
挂载命令速查:
# 挂载 tracefs(推荐)
mount -t tracefs tracefs /sys/kernel/tracing

# 挂载 debugfs(兼容方式)
mount -t debugfs debugfs /sys/kernel/debug
# 此时 ftrace 文件位于 /sys/kernel/debug/tracing

挂载成功后,所有 ftrace 控制文件将出现在 /sys/kernel/tracing/ 目录下。如果使用 debugfs,则路径为 /sys/kernel/debug/tracing/。以下所有接口说明均以 /sys/kernel/tracing/ 为基准。

4.2 核心文件节点详解

ftrace 的接口文件数量众多,但异常定位中最常用的核心节点不超过 10 个。下面按照“配置 -> 过滤 -> 启停 -> 读取”的流程逐一解析。

4.2.1 available_tracers:可用跟踪器列表

该文件为只读,列出当前内核编译支持的跟踪器类型。读取该文件可以快速确认内核是否包含了所需的跟踪功能。

# cat /sys/kernel/tracing/available_tracers
function_graph function nop

常见跟踪器说明:

  • nop:空跟踪器,不记录任何事件,用于关闭跟踪。
  • function:函数调用跟踪器,记录每个内核函数的调用入口。
  • function_graph:函数调用图跟踪器,记录函数的调用链、嵌套深度和执行时间。
诊断价值: 如果 function_graph 未出现在列表中,说明内核未开启 CONFIG_FUNCTION_GRAPH_TRACER,此时无法使用函数调用图功能进行异常定位。

4.2.2 current_tracer:当前激活的跟踪器

读写文件,用于设置或查询当前正在使用的跟踪器。写入 function_graph 即可激活函数调用图跟踪。

# 设置当前跟踪器为 function_graph
echo function_graph > /sys/kernel/tracing/current_tracer

# 验证设置
# cat /sys/kernel/tracing/current_tracer
function_graph

4.2.3 set_ftrace_filter:函数过滤白名单

这是异常定位中最强大的过滤接口。通过写入函数名或通配符,可以精确控制哪些函数被跟踪,从而大幅降低跟踪噪声。

操作 命令示例 效果
添加单个函数 echo do_sys_open > set_ftrace_filter 仅跟踪 do_sys_open
添加通配符 echo 'ext4_*' > set_ftrace_filter 跟踪所有以 ext4_ 开头的函数
追加过滤 echo do_sys_open >> set_ftrace_filter 在已有过滤列表中添加新函数
清空过滤 echo > set_ftrace_filter 移除所有过滤,跟踪所有函数(慎用)
性能警告: 如果不设置过滤,function_graph 会跟踪内核中所有函数的调用,导致系统严重卡顿甚至触发 hung task 检测。在异常定位时,务必先通过 set_ftrace_filter 缩小跟踪范围。

4.2.4 set_ftrace_notrace:函数黑名单

与 set_ftrace_filter 相反,该文件用于排除不需要跟踪的函数。常用于跳过一些高频调用函数(如 __do_softirq、ktime_get),以减少跟踪数据量。

# 排除 ktime_get 和本地时钟中断处理函数
echo 'ktime_get' > set_ftrace_notrace
echo 'hrtimer_interrupt' >> set_ftrace_notrace

4.2.5 trace:跟踪输出缓冲区

只读文件,以人类可读的文本格式输出当前跟踪缓冲区的内容。这是异常定位时最常查看的文件。

# cat /sys/kernel/tracing/trace
# tracer: function_graph
#
# CPU  DURATION                  FUNCTION CALLS
# |     |   |                     |   |   |   |
 0)   0.125 us    |  do_sys_open();
 0)   0.250 us    |    get_unused_fd_flags();
 0)   0.375 us    |    do_filp_open();
 0)   0.500 us    |      path_openat();
 0)   0.625 us    |        get_empty_filp();
 0)   1.000 us    |        __alloc_file();
 0)   0.125 us    |        mnt_want_write();
 0)   0.250 us    |        do_dentry_open();
 0)   0.375 us    |          ext4_file_open();
 0)   0.500 us    |          generic_file_open();
 0)   0.625 us    |        mnt_drop_write();
 0)   0.750 us    |        fd_install();
 0)   1.500 us    |      } /* path_openat */
 0)   2.000 us    |    } /* do_filp_open */
 0)   2.500 us    |  } /* do_sys_open */

4.2.6 tracing_on:跟踪总开关

写入 0 或 1 控制跟踪的启停。与 current_tracer 不同,tracing_on 只控制数据是否写入缓冲区,而不卸载跟踪器。

# 停止跟踪(保留缓冲区内容)
echo 0 > /sys/kernel/tracing/tracing_on

# 读取当前缓冲区
cat /sys/kernel/tracing/trace

# 清空缓冲区并重新开始跟踪
echo 0 > /sys/kernel/tracing/trace
echo 1 > /sys/kernel/tracing/tracing_on

4.2.7 trace_options:跟踪选项配置

通过读写该文件,可以调整跟踪输出的格式和内容。异常定位中常用的选项包括:

  • funcgraph-proc:在输出中显示进程名和 PID。
  • funcgraph-duration:显示函数执行耗时(默认开启)。
  • funcgraph-abstime:显示绝对时间戳。
  • funcgraph-overhead:标记耗时过长的函数。
# 启用进程信息显示
echo funcgraph-proc > /sys/kernel/tracing/trace_options

# 启用绝对时间戳
echo funcgraph-abstime >> /sys/kernel/tracing/trace_options

4.3 核心接口工作流程

下图展示了 ftrace 核心接口在异常定位中的协作关系:

ftrace 核心接口工作流程 用户空间操作(echo / cat) available_tracers (查询可用跟踪器) current_tracer (激活 function_graph) trace_options (配置输出格式) set_ftrace_filter (白名单:只跟踪目标函数) set_ftrace_notrace (黑名单:排除高频函数) tracing_on = 1 (开始跟踪数据采集) 内核 ftrace 引擎(动态插桩) trace (读取函数调用图与耗时数据)

4.4 实战:一次完整的异常定位配置序列

假设我们需要定位 ext4_file_open 函数在打开文件时的调用链和耗时,完整的配置序列如下:

# 1. 挂载 tracefs(如果尚未挂载)
mount -t tracefs tracefs /sys/kernel/tracing

# 2. 设置跟踪器为 function_graph
echo function_graph > /sys/kernel/tracing/current_tracer

# 3. 配置输出选项:显示进程名和绝对时间戳
echo funcgraph-proc > /sys/kernel/tracing/trace_options
echo funcgraph-abstime >> /sys/kernel/tracing/trace_options

# 4. 设置过滤:只跟踪 ext4_file_open 及其子调用
echo ext4_file_open > /sys/kernel/tracing/set_ftrace_filter

# 5. 清空旧缓冲区
echo 0 > /sys/kernel/tracing/trace

# 6. 确保跟踪已启动
echo 1 > /sys/kernel/tracing/tracing_on

# 7. 执行目标操作(例如打开一个 ext4 文件系统上的文件)
# 此处为模拟操作,实际场景中由应用程序触发
# 8. 停止跟踪
echo 0 > /sys/kernel/tracing/tracing_on

# 9. 读取跟踪结果
cat /sys/kernel/tracing/trace
关键点: 步骤 4 的过滤设置是性能和安全的关键。如果不设置过滤,function_graph 会尝试跟踪所有内核函数,导致系统响应变慢,甚至触发内核软锁检测(soft lockup)。在异常定位时,始终遵循“先过滤,后跟踪”的原则。

4.5 接口文件速查表

文件节点 访问权限 核心作用 异常定位中的典型用途
available_tracers 只读 列出支持的跟踪器 确认 function_graph 是否可用
current_tracer 读写 设置/查询当前跟踪器 激活 function_graph
set_ftrace_filter 读写 函数白名单过滤 缩小跟踪范围,聚焦可疑函数
set_ftrace_notrace 读写 函数黑名单过滤 排除高频干扰函数
trace 只读 输出跟踪缓冲区 查看函数调用图与耗时
tracing_on 读写 跟踪启停开关 控制数据采集的起止
trace_options 读写 配置输出格式 添加进程名、时间戳等信息