BPF 编译器集合 (BCC)
BCC 是一个用于创建高效的内核跟踪和操作程序的工具包,包括几个有用的工具和示例。它利用了扩展的 BPF(伯克利数据包过滤器),正式名称为 eBPF,这是 Linux 3.15 中首次添加的一项新功能。 BCC 使用的大部分内容都需要 Linux 4.1 及更高版本。
Ingo Molnár 将 eBPF 描述为:
此周期中更有趣的功能之一是将 eBPF 程序(由内核执行的用户定义的沙箱字节码)附加到 kprobes 的能力。这允许在实时内核映像上进行用户定义的检测,而永远不会崩溃、挂起或对内核产生负面影响。
BCC 使 BPF 程序更易于编写,具有 C 语言的内核检测(并包括围绕 LLVM 的 C 包装器)以及 Python 和 lua 的前端。它适用于许多任务,包括性能分析和网络流量控制。
截屏
此示例跟踪磁盘 I/O 内核函数,并填充 I/O 大小的内核内 2 次幂直方图。为了提高效率,仅将直方图摘要返回给用户级。
# ./bitehist.py
Tracing... Hit Ctrl-C to end.
^C
kbytes : count distribution
0 - > 1 : 3 | |
2 - > 3 : 0 | |
4 - > 7 : 211 | ********** |
8 - > 15 : 0 | |
16 - > 31 : 0 | |
32 - > 63 : 0 | |
64 - > 127 : 1 | |
128 - > 255 : 800 | ************************************** |
上面的输出显示了双峰分布,其中 800 I/O 的最大模式大小在 128 到 255 KB 之间。
请参阅来源:bitehist.py。其跟踪的内容、存储的内容以及数据的呈现方式都可以完全自定义。这仅显示了许多可能的功能中的一些。
安装中
请参阅 INSTALL.md 了解您平台上的安装步骤。
常问问题
请参阅 FAQ.txt 了解最常见的故障排除问题。
参考指南
有关 bcc 和 bcc/BPF API 的参考指南,请参阅 docs/reference_guide.md。
内容
其中一些是包含 C 和 Python 的单个文件,其他有一对 .c 和 .py 文件,还有一些是文件目录。
追踪
示例
- example/tracing/bitehist.py:块 I/O 大小直方图。例子。
- example/tracing/disksnoop.py:跟踪块设备 I/O 延迟。例子。
- example/hello_world.py:打印“Hello, World!”对于新流程。
- example/tracing/mysqld_query.py:使用 USDT 探针跟踪 MySQL 服务器查询。例子。
- example/tracing/nodejs_http_server.py:使用 USDT 探针跟踪 Node.js HTTP 服务器请求。例子。
- example/tracing/stacksnoop:跟踪内核函数并打印所有内核堆栈跟踪。例子。
- tools/statsnoop:跟踪 stat() 系统调用。例子。
- example/tracing/task_switch.py:使用起始和终止 PID 来计算任务切换。
- example/tracing/tcpv4connect.py:跟踪 TCP IPv4 活动连接。例子。
- example/tracing/trace_fields.py:打印跟踪事件字段的简单示例。
- example/tracing/undump.py:转储 UNIX 套接字数据包。示例
- example/tracing/urandomread.py:内核跟踪点示例,跟踪 random:urandom_read。例子。
- example/tracing/vfsreadlat.py Examples/tracing/vfsreadlat.c:VFS 读取延迟分布。例子。
- example/tracing/kvm_hypercall.py:KVM 进入、退出和超级调用示例的条件静态内核跟踪点。
工具
- tools/argdist:将函数参数值显示为直方图或频率计数。例子。
- tools/bashreadline:在系统范围内打印输入的 bash 命令。例子。
- tools/bpflist:显示具有活动 BPF 程序和映射的进程。例子。
- 工具/能力:跟踪安全能力检查。例子。
- tools/compactsnoop:使用 PID 和延迟跟踪紧凑区域事件。例子。
- Tools/Criticalstat:跟踪并报告内核中的长原子关键部分。示例
- 工具/死锁:检测正在运行的进程上潜在的死锁。例子。
- tools/drsnoop:使用 PID 和延迟跟踪直接回收事件。例子。
- tools/funccount:计算内核函数调用次数。例子。
- 工具/注入:使用调用链和谓词示例进行有针对性的错误注入。
- tools/klockstat:跟踪内核互斥锁定事件并显示锁定统计信息。例子。
- tools/opensnoop:跟踪 open() 系统调用。例子。
- tools/readahead:显示预读缓存示例的性能。
- tools/reset-trace:重置跟踪状态。仅维护工具。例子。
- tools/stackcount:计算内核函数调用及其堆栈跟踪。例子。
- 工具/syncsnoop:跟踪sync()系统调用。例子。
- tools/threadsnoop:列出新线程创建。例子。
- tools/tplist:显示内核跟踪点或 USDT 探针及其格式。例子。
- 工具/跟踪:使用过滤器跟踪任意函数。例子。
- tools/ttysnoop:观看 tty 或 pts 设备的实时输出。例子。
- tools/ucalls:总结高级语言中的方法调用或 Linux 系统调用。例子。
- tools/uflow:用高级语言打印方法流程图。例子。
- tools/ugc:跟踪高级语言中的垃圾收集事件。例子。
- tools/uobjnew:按对象类型和分配的字节数汇总对象分配事件。例子。
- tools/ustat:以高级语言收集事件,例如 GC、线程创建、对象分配、异常等。例子。
- tools/uthreads:跟踪 Java 和原始 pthread 中的线程创建事件。例子。
内存和处理工具
- tools/execsnoop:通过 exec() 系统调用跟踪新进程。例子。
- tools/exitsnoop:跟踪进程终止(退出和致命信号)。例子。
- tools/killsnoop:由kill()系统调用发出的跟踪信号。例子。
- tools/kvmexit:显示每个虚拟机退出的 exit_reason 及其统计信息。例子。
- tools/memleak:显示未完成的内存分配以查找内存泄漏。例子。
- tools/oomkill:跟踪内存不足 (OOM) 杀手。例子。
- tools/pidpersec:计算新进程(通过 fork)。例子。
- tools/rdmaucma:跟踪 RDMA 用户空间连接管理器访问事件。例子。
- tools/shmsnoop:跟踪 System V 共享内存系统调用。例子。
- tools/slabratetop:内核SLAB/SLUB内存缓存分配率top。例子。
性能和时间工具
- tools/dbslower:跟踪慢于阈值的 MySQL/PostgreSQL 查询。例子。
- tools/dbstat:将 MySQL/PostgreSQL 查询延迟总结为直方图。例子。
- tools/funcinterval:作为直方图的同一函数之间的时间间隔。例子。
- 工具/功能:时间函数并显示其延迟分布。例子。
- tools/funcslower:跟踪缓慢的内核或用户函数调用。例子。
- tools/hardirqs:测量硬 IRQ(硬中断)事件时间。例子。
- tools/mysqld_qslower:跟踪慢于阈值的 MySQL 服务器查询。例子。
- tools/ppchcalls:总结 ppc hcall 计数和延迟。例子。
- 工具/软中断:测量软IRQ(软中断)事件时间。例子。
- tools/syscount:总结系统调用计数和延迟。例子。
CPU 和调度程序工具
- tools/cpudist:将每个任务的 CPU 开启和关闭时间总结为直方图。示例
- tools/cpuunclaimed:CPU 运行队列样本并计算无人认领的空闲 CPU。示例
- tools/llcstat:按进程汇总 CPU 缓存引用和未命中情况。例子。
- tools/offcputime:通过内核堆栈跟踪总结 CPU 外时间。例子。
- tools/offwaketime:按内核脱离 CPU 堆栈和唤醒堆栈汇总阻塞时间。例子。
- 工具/配置文件:通过按时间间隔采样堆栈跟踪来分析 CPU 使用情况。例子。
- tools/runqlat:以直方图形式运行队列(调度程序)延迟。例子。
- tools/runqlen:以直方图形式运行队列长度。例子。
- tools/runqslower:跟踪长进程调度延迟。例子。
- tools/wakeuptime:通过唤醒器内核堆栈总结睡眠到唤醒时间。例子。
- tools/wqlat:总结工作队列上的工作等待延迟。例子。
网络和套接字工具
- tools/gethostlatency:显示 getaddrinfo/gethostbyname[2] 调用的延迟。例子。
- tools/bindsnoop:跟踪 IPv4 和 IPv6 bind() 系统调用 (bind())。例子。
- tools/netqtoptools/netqtop.c:跟踪并显示 NIC 队列上的数据包分布。例子。
- tools/sofdsnoop:跟踪通过 unix 套接字传递的 FD。例子。
- tools/solisten:跟踪 TCP 套接字侦听。例子。
- tools/sslsniff:嗅探 OpenSSL 写入和读取的数据。例子。
- tools/tcpaccept:跟踪 TCP 被动连接 (accept())。例子。
- tools/tcpconnect:跟踪 TCP 活动连接 (connect())。例子。
- tools/tcpconnlat:跟踪 TCP 活动连接延迟 (connect())。例子。
- tools/tcpdrop:跟踪基于内核的 TCP 数据包丢失的详细信息。例子。
- tools/tcplife:跟踪 TCP 会话并总结生命周期。例子。
- tools/tcpretrans:跟踪 TCP 重传和 TLP。例子。
- tools/tcprtt:跟踪 TCP 往返时间。例子。
- tools/tcpstates:跟踪 TCP 会话状态随持续时间的变化。例子。
- tools/tcpsubnet:汇总并聚合按子网发送的 TCP。例子。
- tools/tcpsynbl:显示 TCP SYN 积压。例子。
- tools/tcptop:按主机汇总 TCP 发送/接收吞吐量。 TCP 的顶部。例子。
- 工具/tcptracer:跟踪 TCP 建立的连接(connect()、accept()、close())。例子。
- tools/tcpcong:跟踪 TCP 套接字拥塞控制状态持续时间。例子。
存储和文件系统工具
- tools/bitesize:显示每个进程 I/O 大小直方图。例子。
- tools/cachestat:跟踪页面缓存命中/未命中率。例子。
- tools/cachetop:按进程跟踪页面缓存命中/未命中率。例子。
- tools/dcsnoop:跟踪目录条目缓存 (dcache) 查找。例子。
- tools/dcstat:目录条目缓存 (dcache) 统计信息。例子。
- 工具/生物延迟:将块设备 I/O 延迟总结为直方图。例子。
- tools/biotop:磁盘顶部:按进程汇总块设备 I/O。例子。
- 工具/生物模式:识别随机/顺序磁盘访问模式。例子。
- tools/biosnoop:使用 PID 和延迟跟踪块设备 I/O。例子。
- tools/dirtop:按目录进行文件读写。目录顶部。例子。
- tools/filelife:跟踪短期文件的生命周期。例子。
- 工具/文件消失:跟踪文件消失的原因(删除或重命名)。例子。
- tools/fileslower:跟踪缓慢的同步文件读取和写入。例子。
- tools/filetop:按文件名和进程读取和写入文件。顶部为文件。例子。
- tools/mdflush:跟踪 md 刷新事件。例子。
- tools/mountsnoop:跟踪系统范围内的挂载和卸载系统调用。例子。
- tools/virtiostat:显示 VIRTIO 设备 IO 统计信息。例子。
文件系统工具
- tools/btrfsdist:将 btrfs 操作延迟分布总结为直方图。例子。
- tools/btrfsslower:跟踪缓慢的 btrfs 操作。例子。
- tools/ext4dist:将 ext4 操作延迟分布总结为直方图。例子。
- tools/ext4slower:跟踪缓慢的 ext4 操作。例子。
- tools/nfsslower:跟踪缓慢的 NFS 操作。例子。
- tools/nfsdist:将 NFS 操作延迟分布总结为直方图。例子。
- tools/vfscount:统计 VFS 调用。例子。
- tools/vfsstat:统计一些 VFS 调用,并带有列输出。例子。
- tools/xfsdist:将 XFS 操作延迟分布总结为直方图。例子。
- tools/xfsslower:跟踪缓慢的 XFS 操作。例子。
- tools/zfsdist:将 ZFS 操作延迟分布总结为直方图。例子。
- tools/zfsslower:跟踪缓慢的 ZFS 操作。例子。
联网
示例:
- example/networking/distributed_bridge/:分布式网桥示例。
- example/networking/http_filter/:简单的 HTTP 过滤器示例。
- example/networking/simple_tc.py:简单的流量控制示例。
- example/networking/simulation.py:模拟助手。
- example/networking/neighbor_sharing/tc_neighbor_sharing.py Examples/networking/neighbor_sharing/tc_neighbor_sharing.c:每 IP 分类和速率限制。
- example/networking/tunnel_monitor/:有效监控流量。
- example/networking/vlan_learning/vlan_learning.py Examples/vlan_learning.c:将以太网流量解复用到工作线程 veth+ 命名空间中。
BPF自省
有助于内省 BPF 程序的工具。
- introspection/bps.c:列出加载到内核中的所有 BPF 程序。 'ps' 用于 BPF 程序。例子。
动机
BPF 保证加载到内核中的程序不会崩溃,也不会永远运行,但 BPF 的通用性足以执行许多任意类型的计算。目前,可以用 C 编写一个程序,将其编译为有效的 BPF 程序,但编写一个将编译为无效 BPF 的 C 程序要容易得多(C 就是这样)。用户直到尝试运行该程序才知道它是否有效。
对于 BPF 特定的前端,人们应该能够用一种语言编写并从编译器接收有关 BPF 后端有效性的反馈。该工具包旨在提供一个只能创建有效的 BPF 程序的前端,同时仍然充分利用其灵活性。
此外,当前与 BPF 的集成工作流程混乱,有时涉及直接在 Linux 内核源代码树中进行编译。该工具链旨在最大限度地减少开发人员编译 BPF 所花费的时间,并将重点放在可以编写的应用程序以及可以使用 BPF 解决的问题上。
该工具包的功能包括:
- 共享库中的端到端 BPF 工作流程
- 用于 BPF 后端的改进的 C 语言
- 与 llvm-bpf 后端集成以实现 JIT
- JIT 程序的动态(卸载)加载
- 支持 BPF 内核挂钩:套接字过滤器、tc 分类器、tc 操作和 kprobes
- Python 的绑定
- 套接字过滤器、tc 分类器和 kprobes 的示例
- 用于跟踪正在运行的系统的独立工具
将来,可能会支持除 python 之外的更多绑定。请随意添加对您选择的语言的支持并发送拉取请求!
教程
- docs/tutorial.md:使用 bcc 工具解决性能、故障排除和网络问题。
- docs/tutorial_bcc_python_developer.md:使用 Python 接口开发新的 bcc 程序。
联网
在 2015 年红帽峰会上,BCC 作为 BPF 会议的一部分进行了介绍。模拟多主机vxlan环境,并使用BPF程序监控其中一个物理接口。 BPF 程序对经过接口的内部和外部 IP 地址进行统计,用户空间组件将这些统计数据转换成显示多粒度流量分布的图表。请参阅此处的代码。
贡献
已经准备好提交一些代码了吗?这里有一些资源可供您加入 IOVisor 社区的讨论并了解您想要做什么。
- 邮件列表: https://lists.iovisor.org/mailman/listinfo/iovisor-dev
- IRC: #iovisor,位于 irc.oftc.net
- BCC 问题跟踪器: Github 问题
- 贡献脚本指南: CONTRIBUTING-SCRIPTS.md
外部链接
想要了解有关 BCC 及其使用方式的更多信息?您可以在 LINKS.md 中找到网络上其他 BCC 内容的链接。