在bpfTrace中使用USDT

在这里插入图片描述本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

本作品 (李兆龙 博文, 由 李兆龙 创作),由 李兆龙 确认,转载请注明版权。

引言

USDT的全称是user-level statically defined tracing,是一种在用户态中埋点,以支持动态追踪的方案,埋点的优点基本可以阐述为以下三点:

  1. 防止inline而导致无法监测到函数
  2. 随版本迭代接口功能可以保证没有变化
  3. 在不进行追踪时插入一条nop指令,在进行追踪时替换为int3。在不追踪时最大程度节省性能,代价只是一条nop和elf文件中多一个NOTE段,其中存储着probe的一些偏移信息。

不过目前这种USDT的埋点方案我还没有找到如何在SystemTap去使用([3]中描述量一种情况),[1]中描述了systemTap中usdt的使用,我们这篇来看一看如何在bpfTrace中使用USDT,这里我们使用Folly中的Traceing工具(folly/tracing)去实现需求,这里其实Folly中只用到了StaticTracepoint-ELFx86.hStaticTracepoint.h这两个文件而已,所以我们完全可以把这两个文件直接拷贝到我们的项目中,使得项目原生支持USDT。

例子

我们先看一个简单的例子:

#include "StaticTracepoint.hpp"
#include <unistd.h>

int main() {
    sleep(5);
    int one = 10;
    int two = 20;
    for (size_t i = 0; i < 100; i++) {
        one = two = i;
        TRACING_SDT(lizhaolong, yunwenqi, one, two);
    }
    sleep(10000);
    return 0;
}

执行如下指令g++ -fno-omit-frame-pointer -O0 -g main.cpp,然后我们gdb进去看看汇编,执行disassemble /m main就可以看到函数对应的源码和汇编了:
在这里插入图片描述
我们可以看到bpfTrace没有开始追踪时,这个地方是一条空指令,因为StaticTracepoint-ELFx86.h中插入汇编时有一条__volatile__,所以这个nop指令也不会被优化。

当我们把bpfTrace挂上时,即执行如下指令sudo bpftrace -e 'usdt:/home/lizhaolong.lzl/usdt/a.out:lizhaolong:yunwenqi {printf("%d %d\n", arg0, arg1)}',我们可以看到这样的输出:
在这里插入图片描述
此时gdb进去,可以看到如下显示:
在这里插入图片描述
这里其实就是去利用uprobes去执行动态追踪了。

我们也可以在elf文件中看到probe已经存在的证据:
在这里插入图片描述
好巧不巧,这里的Location的偏移就是我们设定的probe的起始地址,后面还有后面要提的信号量的偏移。


除了正常的埋点意外,还可以把代码写成下面这样:

#include "StaticTracepoint.hpp"
#include <unistd.h>

// 必须放到全局变量处,这是一个信号量的声明,有extern "C" 前缀
TRACING_SDT_DEFINE_SEMAPHORE(lizhaolong, yunwenqi)

int main() {
    sleep(5);
    int one = 10;
    int two = 20;
    for (size_t i = 0; i < 100; i++) {
        one = two = i;
        if (TRACING_SDT_IS_ENABLED(lizhaolong, yunwenqi)) {
            one *= 10;
            two *= 10;
            TRACING_SDT_WITH_SEMAPHORE(lizhaolong, yunwenqi, one, two);
        }
    }
    sleep(10000);
    return 0;
}

其实就是可能在把参数传向probe时可能需要做一些处理,这些处理可能是比较昂贵的,所以自然没有被追踪时我们不希望这些代码被执行,此时可以设定一个信号量,在被追踪时才被设置,其实本质就是一个volatile unsigned short
在这里插入图片描述
在这里插入图片描述
我们可以看到信号量的地址其实已经是写在elf文件中了的。此时我们用一个if判断跳过了昂贵的参数处理过程。

参考:

  1. https://github.com/agentzh/usdt-sample
  2. https://github.com/facebook/folly
  3. Adding User Space Probing to an Application (heapsort example)

原文链接: https://www.cnblogs.com/lizhaolong/p/16437170.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    在bpfTrace中使用USDT

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/396289

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年4月5日 下午2:15
下一篇 2023年4月5日 下午2:15

相关推荐