bpftrace 工具手册速览

bpftrace 工具手册速览

一、工具基础介绍

1.1 核心功能定位

bpftrace 是基于 eBPF(Extended Berkeley Packet Filter)技术的下一代跟踪工具,提供以下核心能力:

  • 动态追踪:无需重启即可附加探针到内核/用户态函数
  • 低开销监控:利用 eBPF 验证器确保安全执行
  • 高级语言支持:采用类C语法简化探针开发
  • 多数据源融合:同时捕获内核事件、性能计数器、网络数据
  • 实时分析:支持直方图、热力图等可视化输出

1.2 架构演进

BTF信息
事件数据
AST解析
字节码
用户空间
eBPF虚拟机
内核空间
bpftrace前端
LLVM后端

二、安装与配置

2.1 基础安装

Linux发行版

# Ubuntu/Debian
sudo apt-get install bpftrace

# CentOS/RHEL
sudo yum install bpftrace

# Fedora
sudo dnf install bpftrace

macOS

brew install bpftrace

2.2 权限配置

# 临时提权
sudo bpftrace <script.bt>

# 持久化配置(Linux)
echo 'kernel.unprivileged_bpf_disabled=0' | sudo tee /etc/sysctl.d/bpftrace.conf
sudo sysctl -p /etc/sysctl.d/bpftrace.conf

2.3 内核要求

  • 最低版本:Linux 4.1+(推荐5.8+)
  • 必要配置:
    • CONFIG_DEBUG_INFO_BTF=y
    • CONFIG_BPF_SYSCALL=y
    • CONFIG_BPF_EVENTS=y

三、基础语法详解

3.1 探针类型

类型描述示例
kprobe内核函数入口/出口kprobe:tcp_v4_connect
uprobe用户态函数入口uprobe:/usr/bin/curl:main
tracepoint静态跟踪点tracepoint:syscalls:sys_enter_openat
profile周期性采样profile:hz:99 每秒99次采样
interval时间间隔触发interval:s:1 每秒触发
software软件事件software:page-faults

3.2 内置变量

变量类型描述
piduint64进程ID
tiduint64线程ID
uiduint64用户ID
commstring进程名
args结构体函数参数(kprobe专用)
retvaluint64函数返回值(kretprobe专用)
cpuintCPU编号
curtasktask_struct*当前任务结构体指针

3.3 映射表操作

哈希映射

BEGIN
{
    @count = 0;  // 初始化计数器
}

kprobe:tcp_sendmsg
{
    @count = count + 1;
}

END
{
    print(@count);
}

直方图

kprobe:do_sys_open
{
    @latency = hist(args->dfd);  // 按文件描述符统计
}

热力图

profile:hz:99
{
    @stacks = lhist(args->stack_id, 0, 1000000, 10000);
}

3.4 控制流语句

条件判断

kprobe:tcp_v4_connect
{
    if (args->ip->daddr == 0x7F000001) {
        printf("Localhost connection\n");
    }
}

循环结构

BEGIN
{
    @arr = lhist();
}

tracepoint:syscalls:sys_enter_read
{
    for (i = 0; i < 10; i++) {
        @arr[i] = count();
    }
}

四、实战案例分析

4.1 网络分析

TCP重传检测

kprobe:tcp_retransmit_skb
{
    printf("Retransmit detected: PID=%d, SEQ=%llu\n", pid, args->seq);
}

连接跟踪

kprobe:tcp_v4_connect
{
    printf("New connection: %s:%d -> %s:%d\n",
           comm,
           args->us->sport,
           str(args->ip->daddr),
           args->us->dport);
}

4.2 性能调优

系统调用延迟分析

tracepoint:syscalls:sys_enter_openat
{
    @start[tid] = nsecs;
}

tracepoint:syscalls:sys_exit_openat
{
    @latency = hist(nsecs - @start[tid]);
    delete(@start[tid]);
}

CPU火焰图生成

bpftrace -e 'profile:hz:99 {@[stack] = count();}' -o flame.stacks
./FlameGraph/stackcollapse-bpftrace.pl flame.stacks | ./FlameGraph/flamegraph.pl > flame.svg

4.3 安全审计

隐蔽通道检测

kprobe:security_socket_sendmsg
{
    if (args->msg->msg_flags & MSG_MORE) {
        printf("Potential covert channel: PID=%d, LEN=%d\n", pid, args->msg->msg_iter->count);
    }
}

异常进程监控

kprobe:execve
{
    printf("New process: %s(%d) launched by %s(%d)\n",
           str(args->filename),
           pid,
           str(comm),
           tid);
}

五、高级功能集成

5.1 BCC工具协同

混合编程示例

from bcc import BPF

bpf_text = """
kprobe:tcp_sendmsg
{
    @packets = count();
}
"""

b = BPF(text=bpf_text)
b.attach_kprobe(event="tcp_sendmsg", fn_name="kprobe__tcp_sendmsg")
b["@packets"].print_log2_hist("Packets per second")

5.2 持久化存储

环形缓冲区配置

BEGIN
{
    @ring = ringbuf(1024);  // 1MB环形缓冲区
}

kprobe:do_nanosleep
{
    @ring.push(args->requested_time);
}

5.3 共享映射表

进程间通信

// 写入端
kprobe:do_fork
{
    @shared[pid] = comm;
}

// 读取端
kprobe:do_exit
{
    if (@shared[pid]) {
        printf("Process %s exited\n", @shared[pid]);
        delete(@shared[pid]);
    }
}

六、调试与优化

6.1 验证器日志

启用详细验证

bpftrace -d 'kprobe:tcp_sendmsg { @cnt = count(); }' 2> verifier.log

日志分析

; int __attribute__((always_inline)) count(void) {
;     @cnt += 1;
; }
0: (bf) r6 = r1
1: (61) r1 = *(u32 *)(r6 + 12)
2: (61) r2 = *(u32 *)(r6 + 16)
3: (b7) r3 = 1
4: (71) r2 = *(u8 *)(r1 + r2)
5: (55) if r2 != 0x40 goto pc+13
R1=map_value(id=0,off=0,ks=4,vs=8,imm=0) R2=inv(id=0) R3=inv1 R6=ctx R10=fp0
; ... 省略后续指令 ...

6.2 性能优化技巧

  • 避免内核态拷贝:使用str()代替user_string()
  • 减少映射操作:批量更新代替单条记录
  • 利用BTF信息:自动解析结构体成员
  • 限制采样频率:通过interval探针控制负载

七、生态工具链

7.1 可视化套件

工具名称功能描述示例命令
FlameGraph火焰图生成./flamegraph.pl perf.fold > perf.svg
ebpf-exporterPrometheus指标导出ebpf_exporter --config.yaml
Grafana仪表盘展示配置bpftrace数据源

7.2 扩展库

库名称功能描述典型用例
libbpfeBPF底层API开发自定义探针
BCCPython绑定库构建复杂监控系统
AyaRust eBPF框架开发安全关键应用

八、最佳实践指南

8.1 脚本开发规范

  1. 使用#pragma bpftrace option控制行为:
    #pragma bpftrace option interval=1000  // 1秒刷新周期
    #pragma bpftrace option max_active_probes=1024
    
  2. 添加BEGIN/END块进行初始化/清理
  3. 使用@前缀声明映射表变量
  4. 避免在探针处理函数中执行阻塞操作

8.2 生产环境部署

  • 资源限制
    bpftrace -B 1024 --max-probes 4096 <script.bt>
    
  • 日志轮转
    BEGIN
    {
      $log_file = "trace.log";
    }
    
    kprobe:do_sys_open
    {
      @fp = fopen($log_file, "a");
      fprintf(@fp, "Open event: %s\n", str(args->filename));
      fclose(@fp);
    }
    

8.3 故障排查手册

  • 现象Resource temporarily unavailable
    原因:达到最大映射表数量
    解决方案:增加/proc/sys/kernel/bpf_map_max_entries

  • 现象Invalid probe type
    原因:探针类型与事件不匹配
    解决方案:使用trace --list验证事件存在性

  • 现象Permission denied
    原因:未启用非特权eBPF
    解决方案:设置kernel.unprivileged_bpf_disabled=0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值