bpftrace 单行命令教程:12个案例掌握Linux内核追踪技术

bpftrace 单行命令教程:12个案例掌握Linux内核追踪技术

bpftrace High-level tracing language for Linux eBPF bpftrace 项目地址: https://gitcode.com/gh_mirrors/bp/bpftrace

前言

bpftrace 是一个基于eBPF技术的高级追踪工具,它允许开发者通过简洁的脚本语言对Linux内核和用户空间程序进行高效追踪。本教程将通过12个精心设计的单行命令案例,由浅入深地介绍bpftrace的核心概念和使用技巧。

基础概念

在开始之前,我们需要了解几个关键术语:

  • 探针(Probe):bpftrace的观测点,用于捕获事件数据
  • 动作(Action):当探针触发时执行的操作
  • 映射(Map):用于存储和汇总数据的特殊变量类型
  • 过滤器(Predicate):条件表达式,用于筛选特定事件

课程案例

1. 探针列表查询

bpftrace -l 'tracepoint:syscalls:sys_enter_*'

这个命令展示了如何列出所有可用的探针,并使用通配符进行过滤。系统调用入口点是最常用的追踪点之一,因为它们提供了稳定的接口来监控应用程序与内核的交互。

2. Hello World示例

bpftrace -e 'BEGIN { printf("hello world\n"); }'

最简单的bpftrace程序,使用BEGIN特殊探针在程序开始时打印欢迎信息。BEGIN类似于awk中的BEGIN块,常用于初始化和打印标题。

3. 文件打开监控

bpftrace -e 'tracepoint:syscalls:sys_enter_openat { printf("%s %s\n", comm, str(args.filename)); }'

这个例子展示了如何追踪文件打开操作:

  • comm内置变量表示当前进程名
  • args.filename访问系统调用参数
  • str()函数将指针转换为字符串

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); }'

这个例子演示了:

  • 使用过滤器(/.../)针对特定PID
  • hist()函数生成2的幂次方直方图
  • 分析read()系统调用的返回值分布

6. 内核动态追踪read()字节数

bpftrace -e 'kretprobe:vfs_read { @bytes = lhist(retval, 0, 2000, 200); }'

使用kretprobe动态追踪内核函数返回:

  • lhist()生成线性直方图
  • 相比tracepoint,kprobe/kretprobe更灵活但不稳定

7. read()操作耗时分析

bpftrace -e 'kprobe:vfs_read { @start[tid] = nsecs; } kretprobe:vfs_read /@start[tid]/ { @ns[comm] = hist(nsecs - @start[tid]); delete(@start, tid); }'

这个复杂示例展示了:

  • 使用线程ID作为唯一标识
  • nsecs获取高精度时间戳
  • 计算函数入口和返回的时间差
  • 清理临时变量

8. 进程事件统计

bpftrace -e 'tracepoint:sched:sched* { @[probe] = count(); } interval:s:5 { exit(); }'

统计5秒内各种进程调度事件,使用interval探针设置超时。

9. 内核栈采样分析

bpftrace -e 'profile:hz:99 { @[kstack] = count(); }'

99Hz频率采样内核栈:

  • 99Hz避免了与其他定时活动同步
  • 结果适合生成火焰图
  • ustack可用于用户栈分析

10. 调度器追踪

bpftrace -e 'tracepoint:sched:sched_switch { @[kstack] = count(); }'

分析导致上下文切换的内核调用路径,对于理解系统瓶颈非常有用。

11. 块I/O大小分析

bpftrace -e 'tracepoint:block:block_rq_issue { @ = hist(args.bytes); }'

通过直方图分析块设备I/O请求大小分布,注意探针上下文可能不是预期进程。

12. 内核结构体追踪

bpftrace path.bt

其中path.bt内容:

#ifndef BPFTRACE_HAVE_BTF
#include <linux/path.h>
#include <linux/dcache.h>
#endif

kprobe:vfs_open
{
    printf("open path: %s\n", str(((struct path *)arg0)->dentry->d_name.name));
}

这个高级示例展示了:

  • 访问内核结构体成员
  • 类型转换和指针解引用
  • 条件包含头文件处理不同内核配置

总结

通过这12个案例,我们系统性地学习了bpftrace的核心功能:

  1. 从简单追踪到复杂分析
  2. 多种探针类型的使用场景
  3. 数据汇总和可视化技术
  4. 内核结构体和动态追踪

bpftrace的强大之处在于它简洁的语法和丰富的功能,使得系统级分析变得前所未有的便捷。掌握这些基础后,读者可以开始编写自己的追踪脚本,解决实际性能问题。

bpftrace High-level tracing language for Linux eBPF bpftrace 项目地址: https://gitcode.com/gh_mirrors/bp/bpftrace

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

时泓岑Ethanael

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值