土法炼钢兴趣小组的算法知识备份

【操作系统百科】ftrace

文章导航

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

目录

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 子系统

同主题继续阅读

把当前热点继续串成多页阅读,而不是停在单篇消费。

2026-04-27 · os

【操作系统百科】内存回收

Linux 内存回收是 VM 最复杂的子系统之一。本文讲 active/inactive LRU、kswapd 与 direct reclaim、watermark 三线、swappiness 的真实含义、MGLRU 改造、memcg 回收与 PSI。

2026-04-28 · os

【操作系统百科】交换

swap 还值得开吗?本文讲 swap area 基础、swap cache、zram 压缩内存、zswap 前端压缩池、swappiness 的真实含义、容器里的 swap 策略,以及为什么现代 Android 全靠 zram 不靠磁盘。

2026-05-03 · os

【操作系统百科】Slab/SLUB 分配器

buddy 只管页粒度(4K+),内核大多数对象只有几十到几百字节。slab/SLUB 在 buddy 之上做对象级缓存。本文讲 slab 历史、SLUB 接手、SLOB 退场、kmem_cache、per-CPU cache、KASAN 集成。

2026-05-07 · os

【操作系统百科】用户态分配器

glibc malloc、tcmalloc、jemalloc、mimalloc 各有哲学。本文讲 arena、thread cache、size class、madvise 返还策略、碎片与 RSS 膨胀、如何根据负载选分配器。


By .