跟踪技术(ftrace / eBPF)

04-kernel-driver/18-debugging.md07-advanced/04-perf-profiling.md 的扩展。

一、ftrace 完整指南

1. 基础

mount -t tracefs none /sys/kernel/tracing
ls /sys/kernel/tracing

关键文件:
- current_tracer:当前 tracer
- available_tracers:可用 tracer
- tracing_on:1 = 开,0 = 关
- trace:当前 buffer
- trace_pipe:流式
- set_ftrace_filter:函数过滤白名单
- set_ftrace_notrace:黑名单
- set_graph_function:function_graph 目标

2. tracer 类型

Tracer 用途
nop 关闭
function 函数调用
function_graph 函数调用图
irqsoff 关中断时间
preemptoff 关抢占时间
preemptirqsoff 两者结合
wakeup 调度延迟
wakeup_rt 实时任务调度延迟
mmiotrace MMIO 访问
blk 块设备

3. function tracer

echo function > current_tracer
echo do_sys_open > set_ftrace_filter
echo 1 > tracing_on
ls
echo 0 > tracing_on
cat trace

4. function_graph

echo function_graph > current_tracer
echo do_sys_open > set_graph_function
echo 1 > tracing_on
ls
echo 0 > tracing_on
cat trace

输出:

3)               |  do_sys_open() {
3)               |    /* ... */
3)   0.234 us    |    do_filp_open();
3)               |  }

5. trace-cmd 工具

apt install trace-cmd kernelshark

trace-cmd record -p function -l do_sys_open ls
trace-cmd report

trace-cmd record -e all -p function_graph
trace-cmd start -p function -e sched:*
trace-cmd stop
trace-cmd extract
trace-cmd report

6. 自定义事件

ls /sys/kernel/tracing/events/syscalls/
echo 1 > /sys/kernel/tracing/events/syscalls/sys_enter_open/enable
echo 1 > /sys/kernel/tracing/events/syscalls/sys_exit_open/enable
cat trace

7. 内核模块自定义 tracepoint

// mydriver.c
#define CREATE_TRACE_POINTS
#include "trace_mydriver.h"

void my_function(int x)
{
    trace_my_event(x);
}

// trace_mydriver.h
#undef TRACE_SYSTEM
#define TRACE_SYSTEM mydriver

#if !defined(_TRACE_MYDRIVER_H) || defined(TRACE_HEADER_MULTI_READ)
#define _TRACE_MYDRIVER_H

#include <linux/tracepoint.h>

TRACE_EVENT(my_event,
    TP_PROTO(int x),
    TP_ARGS(x),
    TP_STRUCT__entry(__field(int, x)),
    TP_fast_assign(__entry->x = x),
    TP_printk("x=%d", __entry->x)
);

#endif

#include <trace/define_trace.h>

查看:

ls /sys/kernel/tracing/events/mydriver/

二、eBPF(进阶)

1. 能力

2. bpftrace 单行命令

# 看系统调用次数
bpftrace -e 'tracepoint:raw_syscalls:sys_enter { @[comm] = count(); }'

# 看 open 文件名
bpftrace -e 'kprobe:do_sys_open { printf("%s\n", argstr(1)); }'

# 看进程启动
bpftrace -e 'tracepoint:sched:sched_process_exec { printf("%s -> %s\n", args->prev_comm, args->filename); }'

# 看网络连接
bpftrace -e 'tracepoint:syscalls:sys_enter_connect { printf("connect by %s\n", comm); }'

3. bpftrace 脚本(.bt)

#!/usr/bin/bpftrace

kprobe:do_sys_open
{
    printf("pid %d (%s) open %s\n", pid, comm, argstr(1));
}

kretprobe:do_sys_open /retval < 0/
{
    printf("open failed: %d\n", retval);
}
chmod +x script.bt
sudo ./script.bt

4. BCC 工具集

opensnoop-bpfcc        # 所有 open()
execsnoop-bpfcc
tcpconnect-bpfcc
biolatency-bpfcc
runqlat-bpfcc
softirqs-bpfcc
hardirqs-bpfcc
profile-bpfcc          # CPU 火焰图生成
offcputime-bpfcc       # 阻塞时间

5. XDP(eXpress Data Path)

6. 嵌入式 eBPF

三、对比

工具 优点 缺点
ftrace 内置、零依赖 仅 Linux 内核
perf 强大、性能好 学习曲线
eBPF 强大、灵活 新工具
LTTng 跨 tracepoint、用户态 复杂
SystemTap 强大 不再主流
dtrace Solaris 血统 Linux 移植不完美

四、推荐工作流

1. perf top      → 发现热点
2. perf record   → 采样
3. 火焰图         → 直观展示
4. ftrace        → 函数级深度
5. bpftrace      → 复杂逻辑
6. 内核 printk   → 最终定位

五、嵌入式考虑