bpftrace 是一个 基于 eBPF 的新型追踪工具,在 Fedora 28 第一次引入。Brendan Gregg、Alastair Robertson 和 Matheus Marchini 在网上的一个松散的黑客团队的帮助下开发了 bpftrace。它是一个允许你分析系统在幕后正在执行的操作的追踪工具,可以告诉你代码中正在被调用的函数、传递给函数的参数、函数的调用次数等。

这篇文章的内容涉及了 bpftrace 的一些基础,以及它是如何工作的,请继续阅读获取更多的信息和一些有用的实例。

eBPF

eBPF 是一个微型虚拟机,更确切的说是一个位于 Linux 内核中的虚拟 CPU。eBPF 可以在内核空间以一种安全可控的方式加载和运行小型程序,使得 eBPF 的使用更加安全,即使在生产环境系统中。eBPF 虚拟机有自己的指令集架构(ISA),类似于现代处理器架构的一个子集。通过这个 ISA,可以很容易将 eBPF 程序转化为真实硬件上的代码。内核即时将程序转化为主流处理器架构上的本地代码,从而提升性能。

eBPF 虚拟机允许通过编程扩展内核,目前已经有一些内核子系统使用这一新型强大的 Linux 内核功能,比如网络、安全计算、追踪等。这些子系统的主要思想是添加 eBPF 程序到特定的代码点,从而扩展原生的内核行为。

虽然 eBPF 机器语言功能强大,由于是一种底层语言,直接用于编写代码很费力,bpftrace 就是为了解决这个问题而生的。eBPF 提供了一种编写 eBPF 追踪脚本的高级语言,然后在 clang / LLVM 库的帮助下将这些脚本转化为 eBPF,最终添加到特定的代码点。

安装和快速入门

在终端 使用 sudo 执行下面的命令安装 bpftrace:

$ sudo dnf install bpftrace

使用“hello world”进行实验:

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

注意,出于特权级的需要,你必须使用 root 运行 bpftrace,使用 -e 选项指明一个程序,构建一个所谓的“单行程序”。这个例子只会打印 “hello world”,接着等待你按下 Ctrl+C。

BEGIN 是一个特殊的探针名,只在执行一开始生效一次;每次探针命中时,大括号 {} 内的操作(这个例子中只是一个 printf)

都会执行。

现在让我们转向一个更有用的例子:

$ sudo bpftrace -e 't:syscalls:sys_enter_execve { printf("%s called %s\n", comm, str(args->filename)); }'

这个例子打印了父进程的名字(comm)和系统中正在创建的每个新进程的名称。t:syscalls:sys_enter_execve 是一个内核追踪点,是 tracepoint:syscalls:sys_enter_execve 的简写,两种形式都可以使用。下一部分会向你展示如何列出所有可用的追踪点。

comm 是一个 bpftrace 内建指令,代表进程名;filename 是 t:syscalls:sys_enter_execve 追踪点的一个字段,这些字段可以通过 args 内建指令访问。

追踪点的所有可用字段可以通过这个命令列出:

bpftrace -lv "t:syscalls:sys_enter_execve"

示例用法

bpftrace 的一个核心概念是探针点,即 eBPF 程序可以连接到的(内核或用户空间的)代码中的测量点,可以分成以下几大类:

  • kprobe——内核函数的开始处
    kretprobe——内核函数的返回处
    uprobe——用户级函数的开始处
    uretprobe——用户级函数的返回处
    tracepoint——内核静态追踪点
    usdt——用户级静态追踪点
    profile——基于时间的采样
    interval——基于时间的输出
    software——内核软件事件
    hardware——处理器级事件

所有可用的 kprobe / kretprobe、tracepoints、software 和 hardware 探针可以通过这个命令列出:

$ sudo bpftrace -l

uprobe / uretprobe 和 usdt 是用户空间探针,专用于某个可执行文件。要使用这些探针,通过下文中的特殊语法。profile 和 interval 探以固定的时间间隔触发;固定的时间间隔不在本文的范畴内。

统计系统调用数

映射 是保存计数、统计数据和柱状图的特殊 BPF 数据类型,你可以使用映射统计每个系统调用正在被调用的次数:

$ sudo bpftrace -e 't:syscalls:sys_enter_* { @[probe] = count(); }'

一些探针类型允许使用通配符匹配多个探针,你也可以使用一个逗号隔开的列表为一个操作块指明多个连接点。上面的例子中,操作块连接到了所有名称以 t:syscalls:sysenter_ 开头的追踪点,即所有可用的系统调用。

bpftrace 的内建函数 count() 统计系统调用被调用的次数;@[] 代表一个映射(一个关联数组)。该映射的键 probe 是另一个内建指令,代表完整的探针名。

这个例子中,相同的操作块连接到了每个系统调用,之后每次有系统调用被调用时,映射就会被更新,映射中和系统调用对应的项就会增加。程序终止时,自动打印出所有声明的映射。

下面的例子统计所有的系统调用,然后通过 bpftrace 过滤语法使用 PID 过滤出某个特定进程调用的系统调用:

$ sudo bpftrace -e 't:syscalls:sys_enter_* / pid == 1234 / { @[probe] = count(); }'

进程写的字节数

让我们使用上面的概念分析每个进程正在写的字节数:

$ sudo bpftrace -e 't:syscalls:sys_exit_write /args->ret > 0/ { @[comm] = sum(args->ret); }'

bpftrace 连接操作块到写系统调用的返回探针(t:syscalls:sys_exit_write),然后使用过滤器丢掉代表错误代码的负值(/arg->ret > 0/)。

映射的键 comm 代表调用系统调用的进程名;内建函数 sum() 累计每个映射项或进程写的字节数;args 是一个 bpftrace 内建指令,用于访问追踪点的参数和返回值。如果执行成功,write 系统调用返回写的字节数,arg->ret

用于访问这个字节数。

进程的读取大小分布(柱状图):

bpftrace 支持创建柱状图。让我们分析一个创建进程的 read 大小分布的柱状图的例子:

$ sudo bpftrace -e 't:syscalls:sys_exit_read { @[comm] = hist(args->ret); }'

柱状图是 BPF 映射,因此必须保存为一个映射(@),这个例子中映射键是 comm。

这个例子使 bpftrace 给每个调用 read 系统调用的进程生成一个柱状图。要生成一个全局柱状图,直接保存 hist() 函数到 @(不使用任何键)。

程序终止时,bpftrace 自动打印出声明的柱状图。创建柱状图的基准值是通过 args->ret 获取到的读取的字节数。

追踪用户空间程序

你也可以通过 uprobes / uretprobes 和 USDT(用户级静态定义的追踪)追踪用户空间程序。下一个例子使用探测用户级函数结尾处的 uretprobe ,获取系统中运行的每个 bash 发出的命令行:

$ sudo bpftrace -e 'uretprobe:/bin/bash:readline { printf("readline: \"%s\"\n", str(retval)); }'

要列出可执行文件 bash 的所有可用 uprobes / uretprobes, 执行这个命令:

$ sudo bpftrace -l "uprobe:/bin/bash"

uprobe 指向用户级函数执行的开始,uretprobe 指向执行的结束(返回处);readline() 是 /bin/bash 的一个函数,返回键入的命令行;retval 是被探测的指令的返回值,只能在 uretprobe 访问。

使用 uprobes 时,你可以用 arg0..argN 访问参数。需要调用 str() 将 char * 指针转化成一个字符串。

自带脚本

bpftrace 软件包附带了许多有用的脚本,可以在 /usr/share/bpftrace/tools/ 目录找到。

这些脚本中,你可以找到:

  • killsnoop.bt——追踪 kill() 系统调用发出的信号
  • tcpconnect.bt——追踪所有的 TCP 网络连接
  • pidpersec.bt——统计每秒钟(通过fork)创建的新进程
  • opensnoop.bt——追踪 open() 系统调用
  • bfsstat.bt——追踪一些 VFS 调用,按秒统计

你可以直接使用这些脚本,比如:

$ sudo /usr/share/bpftrace/tools/killsnoop.bt

你也可以在创建新的工具时参考这些脚本。

基于 eBPF 的新型追踪工具:bpftrace相关推荐

  1. eHIDS 一款基于eBPF的HIDS开源工具

    一 前言 IDS一般指入侵检测系统.入侵检测系统(intrusion detection system,简称"IDS")是一种对网络传输进行即时监视,在发现可疑传输时发出警报或者采 ...

  2. 基于eBPF的云原生可观测性开源工具Kindling之Kindling-agent 性能测试评估

    背景 Kindling-agent是基于eBPF的云原生可观测性开源工具Kindling中采集端的组件,能够通过采集和分析内核事件,获取运行于同一宿主机上的其他服务的业务.网络等指标.其工作模式是在主 ...

  3. Linux中基于eBPF的恶意利用与检测机制(rootkit、驱动)

    目录 前言 现状分析 海外资料 国内资料 eBPF技术恶意利用的攻击原理 网络层恶意利用 Linux系统运行时恶意利用 综述 检测防御 运行前 运行时 运行后 防御 工程实现 系统兼容性 CO-RE ...

  4. 基于eBPF技术的开源项目Kindling之探针架构介绍

    Kindling开源项目是一款基于eBPF技术的云原生可观测性项目.本文将主要介绍探针的具体架构设计. Kindling探针的架构设计理念 Kindling架构设计中有一个很重要的理念:关注点分离(S ...

  5. Cilium 1.7发布:Hubble UI、全集群网络策略、基于eBPF的Direct Server Return以及更多

    在这里,我们要向大家高兴地宣布,Cilium 1.7版本正式发布了!在本轮更新周期当中,由141位开发者组成的项目社区共完成了1551项提交,而且很多朋友是第一次为Cilium项目提交贡献. Hubb ...

  6. 基于 eBPF 的 prometheus 监控方案

    基于 eBPF 的 prometheus 监控方案 1. 前言 2. ebpf_exporter 环境搭建 3. Prometheus 与 Grafana 配置 4. ebpf_exporter 代码 ...

  7. 深度解析|基于 eBPF 的 Kubernetes 一站式可观测性系统

    作者:李煌东.炎寻 摘要 阿里云目前推出了面向 Kubernetes 的一站式可观测性系统,旨在解决 Kubernetes 环境下架构复杂度高.多语言&多协议并存带来的运维难度高的问题,数据采 ...

  8. python商业分析_科研进阶 | 纽约大学 | 商业分析、量化金融:基于Python的商业分析工具...

    科研进阶 | 纽约大学 | 商业分析.量化金融:基于Python的商业分析工具(8.22开课)​mp.weixin.qq.com 课题名称 = 基于Python的商业分析工具 = 项目背景 数据分析为 ...

  9. 服务调用追踪工具skywalking实践

    skywalking简介 skywalking是一个开源的可观测平台,用于收集.分析.聚合和可视化来自服务和云原生基础设施的数据.skywalking提供了一种简单的方式来维护您的分布式系统的清晰视图 ...

最新文章

  1. Java中的拆箱与装箱
  2. 不要一辈子靠技术生存
  3. 面试官:你都工作3年了,连选择排序法都不会,我怎么能选择你
  4. 下列不是c++ 标准数据类型得是?
  5. python面向对象和面向过程的区别_Python11-01_面向对象----面向对象和面向过程的区别...
  6. G6 图可视化引擎——入门教程——动画
  7. Apache Cassandra和Apache Ignite:关系并置和分布式SQL
  8. android 手机壁纸源码,Android工程实现换壁纸功能【附源码】
  9. 完美日记:保障电商大促活动平稳运行
  10. 音视频开发必备基本基础知识(1)
  11. CentOS 6.9下KVM虚拟机通过virt-clone克隆虚拟机(转)
  12. python鼠标键盘事件代码_Python+selenium鼠标、键盘事件
  13. python selenium手动输入验证码_Python Selenium Cookie 绕过验证码实现登录
  14. 在Pyramid中使用Mako模板以及默认和.html后缀关联
  15. 前端er应该掌握的数据可视化技术
  16. Ps如何把背景图片拉长并不变形!
  17. 文本数据挖掘-----词向量
  18. 2022年新型智慧城市整体规划建设方案
  19. SEO关键词之选取策略及具体方法
  20. 5月31日武汉国金天地亮灯仪式鎏光绽放!

热门文章

  1. 超越BN-ReLU!谷歌大脑等提出EvoNorms:归一化激活层的进化
  2. 暴力裁员?小米回应来了,网友表示没毛病!
  3. Django源码分析6:auth认证及登陆保持
  4. 数据流分析与 SSA | 什么是静态单赋值 SSA
  5. Java Web项目配置环境搭建-如何增加Tomcat服务 Tomcat[内含Tomcat7资源]
  6. 技术17期:近几年崛起的Pytorch究竟是何方神圣?
  7. 如何在 1 秒内将 50 个 OpenCV 帧上传到云存储
  8. HyperPocket:生成点云网络
  9. 【OpenCV 4开发详解】轮廓发现与绘制
  10. 【OpenCV 4开发详解】窗口交互操作