ftrace
ftrace 是 Linux 内核中功能最强大且最灵活的内核级跟踪工具之一,用于分析函数调用、性能瓶颈、调度延迟、中断处理等问题。下面我们从 原理角度 对 ftrace 进行全面分析。
ftrace 简介
- ftrace 是 Linux 内核从 2.6.27 开始引入的功能。
- 它可以在运行时 动态追踪内核函数调用路径、分析时延、检查中断处理情况。
- 和 perf 不同,它是 内核原生集成 的跟踪框架。
核心组件与原理
- 核心模块结构
kernel/trace/
├── trace.c <- 核心框架
├── trace_output.c <- 跟踪日志输出格式
├── trace_functions.c <- function tracer
├── trace_irqsoff.c <- irqsoff tracer
├── trace_sched_wakeup.c<- sched tracer
└── ftrace.c <- 与 arch 无关的主要实现
- 跟踪机制原理
ftrace 的核心是 函数入口处打桩(patching),它依赖如下两种技术:
(1) 动态函数打桩(Function Tracing)
-
原理:
- Linux 编译时使用
-pg参数(即CONFIG_FUNCTION_TRACER=y)来在每个函数开头插入调用mcount()的指令。 - 编译后的二进制中,所有函数头部都会有类似如下代码(以 x86 为例):
call mcount - Linux 编译时使用
-
启用 ftrace 后,内核会将这些
mcount替换为跳转到 tracer 的钩子函数,如:
call ftrace_caller
- 这就允许内核在每次函数调用时调用我们自定义的钩子。
(2) 动态修改代码(code patching)
- 在运行时将
call mcount替换为nop(禁用 tracing)或替换为跳转到 tracer。 - 使用
ftrace_make_nop()和ftrace_make_call()进行 patch。 - 在安全性上,通过
stop_machine()来暂停所有 CPU 后 patch,避免并发问题。
- ftrace 关键函数
| 函数名 | 作用 |
|---|---|
ftrace_regs_caller | 统一的调用接口,用于保存上下文 |
ftrace_ops | 跟踪回调结构体,每个 tracer 注册一个 |
register_ftrace_function() | 注册一个 ftrace_ops |
ftrace_update_ftrace_func() | 更新 hook 的函数入口 |
常用 Tracer 类型及其实现
- function tracer
- 打印所有函数的调用路径。
- 配合
filter使用可指定跟踪哪些函数。 - 实现位于
kernel/trace/trace_functions.c
- function_graph tracer
- 显示函数调用图(带层次结构与返回时间)。
- 利用
return trampoline技术实现记录函数返回点。 - 利用
prepare_ftrace_return()修改返回地址为return_to_handler()。
- irqsoff / preemptoff tracer
- 检测某些代码段关闭中断(irq)或禁止抢占(preempt)持续时间是否过长。
- 用于定位实时性问题。
- 实现位于
kernel/trace/trace_irqsoff.c
- sched tracer
- 跟踪调度器行为,如上下文切换、唤醒延迟。
- 对实时分析尤其重要。
调试接口与使用方法
ftrace 的运行时接口全部暴露在:
/sys/kernel/debug/tracing/
常用文件说明
| 文件名 | 功能 |
|---|---|
current_tracer | 设置当前 tracer 类型 |
available_tracers | 查看支持的 tracer |
trace | 当前的 trace 结果 |
set_ftrace_filter | 指定需要 hook 的函数 |
set_ftrace_notrace | 指定不要跟踪的函数 |
使用示例:
# 启用 function tracer
echo function > /sys/kernel/debug/tracing/current_tracer
# 仅跟踪 do_sys_open
echo do_sys_open > /sys/kernel/debug/tracing/set_ftrace_filter
# 查看 trace
cat /sys/kernel/debug/tracing/trace
性能优化与开销控制
- 默认不启用 ftrace,不影响系统性能。
- nop tracer 等于关闭状态,几乎没有开销。
- 启用 function_graph 时会对每次函数调用和返回都产生额外开销。
开销控制手段:
- 只启用必要函数过滤:set_ftrace_filter
- 使用静态追踪点(tracepoints)替代通用 tracer
- 使用 event tracing 精细控制要观察的内核事件
与其他 tracing 技术对比
| 技术 | 优点 | 缺点 |
|---|---|---|
| ftrace | 原生、效率高、无用户空间依赖 | 功能较底层 |
| perf | 用户态工具丰富、统计强大 | 比 ftrace 稍慢 |
| eBPF | 可动态加载程序、灵活性高 | 写法复杂、需要新内核 |
| kprobe | 动态追踪任意内核符号 | 稍慢,开销略大 |
架构支持
- 支持 x86、ARM、RISC-V 等主流架构。
- 每个架构需实现 arch_ftrace_update_code() 和 prepare_ftrace_return() 等函数。
典型应用场景
- 函数调用跟踪(function tracer)
- 调度延迟诊断(sched, irqsoff tracer)
- 内核事件分析(event tracing)
- 动态 debug 与性能分析
- 与 trace-cmd / KernelShark 配合图形化分析
理解
ftrace 作为 Linux 内核中的“瑞士军刀”级调试工具,其核心机制是通过 函数打桩 + 动态 patch 来实现低开销的内核级追踪。理解其原理不仅有助于深入掌握 Linux 内核架构,还可以在实际性能调优、Bug 分析中发挥巨大作用。
65

被折叠的 条评论
为什么被折叠?



