ftrace

目录

ftrace 是内核内置的追踪框架——不需要额外模块,不需要重新编译,生产环境可用。

一、先看图

flowchart TD
    APP[用户态<br/>trace-cmd / echo] -->|控制| TRACEFS[tracefs<br/>/sys/kernel/debug/tracing]
    TRACEFS --> FTRACE[ftrace 框架]
    FTRACE --> FT[function tracer<br/>mcount/fentry]
    FTRACE --> FG[function_graph<br/>调用图]
    FTRACE --> TP[tracepoints<br/>静态探针]
    FTRACE --> HIST[histogram<br/>触发器]
    FT --> RING[ring buffer<br/>per-CPU]
    FG --> RING
    TP --> RING

    classDef ctrl fill:#388bfd22,stroke:#388bfd,color:#adbac7;
    classDef trace fill:#3fb95022,stroke:#3fb950,color:#adbac7;
    class APP,TRACEFS ctrl
    class FTRACE,FT,FG,TP,HIST,RING trace

二、基本原理

2.1 mcount / fentry

GCC 编译内核函数时插入 mcount 调用(或 -fpatchable-function-entry 插入 nop)。

function_entry:
    nop nop nop nop nop   # 5 字节 nop(x86)
    ...

启用 ftrace 时 → 动态 patch nop 为 call → 跳转到追踪代码。

2.2 零 overhead

未启用时 → nop → 无开销。

三、function tracer

echo function > /sys/kernel/debug/tracing/current_tracer
echo do_sys_openat2 > /sys/kernel/debug/tracing/set_ftrace_filter
echo 1 > /sys/kernel/debug/tracing/tracing_on
cat /sys/kernel/debug/tracing/trace

输出每次函数调用的 CPU、时间戳、进程。

四、function_graph

echo function_graph > /sys/kernel/debug/tracing/current_tracer
cat /sys/kernel/debug/tracing/trace
 0)               |  do_sys_openat2() {
 0)   0.892 us    |    getname();
 0)               |    do_filp_open() {
 0)   1.234 us    |      path_openat();
 0)   2.567 us    |    }
 0)   4.123 us    |  }

展示调用栈和耗时 → 性能分析利器。

五、Tracepoints

静态探针,编译时定义:

// include/trace/events/sched.h
TRACE_EVENT(sched_switch, ...)
echo 1 > /sys/kernel/debug/tracing/events/sched/sched_switch/enable
cat /sys/kernel/debug/tracing/trace

tracepoints 比函数追踪更稳定 → 不依赖函数名。

六、trace-cmd

trace-cmd record -p function_graph -g do_sys_openat2
trace-cmd report | head -30

# 实时查看
trace-cmd start -p function_graph -g vfs_read
trace-cmd show
trace-cmd stop

七、Histogram 触发器

echo 'hist:key=common_pid:val=hitcount:sort=hitcount.descending' > \
    /sys/kernel/debug/tracing/events/sched/sched_switch/trigger
cat /sys/kernel/debug/tracing/events/sched/sched_switch/hist

内核空间聚合 → 不需要把每条 trace 拷贝到用户态。

八、Synthetic Events

组合多个事件:

echo 'wakeup_lat s32 lat' > /sys/kernel/debug/tracing/synthetic_events
echo 'hist:keys=pid:ts0=common_timestamp.usecs' > \
    /sys/kernel/debug/tracing/events/sched/sched_waking/trigger
echo 'hist:keys=next_pid:lat=common_timestamp.usecs-$ts0:onmatch(sched.sched_waking).wakeup_lat($lat)' > \
    /sys/kernel/debug/tracing/events/sched/sched_switch/trigger

九、观察

# 可用 tracer
cat /sys/kernel/debug/tracing/available_tracers
# 可用 tracepoints
cat /sys/kernel/debug/tracing/available_events | wc -l
# 可追踪函数
cat /sys/kernel/debug/tracing/available_filter_functions | wc -l
# 当前状态
cat /sys/kernel/debug/tracing/tracing_on

十、小结


参考文献

工具


上一篇:稳定 ABI 下一篇:perf 子系统

文章导航

分类入口
os
标签入口
#ftrace#tracepoint#trace-cmd#function-graph#fentry

读完这篇,下一步读什么

优先读同系列或同问题的下一篇,把单篇消费变成主题集群。


By .