BPF, 一个强大的追踪调试系统

记得 5 年前刚接触 perf 的时候,还特意调研了一下不同系统上的动态和静态追踪工具,知道了 Linux 上的 SystemTap,perf。Solaris 上的 DTrace。看到绝大多数资料都说 DTrace 多么的强大好用,但是 Linux 却没有与之相提并论的工具。

最近看到 BPF 这三个字被提及的很频繁,搜索了一下发现它号称 “Linux 中的 DTrace”, 于是试着玩了一下。

先说一个题外话,BPF 全称是 “Berkeley Packet Filter”,字面意思是包过滤器,那么问题来了 我一个包过滤器,怎么追踪调试的呢?这个小问题请看参考资料1 。

安装

首先,内核版本最好大于 4.9 , 可以用 uname -a 命令查看。

其次,查看一下内核在编译的时候是否开启了 BPF 选项,一般在 /boot/ 目录下有对应内核版本的 config 文件,比如在我的机器上是 /boot/config-4.15.0-30-generic。 如果看到 CONFIG_BPF_SYSCALL=y 说明可以用 BPF 的基本功能。

前面提到 BPF 号称 Linux 中的 DTrace,为什么呢? 因为 DTrace 包含了一个类似脚本语言的 D 语言,用户可以用简单的几句 D 语言完成复杂的调试追踪任务,这一点是 perf 做不到,而 BPF 做到了。

确认了内核支持 BPF 之后,我们可以安装一个叫做 bcc 的工具,通过它可以方便的使用 BPF。

BCC - Tools for BPF-based Linux IO analysis, networking, monitoring

如果是 Ubuntu 系统,可以添加源

1. sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys D4284CDD

2. echo "deb https://repo.iovisor.org/apt/bionic bionic main" |\
   sudo tee /etc/apt/sources.list.d/iovisor.list

3. sudo apt-get install bcc-tools

然后就能用 apt 命令 install bcc 了。

使用

在系统中安装好 bcc 之后,再下载一份源码,因为想试玩 tools 目录下的几十个工具。

tcpconnect.py 跟踪系统中所有的 tcp connect() 调用。

> openssl s_client -connect google.com:443

root@ubuntu:~/bcc/tools# ./tcpconnect.py
PID    COMM         IP SADDR            DADDR            DPORT
11493  openssl      4  192.168.122.167  216.58.195.78    443

开发

随便打开一个 py 文件,都能看到像下面这样的一段代码,这就是类似 DTrace 的 D 语言那样,用较高级的语言,通过即时编译,完成复杂的追踪调试任务。BPF 最核心的优势也在于此。

bpf_text = 
#include <uapi/linux/ptrace.h>
#define KBUILD_MODNAME "foo"
#include <linux/tcp.h>
#include <net/sock.h>
#include <bcc/proto.h>

BPF_HASH(last, struct sock *, u64);

// separate data structs for ipv4 and ipv6
struct ipv4_data_t {
    u64 ts_us;
    u64 skaddr;
    u64 saddr;
    u64 daddr;
    u64 span_us;
    u32 pid;
    u32 ports;
    u32 oldstate;
    u32 newstate;
    char task[TASK_COMM_LEN];
};

争取下次可以自己开发一个小工具。happy hacking

参考资料

  • https://linux.cn/article-8038-1.html
  • http://www.brendangregg.com/ebpf.html
  • https://github.com/iovisor/bcc
-----------------------
返回首页

| Copyright 2009 - 2018 by Runz |