eunomia-bpf 项目中的 bpftrace 快速入门教程
2025-07-10 02:09:41作者:余洋婵Anita
概述
本教程将带领读者通过 12 个简洁的示例快速掌握 bpftrace 的核心用法。bpftrace 是一个强大的 Linux 动态追踪工具,可以用于性能分析、故障排查和系统行为观察。每个示例都展示了不同的 bpftrace 功能,从基础概念到高级应用逐步深入。
基础概念
在开始之前,我们需要了解几个关键概念:
- 探针(Probe):bpftrace 的观测点,用于捕获事件数据
- 动作(Action):当探针触发时执行的操作
- 映射(Map):用于存储和汇总数据的特殊变量类型
- 过滤器(Predicate):决定是否执行动作的条件表达式
12个核心示例
1. 列出可用探针
bpftrace -l 'tracepoint:syscalls:sys_enter_*'
这个命令列出所有可用的探针,支持通配符匹配。这是探索系统可观测性的第一步。
2. Hello World 示例
bpftrace -e 'BEGIN { printf("hello world\n"); }'
最简单的 bpftrace 程序,演示了 BEGIN 特殊探针的用法,它在程序开始时触发。
3. 跟踪文件打开操作
bpftrace -e 'tracepoint:syscalls:sys_enter_openat { printf("%s %s\n", comm, str(args.filename)); }'
这个示例展示了如何跟踪系统中的文件打开操作,输出进程名和文件名。
4. 按进程统计系统调用次数
bpftrace -e 'tracepoint:raw_syscalls:sys_enter { @[comm] = count(); }'
使用映射和 count() 函数统计各进程的系统调用次数。
5. read() 调用字节数分布
bpftrace -e 'tracepoint:syscalls:sys_exit_read /pid == 18644/ { @bytes = hist(args.ret); }'
通过直方图展示特定进程 read() 调用返回的字节数分布。
6. 内核动态追踪 read() 字节数
bpftrace -e 'kretprobe:vfs_read { @bytes = lhist(retval, 0, 2000, 200); }'
使用 kretprobe 对内核函数 vfs_read() 进行动态追踪,分析其返回值分布。
7. 测量 read() 操作耗时
bpftrace -e 'kprobe:vfs_read { @start[tid] = nsecs; } kretprobe:vfs_read /@start[tid]/ { @ns[comm] = hist(nsecs - @start[tid]); delete(@start[tid]); }'
这个复杂示例展示了如何测量 read() 操作的耗时,并使用线程ID作为关联键。
8. 统计进程级事件
bpftrace -e 'tracepoint:sched:sched* { @[probe] = count(); } interval:s:5 { exit(); }'
统计5秒内各种进程调度事件的发生次数。
9. 分析内核调用栈
bpftrace -e 'profile:hz:99 { @[kstack] = count(); }'
以99Hz频率采样内核调用栈,可用于生成火焰图分析CPU使用情况。
10. 调度器追踪
bpftrace -e 'tracepoint:sched:sched_switch { @[kstack] = count(); }'
分析导致上下文切换的内核调用栈,帮助理解进程为何让出CPU。
11. 块I/O大小分析
bpftrace -e 'tracepoint:block:block_rq_issue { @ = hist(args.bytes); }'
通过直方图展示块设备I/O请求的大小分布。
12. 内核结构体追踪
bpftrace -e 'kprobe:vfs_open { printf("open path: %s\n", str(((struct path *)arg0)->dentry->d_name.name)); }'
高级示例展示如何访问内核结构体成员,需要了解内核数据结构。
总结
通过这12个示例,我们学习了bpftrace的核心功能:
- 各种探针类型的使用(tracepoint、kprobe、kretprobe等)
- 数据的收集和汇总方法(映射、统计函数)
- 过滤条件的应用
- 内核结构体的访问技巧
bpftrace是一个功能强大且灵活的工具,掌握这些基础后,读者可以开始编写自己的追踪脚本,解决实际的系统观测和分析问题。