linux ftrace 介绍
实现原理
实现原理基于动态插桩技术与环形缓冲区管理
动态插桩
ftrace 的核心机制是在内核编译阶段通过 GCC 的 -pg 选项,在每个函数的入口处插入对 mcount 函数的调用,这些插桩点地址会被收集到内核的 __mcount_loc 段中,形成一个全局函数地址列表。
mcount会根据当前配置的跟踪器类型,记录函数调用信息(如函数名、调用时间、调用栈等)到环形缓冲区。
内核初始化阶段,ftrace 会遍历 __mcount_loc 段,将所有插桩点的 call mcount 指令替换为 nop(无操作指令),此时跟踪功能默认关闭,性能开销几乎为零。
func_a: push %rbp mov %rsp,%rbp call mcount ; 插桩点:记录 func_a 的调用 call func_b ; 调用 func_b pop %rbp ret func_a: push %rbp mov %rsp,%rbp nop ; 原 call mcount 被替换 call func_b pop %rbp ret
当用户通过 debugfs 启用特定跟踪器(如 function 或 function_graph)时,ftrace 会动态将目标函数的 nop 指令替换回 call mcount,激活跟踪功能。
环形缓冲区
每个 CPU 拥有独立的环形缓冲区,避免多核间的锁竞争。缓冲区大小可通过 buffer_size_kb 文件配置,总大小为 buffer_size_kb × CPU 数量。
当函数调用发生时,mcount 函数将跟踪信息(如函数地址、时间戳、调用关系等)写入当前 CPU 的环形缓冲区。
用户可通过 debugfs 下的 trace 文件读取缓冲区内容,或通过 trace_pipe 管道文件实时获取跟踪流。工具如 trace-cmd 或 KernelShark 可进一步解析和可视化这些数据。

浙公网安备 33010602011771号