首页 > 其他分享 >bcc 语法

bcc 语法

时间:2022-10-06 18:00:07浏览次数:45  
标签:函数 trace bpf BPF bcc 语法 key perf

基本结构

#导入库
from bcc import BPF
#使用BPF()执行bpf代码
BPF(text="""
#C语言代码段
"""
)
#对bpf的处理代码

C语言代码编写

不需要写main函数,目前知道可以写两种函数,以“kprobe__”开头的函数和自定义函数。bpf函数至少要包含一个参数“ctx”,即使不使用也应该存在,可以声明为“void *ctx”。

以“kprobe__”开头的函数,其余的名称部分表示要检测的函数,比如“kprobe__sys_clone”,表示要检测的函数是“sys_clone()”。例:

from bcc import BPF
#
BPF(text=
"""
int kprobe__sys_clone(void *ctx) 
{
    bpf_trace_printk("Hello, World!\\n"); 
    return 0; 
}
"""
).trace_print()

自定义函数需要另外指定其要关联的事件或其他,由”attach_*“类的函数实现。举例如下:

bpf_text="""
int hello(void *ctx) {
    bpf_trace_printk("Hello, World!\\n");
    return 0;
}
"""
b = BPF(text=bpf_text)
#将“hello()”函数关联clone函数。
b.attach_kprobe(event=b.get_syscall_fnname("clone"), fn_name="hello")
 
print("%-18s %-16s %-6s %s" % ("TIME(s)", "COMM", "PID", "MESSAGE"))
while 1:
    try:
        (task, pid, cpu, flags, ts, msg) = b.trace_fields()
    except ValueError:
        continue
    print("%-18.9f %-16s %-6d %s" % (ts, task, pid, msg))

部分bpf函数说明

bpf_trace_printk() : 相当于精简版的printk,将数据输出到trace_pipe(/sys/kernel/debug/tracing/trace_pipe),此函数有一定限制,最大3个参数,一个%s,但是由于trace_pipe是全局共享的,对于并发程序而言有冲突,因此更建议使用BPF_PERF_OUTPUT()。

BPF_HASH() : 创建散列,例如“BPF_HASH(test)”创建了一个名为test的散列,相关操作函数如下:

  1. update() : 更新散列的内容,例如“u64 key=0,num=1;test.update(&key,&num);”,将num的值与key关联起来。

  2. delete() : 删除指定key,例如“u64 key=0;test.delete(&key);”,即删除key=0的列。

  3. lookup() : 获取指定key的值,如果对应的key没有值,则返回"NULL"。例如“u64 key=0,num;num=test.lookup(&key)”,获取key等于0的列的值。

bpf_ktime_get_ns(): 获取当前时间,精确到纳秒。例如“u64 ts=bpf_ktime_get_ns()”。

BPF_PERF_OUTPUT(): 命名输出管道。例如“BPF_PERF_OUTPUT(test)”,命名了一个名为"test"的管道。操作函数如下:

  1. perf_submit() : 将数据输出到perf环缓冲区读取。例如“test.perf_submit(ctx,&data,sizeof(data))”。ctx为函数的固定参数,data为自定义数据结构,最后一个参数为data的大小。

bpf_get_current_pid_tgid() : 获取当前进程pid和tgid,其中pid位于低32位,tgid位于高32位,对于多线程程序而言,tgid是相同的,需要用pid来区分。

bpf_get_current_comm() : 获取当前进程的进程名。例:

#include <linux/sched.h>
int hello()
{
    char comm[TASK_COMM_LEN];
    bpf_get_current_comm(&comm,sizeof(comm));
    return 0;
}

部分bcc函数说明

BPF() : 用于执行bpf程序的主要函数,使用方法“b = BPF(text=C代码文本)”。将会返回一个引用,可以用通过此引用控制bpf程序。部分操作函数如下:

  1. trace_print() : 打印出trace_pipe管道的内容。例如“b.trace_print()”。

  2. get_syscall_fnname() : 获取指定系统调用函数名。例如“b.get_syscall_fnname("clone")”,返回“__x64_sys_clone”。

  3. attach_kprobe() : 将函数与内核事件关联,用于检测指定事件。例如“b.attach_kprobe(event=b.get_syscall_fnname("clone"), fn_name="hello")”,event指定事件,fn_name,指定bpf代码里的函数名,比如这里就是hello()函数。

  4. trace_fields() : 从trace_pipe返回一组固定格式的字段,与trace_print()类似,但是官方建议使用 BPF_PERF_OUTPUT()。使用方法“(task, pid, cpu, flags, ts, msg) = b.trace_fields()”,其中msg为bpf代码中向trace_pipe输出的数据。

  5. open_perf_buffer() : 打开perf缓冲区,并指定一个回调函数,当有数据时,自动使用该函数处理。

  6. perf_buffer_poll() : 等待perf缓冲区的内容。

  7. event() : 获取从 BPF_PERF_OUTPUT()传递的事件。使用方法如下所示:

from bcc import BPF
 
b = BPF(text="""
//。。。bpf代码。。。
BPF_PERF_OUTPUT(events);
//。。。bpf代码。。。
"""
)
#。。。bcc代码。。。
 
#定义回调函数
def print_event(cpu, data, size)
    event = b["events"].event(data) #获取由bpf函数perf_submit输出的数据
    #。。。代码省略。。。
 
# 循环并回调到print_event
b["events"].open_perf_buffer(print_event)
while 1:
    b.perf_buffer_poll()

标签:函数,trace,bpf,BPF,bcc,语法,key,perf
From: https://www.cnblogs.com/linhaostudy/p/16758118.html

相关文章

  • bcc之hello world
    bcc代码——Hello,world1、简单监控clone()系统调用,将相关的信息打印出来#!/usr/bin/pythonfrombccimportBPFBPF(text="""intkprobe__sys_clone(void*ctx){ bpf......
  • Java刷题语法整理
    输入输出问题汇总BufferedReader/Scanner输入//BufferedReader类位于java.io包中,要引入java.ioimportjava.io.BufferedReader;importjava.io.InputStreamReader;B......
  • MySQL 基础语法
    SELECT基础用法SELECTname,ageFROMuserDISTINCT——对检索结果去重应用于所有列而不仅是它后面的一列,所有列的值都不同才会被认为不同。SELECTDISTI......
  • Linux正则表达式 - 语法
    正则表达式- 语法摘自:https://www.runoob.com/regexp/regexp-syntax.html 正则表达式(regularexpression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是......
  • 1.5 基本语法_循环结构 for ... in... 循环,while 循环,break与continue
    #for... in... 遍历循环foriinrange(1,6):#数字遍历print(i)forchin'Python':#字符串遍历print(ch)#循环结构的while......
  • 1.3 基本语法_输入函数input
    age=input('你几岁了?')print(age)'''由计算机提问而得到的任何回答,统统为字符串str类型'''print(type(age))age=int(age)#类型转换"机"print(type(ag......
  • MarkDown语法
    MarkDown语法标题一级标题:#文本二级标题:##文本...依次类推注意:‘#’号和文本之间要加一个‘空格’字体粗体:**粗体**斜体:*斜体*粗斜体:***粗斜体***删除线:~~删......
  • 1.2 基本语法_数据类型
    #数据类型 '''字符串类型str:可以是单引号,双引号和3引号'''a='HELLO'b="HELLO"c='''HELLO'''d="""HELLO"""print(a)print(b)print(c)print(d)age=20print......
  • iptables语法
    ####filter是最常用的#iptables-nvL查看默认规则#serviceiptablesrestart重启iptables服务#systemctlrestartiptables重启iptables服务#serviceiptablessave......
  • MarkDown基本语法
    MarkDown学习标题:(一个#号加空格代表一个级别标题)字体:粗体:两边加两个*号斜体:两边加一个*号斜体加粗:两边加三个*号删除线:两边加两个波浪号~引用1.大于号>加空格分......