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 可进一步解析和可视化这些数据。

 

posted @ 2025-07-23 11:37  流水灯  阅读(49)  评论(0)    收藏  举报