eBPF BCC开源工具简介

news2024/11/28 22:36:52

目录

官方链接

编译安装

ubuntu版本

安装

examples

tools

hello_world.py demo

运行报错

网上目前的解决办法

错误分析过程

python版本检测

libbcc库检查

python3 bcc库检查

正常输出

监控进程切换

运行输出

监控CPU直方图

缓存命中率监控:cachestat

cachetop

BCC开发指南


官方链接

主页:https://github.com/iovisor/bcc

bcc开发:https://github.com/iovisor/bcc/blob/master/docs/tutorial_bcc_python_developer.md

编译安装

ubuntu版本

wj@wj:~$ lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 22.04.2 LTS
Release:	22.04
Codename:	jammy

安装

git clone https://github.com/iovisor/bcc.git
mkdir bcc/build; cd bcc/build
cmake ..
make
sudo make install
cmake -DPYTHON_CMD=python3 .. # build python3 binding
pushd src/python/
make
sudo make install
popd

安装路径:
/usr/share/bcc/tools

可以看到 /usr/share/bcc 目录下,有4个文件夹,examples  introspection  man  tools 。

在examples 文件下,有一些简单的demo。tools文件下有 bcc的各种工具。

examples

 

tools

hello_world.py demo

#!/usr/bin/python
# Copyright (c) PLUMgrid, Inc.
# Licensed under the Apache License, Version 2.0 (the "License")

# run in project examples directory with:
# sudo ./hello_world.py"
# see trace_fields.py for a longer example

from bcc import BPF

# This may not work for 4.17 on x64, you need replace kprobe__sys_clone with kprobe____x64_sys_clone
BPF(text='int kprobe__sys_clone(void *ctx) { bpf_trace_printk("Hello, World!\\n"); return 0; }').trace_print()

上述 hello_world.py程序中会监测 kprobe__sys_clone 事件,一旦内核监测到 kprobe__sys_clone 事件产生,就会打印 Hello, World! 出来。

运行报错

wj@wj:/usr/share/bcc/examples$ sudo python3 hello_world.py 
Traceback (most recent call last):
  File "/usr/share/bcc/examples/hello_world.py", line 9, in <module>
    from bcc import BPF
  File "/usr/lib/python3/dist-packages/bcc/__init__.py", line 27, in <module>
    from .libbcc import lib, bcc_symbol, bcc_symbol_option, bcc_stacktrace_build_id, _SYM_CB_TYPE
  File "/usr/lib/python3/dist-packages/bcc/libbcc.py", line 20, in <module>
    lib.bpf_module_create_b.restype = ct.c_void_p
  File "/usr/lib/python3.10/ctypes/__init__.py", line 387, in __getattr__
    func = self.__getitem__(name)
  File "/usr/lib/python3.10/ctypes/__init__.py", line 392, in __getitem__
    func = self._FuncPtr((name_or_ordinal, self))
AttributeError: /lib/x86_64-linux-gnu/libbcc.so.0: undefined symbol: bpf_module_create_b

网上目前的解决办法

主要还是python版本问题,将python2切换为python3。而我这边显然不是这个问题,因为我的机子上只有python3

错误分析过程

根据报错信息,和报错相关的路径:

/lib/x86_64-linux-gnu/libbcc.so.0 :bcc库采用的libbcc.so.0

/usr/lib/python3/dist-packages/bcc :报错的bcc库

python版本检测

使用的均为python3,没有python2,所以不存在版本问题。

libbcc库检查

wj@wj:/usr/share/bcc/examples$ ls -lh /lib/x86_64-linux-gnu/ |grep libbcc
-rw-r--r--  1 root root  5.0M 11月  5 14:48 libbcc.a
-rw-r--r--  1 root root  1.5M 11月  5 14:46 libbcc_bpf.a
lrwxrwxrwx  1 root root    15  1月 19  2021 libbcc_bpf.so -> libbcc_bpf.so.0
lrwxrwxrwx  1 root root    20 11月  5 14:54 libbcc_bpf.so.0 -> libbcc_bpf.so.0.28.0
-rw-r--r--  1 root root   51K  1月 19  2021 libbcc_bpf.so.0.18.0
-rw-r--r--  1 root root  2.8M 11月  5 14:48 libbcc_bpf.so.0.28.0
-rw-r--r--  1 root root  243K 11月  5 14:47 libbcc-loader-static.a
lrwxrwxrwx  1 root root    11  1月 19  2021 libbcc.so -> libbcc.so.0
lrwxrwxrwx  1 root root    16 11月  5 14:54 libbcc.so.0 -> libbcc.so.0.28.0
-rw-r--r--  1 root root  3.3M  1月 19  2021 libbcc.so.0.18.0
-rw-r--r--  1 root root  105M 11月  5 14:47 libbcc.so.0.28.0

可以看到libbcc库的实际指向为: libbcc.so.0 -> libbcc.so.0.28.0

根据报错内容,python库需要bpf_module_create_b,而libbcc.so.0.28.0中没有

可以通过以下命令查看:

wj@wj:/usr/share/bcc/examples$ strings /lib/x86_64-linux-gnu/libbcc.so.0.28.0 |grep bpf_module_create_
bpf_module_create_c
bpf_module_create_c_from_string
bpf_module_create_c.cold
bpf_module_create_c_from_string.cold
bpf_module_create_c
bpf_module_create_c_from_string

此时注意到上一个步骤中的libbcc.so.0.18.0,同样进行bpf_module_create_b检查

wj@wj:/usr/share/bcc/examples$ strings /lib/x86_64-linux-gnu/libbcc.so.0.18.0 |grep bpf_module_create_
bpf_module_create_b
bpf_module_create_c
bpf_module_create_c_from_string

发现存在bpf_module_create_b,即便不进行时间对比,通过版本号0.18.0与0.28.0也知道,
python3的bcc库竟然请求的是老版(0.18.0)的bcc lib库

python3 bcc库检查

wj@wj:/usr/share/bcc/examples$ ll  /usr/lib/python3/dist-packages/bcc/
总计 212
drwxr-xr-x   3 root root  4096 10月  4 15:36 ./
drwxr-xr-x 155 root root 12288 11月  5 14:56 ../
-rw-r--r--   1 root root  2566  1月 19  2021 containers.py
-rw-r--r--   1 root root 20914  1月 19  2021 disassembler.py
-rw-r--r--   1 root root 58581  1月 19  2021 __init__.py
-rw-r--r--   1 root root 12951  1月 19  2021 libbcc.py
-rw-r--r--   1 root root  4693  1月 19  2021 perf.py
drwxr-xr-x   2 root root  4096 10月  4 15:36 __pycache__/
-rw-r--r--   1 root root  9656  1月 19  2021 syscall.py
-rw-r--r--   1 root root 40588  1月 19  2021 table.py
-rw-r--r--   1 root root  1604  1月 19  2021 tcp.py
-rw-r--r--   1 root root  9102  1月 19  2021 usdt.py
-rw-r--r--   1 root root  4904  1月 19  2021 utils.py
-rw-r--r--   1 root root    23  1月 19  2021 version.py

根据文件时间可以确定,确实都是21年的老库,遂进行替换,先查找bcc源码中的bcc python库:

wj@wj:/usr/share/bcc/examples$ find / -name libbcc.py -ls 2>/dev/null
   408370     16 -rw-rw-r--   1 wj       wj          14561 11月  5 14:44 /home/wj/bcc/build/src/python/bcc-python3/bcc/libbcc.py
   408643     16 -rw-r--r--   1 root     root        14561 11月  5 14:44 /home/wj/bcc/build/src/python/bcc-python3/build/lib/bcc/libbcc.py
   407310     16 -rw-rw-r--   1 wj       wj          14561 11月  5 14:43 /home/wj/bcc/src/python/bcc/libbcc.py
  4496431     16 -rw-r--r--   1 root     root        12951 1月 19  2021 /usr/lib/python3/dist-packages/bcc/libbcc.py

wj@wj:/usr/share/bcc/examples$ cp -r /home/wj/bcc/build/src/python/bcc-python3/bcc/* /usr/lib/python3/dist-packages/bcc/
cp: 无法创建普通文件 '/usr/lib/python3/dist-packages/bcc/containers.py': 权限不够
cp: 无法创建普通文件 '/usr/lib/python3/dist-packages/bcc/disassembler.py': 权限不够
cp: 无法创建普通文件 '/usr/lib/python3/dist-packages/bcc/__init__.py': 权限不够
cp: 无法创建普通文件 '/usr/lib/python3/dist-packages/bcc/libbcc.py': 权限不够
cp: 无法创建普通文件 '/usr/lib/python3/dist-packages/bcc/perf.py': 权限不够
cp: 无法创建普通文件 '/usr/lib/python3/dist-packages/bcc/syscall.py': 权限不够
cp: 无法创建普通文件 '/usr/lib/python3/dist-packages/bcc/table.py': 权限不够
cp: 无法创建普通文件 '/usr/lib/python3/dist-packages/bcc/tcp.py': 权限不够
cp: 无法创建普通文件 '/usr/lib/python3/dist-packages/bcc/usdt.py': 权限不够
cp: 无法创建普通文件 '/usr/lib/python3/dist-packages/bcc/utils.py': 权限不够
cp: 无法创建普通文件 '/usr/lib/python3/dist-packages/bcc/version.py': 权限不够
sudo cp -r /home/wj/bcc/build/src/python/bcc-python3/bcc/* /usr/lib/python3/dist-packages/bcc/

参考:AttributeError: /lib/x86_64-linux-gnu/libbcc.so.0: undefined symbol: bpf_module_create_b-CSDN博客

正常输出

可以看到 内核捕获到了 kprobe__sys_clone 事件,并打印出 Hello, World! 出来。

监控进程切换

//task_switch.py


#!/usr/bin/python
# Copyright (c) PLUMgrid, Inc.
# Licensed under the Apache License, Version 2.0 (the "License")

from bcc import BPF
from time import sleep

b = BPF(src_file="task_switch.c")
b.attach_kprobe(event_re="^finish_task_switch$|^finish_task_switch\.isra\.\d$",
                fn_name="count_sched")

# generate many schedule events
for i in range(0, 100): sleep(0.01)

for k, v in b["stats"].items():
    print("task_switch[%5d->%5d]=%u" % (k.prev_pid, k.curr_pid, v.value))

k.prev_pid :表示上一个进程的 pid

k.curr_pid :表示切换到当前进程 pid

task_switch.c

#include <uapi/linux/ptrace.h>
#include <linux/sched.h>

struct key_t {
    u32 prev_pid;
    u32 curr_pid;
};

BPF_HASH(stats, struct key_t, u64, 1024);
int count_sched(struct pt_regs *ctx, struct task_struct *prev) {
    struct key_t key = {};
    u64 zero = 0, *val;

    key.curr_pid = bpf_get_current_pid_tgid();
    key.prev_pid = prev->pid;

    // could also use `stats.increment(key);`
    val = stats.lookup_or_try_init(&key, &zero);
    if (val) {
        (*val)++;
    }
    return 0;
}

运行输出

wj@wj:/usr/share/bcc/examples/tracing$ sudo python3 task_switch.py 
[sudo] wj 的密码: 
task_switch[  879->    0]=1
task_switch[    0->14938]=2
task_switch[14959->    0]=1
task_switch[    0->14964]=2
task_switch[    0->   71]=2
task_switch[    0->15021]=1
task_switch[14969->14939]=1
task_switch[11713->    0]=1
task_switch[   52->    0]=1
task_switch[    0->  809]=4
task_switch[ 2402->    0]=6
task_switch[  928->    0]=1
task_switch[ 5247->    0]=3
task_switch[    0->  437]=3
task_switch[    0-> 7458]=6
task_switch[    0->14986]=1
task_switch[11411->    0]=3
task_switch[ 2674->    0]=5
task_switch[15064->    0]=1
task_switch[ 8767->    0]=48
task_switch[14939->14969]=1
task_switch[14998->    0]=1
task_switch[    0->14921]=2
task_switch[14986->14959]=2
task_switch[    0->15194]=1
task_switch[    0->   16]=1
task_switch[    0->   15]=14
task_switch[  901->15194]=1
task_switch[   22->    0]=1
task_switch[ 1816->    0]=7
task_switch[    0->   40]=1
task_switch[14959->14986]=1
task_switch[    0->  901]=1
task_switch[14577->    0]=1
task_switch[    0-> 5247]=3
task_switch[   58->    0]=1
task_switch[14938->    0]=2
task_switch[    0->11411]=3
task_switch[   34->    0]=1
task_switch[15194->    0]=2
task_switch[    0->   58]=1
task_switch[    0->   28]=1
task_switch[ 7458->    0]=7
task_switch[    0->15010]=3
task_switch[  926->    0]=1
task_switch[14921->    0]=2
task_switch[   46->    0]=1
task_switch[14964->    0]=3
task_switch[15030->    0]=3
task_switch[   15->    0]=14
task_switch[   40->    0]=1
task_switch[    0->14374]=5
task_switch[    0->15064]=1
task_switch[15129->    0]=1
task_switch[    0-> 8767]=47
task_switch[    0->15129]=1
task_switch[  809->    0]=3
task_switch[14374->    0]=5
task_switch[    0-> 2674]=5
task_switch[    0->   34]=1
task_switch[    0->  926]=1
task_switch[    0->15211]=100
task_switch[14969->    0]=1
task_switch[    0->14969]=1
task_switch[    0->11713]=1
task_switch[  437->    0]=3
task_switch[  835->    0]=11
task_switch[ 2035->    0]=11
task_switch[ 8767->   29]=10
task_switch[    0->14577]=1
task_switch[    0-> 1816]=7
task_switch[    0->14998]=1
task_switch[    0->  928]=1
task_switch[15010->    0]=3
task_switch[    0-> 2402]=6
task_switch[    0->14981]=1
task_switch[    0-> 2142]=1
task_switch[  953->    0]=1
task_switch[   29-> 8767]=10
task_switch[  835-> 8767]=1
task_switch[    0->  835]=12
task_switch[   28->    0]=1
task_switch[    0->  953]=1
task_switch[    0-> 2035]=11
task_switch[14981->14964]=1
task_switch[  809-> 7458]=1
task_switch[ 1702->    0]=1
task_switch[    0->   52]=1
task_switch[   16->    0]=1
task_switch[    0->  879]=1
task_switch[    0->15030]=3
task_switch[15211->    0]=100
task_switch[    0->   22]=1
task_switch[   71->    0]=2
task_switch[15021->    0]=1
task_switch[    0->   46]=1
task_switch[ 2142->    0]=1

监控CPU直方图

tools/cpudist: Summarize on- and off-CPU time per task as a histogram.

tools/cpudist:将每个任务的 CPU 开启和关闭时间总结为直方图。

wj@wj:/usr/share/bcc/tools$ sudo python3 ./cpudist
Tracing on-CPU time... Hit Ctrl-C to end.
^C
     usecs               : count     distribution
         0 -> 1          : 5        |*                                       |
         2 -> 3          : 38       |********                                |
         4 -> 7          : 106      |***********************                 |
         8 -> 15         : 134      |******************************          |
        16 -> 31         : 156      |***********************************     |
        32 -> 63         : 177      |****************************************|
        64 -> 127        : 142      |********************************        |
       128 -> 255        : 63       |**************                          |
       256 -> 511        : 79       |*****************                       |
       512 -> 1023       : 21       |****                                    |
      1024 -> 2047       : 7        |*                                       |
      2048 -> 4095       : 1        |                                        |
      4096 -> 8191       : 1        |                                        |
wj@wj:/usr/share/bcc/tools$ 

缓存命中率监控:cachestat

  • tools/cachestat: Trace page cache hit/miss ratio. Examples.

sudo python3 ./cachestat

cachetop

sudo python3 ./cachetop

以上都是自定义在 examples 和 tools 中的工具。如果需要自己开发 bcc 程序,那应该怎么样使用呢?可以参考如下链接。

BCC开发指南

https://github.com/iovisor/bcc/blob/master/docs/tutorial_bcc_python_developer.md

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1174809.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

英语——分享篇——每日200词——201-400

201——feel——[fi:l]——vt.摸&#xff0c;感觉&#xff0c;认为&#xff1b;n.感觉&#xff0c;触摸——feel——f斧头(编码)ee眼睛(象形)l棍子(编码)——斧头用眼看&#xff0c;棍子用手摸——The metal felt smooth and cold.——这种金属摸起来冰冷而光滑。 202——cleve…

SpringBoot项目打包与运行

1.clean生命周期 说明&#xff1a;为了项目能够正确打包&#xff0c;先清理打包文件。 2.package生命周期 说明&#xff1a;打包后生成以下目录。 2.1问题 说明&#xff1a;springboot_08_ssmp-0.0.1-SNAPSHOT.jar中没有主清单属性。 2.2解决 说明&#xff1a;注释skip&…

[LeetCode]-160. 相交链表-141. 环形链表-142.环形链表II-138.随机链表的复制

目录 160.相交链表 题目 思路 代码 141.环形链表 题目 思路 代码 142.环形链表II 题目 思路 代码 160.相交链表 160. 相交链表 - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/intersection-of-two-linked-lists/description/ 题目 给你两个…

Node问题:如何正确安装nvm?Mac和Win双教程!

前端功能问题系列文章&#xff0c;点击上方合集↑ 序言 大家好&#xff0c;我是大澈&#xff01; 本文约1700字&#xff0c;整篇阅读大约需要3分钟。 本文主要内容分三部分&#xff0c;第一部分是需求分析&#xff0c;第二部分是实现步骤&#xff0c;第三部分是问题详解。 …

为什么有了MAC地址,还需要IP地址?

解释 搞懂这个问题&#xff0c;首先需要了解交换机的功能 交换机内部有一张MAC地址映射表&#xff0c;记录着MAC地址和端口的对应关系。 如果A要给B发送一个数据包&#xff0c;构造如下格式的数据结构&#xff1a; 到达交换机时&#xff0c;交换机内部通过自己维护的 MAC 地…

ConcurrentHashMap是如何实现线程安全的

目录 原理&#xff1a; 初始化数据结构时的线程安全 put 操作时的线程安全 原理&#xff1a; 多段锁cassynchronize 初始化数据结构时的线程安全 在 JDK 1.8 中&#xff0c;初始化 ConcurrentHashMap 的时候这个 Node[] 数组是还未初始化的&#xff0c;会等到第一次 put() 方…

常见面试题-MySQL专栏(三)MVCC、BufferPool

typora-copy-images-to: imgs 了解 MVCC 吗&#xff1f; 答&#xff1a; MVCC&#xff08;Multi-Version Concurrency Control&#xff09; 是用来保证 MySQL 的事务隔离性的&#xff0c;对一行数据的读和写两个操作默认是不会通过加锁互斥来保证隔离性&#xff0c;避免了频…

【Mybatis小白从0到90%精讲】07:Mybatis 传递参数方式详解

文章目录 前言一、序号传参二、@Param注解传参三、对象传参单个参数多个参数四、万能Map传参单个参数多个参数总结前言 Mybatis传递参数的方式,或者说 获取参数的方式,非常灵活,支持多种方式,所以为了彻底搞懂,今天我们来总结一下Mybatis传参方式! 一、序号传参 Mapper接…

老电脑升级内存、固态硬盘、重新装机过程记录

基础环境&#xff1a; 电脑型号&#xff1a;联想XiaoXin700-15ISK系统版本&#xff1a;Windows10 家庭中文版 版本22H2内存&#xff1a;硬盘&#xff1a; 升级想法&#xff1a; 内存升级&#xff0c;固态硬盘升级&#xff0c;系统重装&#xff08;干净一点&#xff09; 升级内存…

c++类和对象(八) static成员 友元

1.1 概念 声明为static的类成员称为类的静态成员&#xff0c;用static修饰的成员变量&#xff0c;称之为静态成员变量&#xff1b;用static修饰的成员函数&#xff0c;称之为静态成员函数。静态成员变量一定要在类外进行初始化。 面试题&#xff1a;实现一个类&#xff0c;计算…

Leetcode—187.重复的DNA序列【中等】

2023每日刷题&#xff08;二十&#xff09; Leetcode—187.重复的DNA序列 实现代码 class Solution { public:const int L 10;vector<string> findRepeatedDnaSequences(string s) {unordered_map<string, int> str;vector<string> ans;int len s.size()…

第 370 场 LeetCode 周赛题解

A 找到冠军 I 枚举求强于其他所有队的队 class Solution { public:int findChampion(vector<vector<int>> &grid) {int n grid.size();int res 0;for (int i 0; i < n; i) {int t 0;for (int j 0; j < n; j)if (j ! i)t grid[i][j];if (t n - 1) …

Linux环境基础开发工具使用(二)

&#x1f4d8;北尘_&#xff1a;个人主页 &#x1f30e;个人专栏:《Linux操作系统》《经典算法试题 》《C》 《数据结构与算法》 ☀️走在路上&#xff0c;不忘来时的初心 文章目录 一、Linux项目自动化构建工具-make/Makefile1、背景2、实例代码3、依赖关系4、依赖方法5、原理…

精品基于Python的图书借阅归还管控系统

《[含文档PPT源码等]精品基于Python的图书管控系统》该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程、包运行成功&#xff01; 软件开发环境及开发工具&#xff1a; 开发语言&#xff1a;python 使用框架&#xff1a;Django 前端技术&#xff1a;Ja…

从NetSuite Payment Link杂谈财务自动化、数字化转型

最近在进行信息化的理论学习&#xff0c;让我有机会跳开软件功能&#xff0c;用更加宏大的视野&#xff0c;来审视我们在哪里&#xff0c;我们要到哪去。 在过去20多年&#xff0c;我们的财务软件经历了电算化、网络化、目前处于自动化、智能化阶段。从NetSuite这几年的功能发…

理解 fopen的 rwa r+w+a+ 参数含义

tags: C categories: C 理解 一图胜千言 我愿称之为最强 c - Difference between r and w in fopen() - Stack Overflow; 需要注意里面的a和 a, 区别在于 a 不可以读而 a可以读. c - Difference between r and w in fopen() - Stack Overflow; ModeReadWriteCreate New Fil…

【Java基础】内部类

一、什么是内部类 在一个类的里面&#xff0c;再定义一个类。&#xff08;在一个类的内部定义的类&#xff0c;称为内部类&#xff09; 举例:在A类的内部定义B类&#xff0c;B类就被称为内部类 二、内部类的访问特点 1.内部类可以直接访问外部类的成员&#xff0c;包括…

数据处理中的中心化

数据处理中的中心化&#xff0c;就是将原数据减去平均值&#xff0c;得到新的数据&#xff0c;新的数据的平均值为0。 假设原数据是x&#xff08;x可以是多维的&#xff09;&#xff0c;其平均值是&#xff0c;新的数据&#xff0c;那么新数据的平均值是为0的。下面证明下&…

[LeetCode] 2.两数相加

一、题目描述 给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。 请你将两个数相加&#xff0c;并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外&#xff0c;这两个…

网络编程 - HTTP协议

目录 HTTP协议格式 一&#xff0c;请求格式 1.1 URL的基本格式 1.2 方法(method) 1.3 请求头header 二&#xff0c;响应格式 2.1 状态码 HTTP协议格式 HTTP协议与之前讲的TCP/IP协议不同&#xff0c;HTTP协议要分为两个部分——请求和响应&#xff0c;也就是一种"一…