Datenlord |用BPF实现用户态tracing

本文介绍了BPF(Berkeley Packet Filter)在Linux内核中的发展,从简单的网络包过滤工具演变为一个强大的内核扩展工具。通过用户态静态定义的Tracepoints(USDT)在程序中插入轻量级的监控点,配合BPF字节码的运行,可以在内核态安全地执行用户编写的程序,用于性能分析、网络、安全等多个领域。文章以一个用户态应用为例,展示了如何使用BPF和bpftrace命令进行性能分析,以及如何通过BCC工具编写BPF程序进行USDT tracing,从而捕获和处理tracepoint数据。

作者 | 王璞

BPF是最近Linux内核领域热门的技术。传统的BPF指的是tcpdump命令用于过滤网络包的工具,现在BPF已经得到极大的扩展,不再是Berkeley Packet Filter的缩写对应的简单的网络包过滤工具。 从Kernel 4.9之后,BPF已经成为一个完善的内核扩展工具,BPF在内核里运行一个sandbox,用于执行BPF的字节码(bytecode), 在执行BPF程序前,BPF的检查器会对BPF程序的字节码进行安全检查(比如,指针要先判断不为空后再访问,代码里不能有循环,等等),以保证BPF程序不会导致系统崩溃,因为BPF程序执行时是在内核态。 因此,BPF可以很安全地在内核态执行用户编写的程序,而且有安全保证,这比编写内核模块安全太多了。 正是因为BPF能保证安全,并运行在内核态,可以大大简化很多以前很复杂的事情,目前BPF已经应用于性能分析、网络、安全、驱动、区块链等等领域。

已经有很多文章介绍BPF在内核性能分析(Kernel tracing)方面的应用。内核有各种定义的tracepoint用于静态tracing,也可以采用动态tracing来跟踪内核函数调用。 用BPF进行内核tracing,开销小而且性能好,因为BPF程序是运行在内核态,不需要把采集到的数据再传回用户态处理,而是直接在内核态完成数据采集和处理,然后把处理结果传回用户态用于展示。 关于BPF用于内核tracing方面不再赘述,本文专注于利用BPF进行用户态应用性能分析(Userspace tracing)方面。

用户态tracing


在进行用户态tracing前,要在程序里定义tracepoints。这里主要介绍Userland Statically Defined Tracepoints(USDT)。

因为USDT依赖systemtap-sdt-dev包,先要安装依赖包,以Ubuntu为例,运行sudo apt install systemtap-sdt-dev进行安装。 下面的示例test-server.c给出如何使用宏DTRACE_PROBE1在用户程序里定义tracepoint:

#include <sys/sdt.h>
#include <unistd.h>

int main(int argc, char **argv)
{
    int idx = 0;
    while(1) {
        idx++;
        // 自定义的tracepoint
        DTRACE_PROBE1(test_grp, test_idx, idx);
        sleep(1);
    }
    return 0;
}

上面的例子,用宏DTRACE_PROBE1定义了一个组名为test_grp、名称为test_idx的用户态tracepoint。该tracepoint只有一个参数,该参数是一个递增的整数变量。 如果要定义有两个或更多参数的tracepoint,要用DTRACE_PROBE2DTRACE_PROBE3,以此类推。如果tracepoint不带参数,则用DTRACE_PROBE来定义。 用gcc命令编译上面的程序

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

达坦科技DatenLord

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

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

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

打赏作者

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

抵扣说明:

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

余额充值