bcc学习总结一

10 篇文章 0 订阅
7 篇文章 0 订阅

基本结构

#导入库
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()

     

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: LabVIEW是一种基于图形化编程环境的软件开发工具,用于数据采集、控制系统和实验室测量以及其他工程应用。BCC校验是一种二进制校验方法,用于检测数据在传输过程中的错误。 在LabVIEW中,我们可以使用内置的函数和工具来实现BCC校验。首先,我们需要将待发送的数据转换为二进制形式。然后,我们可以使用逻辑门函数来实现BCC校验。 BCC校验的原理是通过对数据进行异或运算来计算校验位。首先,将所有数据字节进行异或运算,得到一个校验字节。然后,将该校验字节添加到数据中,一起发送。 在LabVIEW中,我们可以使用逻辑门函数XOR来实现异或运算。我们将所有的数据字节输入到XOR函数中,并将其输出连接到校验位的输出。然后,我们可以将校验位添加到数据中,准备发送。 另外,在接收端,我们可以使用相同的方法进行BCC校验。将接收到的数据字节输入到XOR函数中,并将其输出与接收到的校验位进行比较。如果两者相等,则说明数据在传输过程中没有发生错误。 总结来说,LabVIEW可以通过使用逻辑门函数实现BCC校验。通过将数据字节输入到XOR函数中进行异或运算,我们可以计算出校验位。在发送端,将校验位添加到数据中一起发送。在接收端,将接收到的数据字节和校验位输入到XOR函数中,进行比较来检测传输错误。这样可以保证数据在传输过程中的准确性。 ### 回答2: LabVIEW BCC校验是一种用于检测数据传输错误的校验方法。BCC是“纵向冗余校验”的缩写,它通过对数据进行逐位异或操作来计算校验和。 LabVIEW BCC校验的原理是将要传输的数据的每一位与校验位进行异或操作,得到一个校验和。在接收端,将接收到的数据的每一位与校验位再进行异或操作,如果得到的结果为0,则说明数据传输没有错误。 具体的实现步骤如下: 1. 将要传输的数据划分为若干个字节,并按照字节顺序进行传输。 2. 在发送端,对每个字节进行异或操作,得到一个校验和。 3. 将校验和添加到发送数据的末尾。 4. 在接收端,对接收到的数据的每个字节进行异或操作,并将得到的结果与校验和进行比较。 5. 如果得到的结果与校验和相等,说明数据传输没有错误;否则,说明数据传输存在错误。 LabVIEW BCC校验方法简单且效率高,但存在一定的局限性,如只能检测单比特错误和偶数比特错误,对于其他错误类型无法有效检测。因此,在进行数据传输时,建议结合其他校验方法,如CRC校验等,以提高校验的准确性和安全性。 ### 回答3: LabVIEW是一种基于图形化编程的软件开发平台,用于数据采集、控制系统和仪器交互等应用。BCC(Block Check Character)校验是一种用于检测数据传输错误的方法。 在LabVIEW中,实现BCC校验可以通过以下步骤进行: 1. 首先,将要发送的数据分成若干块,并计算每个数据块的异或值。 2. 将计算得到的异或值作为BCC校验码添加到发送数据的末尾。注意,BCC校验码的计算不包括校验码本身,即不将BCC校验码计算在内。 3. 将包含BCC校验码的数据发送给接收端。 在接收端,进行BCC校验的步骤如下: 1. 接收到数据后,将除最后一个字节外的所有数据进行异或操作,得到接收数据的BCC校验码。注意,不计算校验码本身。 2. 将计算得到的BCC校验码与接收数据的最后一个字节进行比较。 3. 如果两者相等,则说明数据传输没有错误;如果两者不相等,则说明数据传输存在错误。 通过实现这些步骤,LabVIEW可以通过BCC校验来检测数据传输过程中是否出现错误。这种校验方法简单有效,适用于大多数基本数据传输应用。但请注意,BCC校验方法不能纠正错误,只能检测错误的存在。如果需要更高的数据传输可靠性,可以考虑使用其他可纠错的校验方法,如CRC(循环冗余校验)。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值