3. 编译内核支持Ftrace:配置内核选项

Ftrace 作为内核内置的追踪基础设施,其功能依赖于内核编译时的配置选项。要使 Ftrace 可用,必须在 Linux 内核源码配置阶段启用相应的 CONFIG_* 选项。本章将详细讲解如何配置内核以完整支持 Ftrace,包括动态追踪、函数追踪器以及相关辅助功能。

3.1 核心配置选项概览

Ftrace 的功能由一组内核配置选项控制。下表列出了启用 Ftrace 所需的核心选项及其作用:

配置选项 依赖 功能描述 推荐设置
CONFIG_FTRACE 无 Ftrace 功能的全局开关,必须启用 y
CONFIG_FUNCTION_TRACER CONFIG_FTRACE 启用函数追踪器,允许追踪内核函数的进入和退出 y
CONFIG_DYNAMIC_FTRACE CONFIG_FUNCTION_TRACER 启用动态 Ftrace,允许在运行时动态启用/禁用追踪点,大幅降低性能开销 y
CONFIG_DYNAMIC_FTRACE_WITH_REGS CONFIG_DYNAMIC_FTRACE 在动态追踪点保存寄存器上下文,用于 kprobe 和函数参数读取 y
CONFIG_FUNCTION_GRAPH_TRACER CONFIG_FUNCTION_TRACER 启用函数图追踪器,以调用图形式显示函数调用关系 y
CONFIG_STACK_TRACER CONFIG_FTRACE 启用栈追踪器,用于记录内核栈使用情况 y
CONFIG_FTRACE_SYSCALLS CONFIG_FTRACE 启用系统调用追踪点,支持追踪系统调用事件 y
配置建议: 对于调试和故障排查场景,建议将上述所有选项均设置为 y(编译进内核)。动态 Ftrace 和寄存器保存功能对于降低追踪开销和获取详细参数至关重要。

3.2 配置流程与步骤

配置内核支持 Ftrace 的典型流程如下:

  1. 进入内核源码目录:cd /usr/src/linux 或你的内核源码路径。
  2. 加载现有配置:make oldconfig 或 make defconfig。
  3. 启动配置界面:make menuconfig(推荐)或 make xconfig。
  4. 导航至 Ftrace 选项:进入 Kernel hacking → Tracers。
  5. 启用核心选项:按空格键选中以下选项:
    • Ftrace
    • Kernel Function Tracer
    • Enable/disable function tracing dynamically
    • Enable dynamic ftrace with register saving
    • Kernel Function Graph Tracer
    • Trace syscalls
  6. 保存并退出:选择 Save,退出配置界面。
  7. 编译内核:make -j$(nproc)。
  8. 安装内核:make modules_install install。
注意: 启用 CONFIG_DYNAMIC_FTRACE_WITH_REGS 可能会略微增加内核映像大小,但对于使用 kprobe 和读取函数参数是必需的。在嵌入式或资源受限系统中,请评估此选项的影响。

3.3 动态Ftrace的工作原理

动态 Ftrace 是 Ftrace 的核心特性之一,它通过在编译时插入桩(nop 指令)并在运行时动态修改这些指令来实现低开销的追踪。下图展示了动态 Ftrace 的工作流程:

动态Ftrace工作原理图 动态Ftrace工作原理 编译阶段 插入 nop 指令桩 内核初始化 注册 ftrace_ops 运行时修改 nop → call ftrace_caller 动态修改细节 • 当用户启用某个函数的追踪时,Ftrace 将对应地址的 nop 指令 修改为 call ftrace_caller 指令。 • 当用户禁用追踪时,将 call 指令恢复为 nop,实现零开销。 函数调用路径对比 未追踪:函数直接执行 nop 已追踪:跳转到 ftrace_caller

3.4 验证Ftrace是否启用

内核启动后,可以通过以下方法验证 Ftrace 是否已正确配置并启用:

  • 检查 debugfs 挂载:mount | grep debugfs,确保 debugfs 已挂载到 /sys/kernel/debug。
  • 检查 tracing 目录:ls /sys/kernel/debug/tracing/,应包含 available_tracers、current_tracer、trace 等文件。
  • 查看可用追踪器:cat /sys/kernel/debug/tracing/available_tracers,输出应包含 function 和 function_graph。
  • 检查内核配置:cat /proc/config.gz | gunzip | grep CONFIG_FTRACE,确认相关选项为 y。
快速验证命令:
# 挂载 debugfs(如果未自动挂载)
mount -t debugfs none /sys/kernel/debug

# 查看可用追踪器
cat /sys/kernel/debug/tracing/available_tracers

# 预期输出示例:
# function function_graph nop

3.5 常见配置问题与排查

问题现象 可能原因 解决方案
available_tracers 为空或只有 nop CONFIG_FUNCTION_TRACER 未启用 重新配置内核,启用 CONFIG_FUNCTION_TRACER
动态追踪不生效,修改 set_ftrace_filter 无反应 CONFIG_DYNAMIC_FTRACE 未启用 启用 CONFIG_DYNAMIC_FTRACE 并重新编译
使用 kprobe 时无法读取函数参数 CONFIG_DYNAMIC_FTRACE_WITH_REGS 未启用 启用该选项,确保寄存器上下文被保存
系统调用追踪无输出 CONFIG_FTRACE_SYSCALLS 未启用 启用该选项,并检查 events/syscalls 目录

3.6 配置选项依赖关系图

以下 SVG 图展示了 Ftrace 核心配置选项之间的依赖关系,帮助理解哪些选项是基础,哪些是可选增强:

Ftrace配置选项依赖关系 Ftrace 配置选项依赖关系 CONFIG_FTRACE CONFIG_FUNCTION_TRACER CONFIG_STACK_TRACER CONFIG_DYNAMIC_FTRACE CONFIG_FUNCTION_GRAPH_TRACER CONFIG_DYNAMIC_FTRACE_WITH_REGS CONFIG_FTRACE_SYSCALLS (可选,依赖 FTRACE)

3.7 小结

正确配置内核编译选项是使用 Ftrace 的前提。核心要点包括:

  • 必须启用 CONFIG_FTRACE 和 CONFIG_FUNCTION_TRACER 作为基础。
  • 强烈建议启用 CONFIG_DYNAMIC_FTRACE 和 CONFIG_DYNAMIC_FTRACE_WITH_REGS 以获得低开销和参数读取能力。
  • 根据调试需求,可选启用 CONFIG_FUNCTION_GRAPH_TRACER、CONFIG_STACK_TRACER 和 CONFIG_FTRACE_SYSCALLS。
  • 配置完成后,通过 /sys/kernel/debug/tracing/ 目录验证功能是否生效。

完成内核配置和编译后,即可进入下一阶段:使用 Ftrace 进行实际的函数追踪和故障排查。