bpftrace

1. bpftrace 介绍 

        bpftrace 是一个基于 eBPF (Extended Berkeley Packet Filter) 的高级工具,用于动态跟踪系统的各种事件和性能指标。它可以在不需要重新编译内核模块的情况下,以一种安全、高效的方式执行代码,从而提供了丰富的系统跟踪和性能分析能力。        

2. bpftrace 使用

2.1. 语法结构

bpftrace 语法结构:

probes /filter/ { action }

probes:事件,tracepoint, kprobe, kretprobe, uprobe。两个特殊事件 BEGIN/END,用于脚本开始和结束处执行。

filter:过滤条件,事件触发时,判断条件,例如:/pid == 3245/,表示pid 为3245的进程执行。

action :具体执行的操作,例如:{ printf("close\n");} 打印close

2.2. probes

2.3. bpftrace 变量

内置变量

bpftrace 脚本常用变量如下:

uid:用户id。

tid:线程id

pid:进程id。

cpu:cpu id。

cgroup:cgroup id.

probe:当前的trace点。

comm:进程名字。

nsecs:纳秒级别的时间戳。

kstack:内核栈描述

curtask:当前进程的task_struct地址。

args:获取该kprobe或者tracepoint的参数列表

arg0:获取该kprobe的第一个变量,tracepoint不可用

arg1:获取该kprobe的第二个变量,tracepoint不可用

arg2:获取该kprobe的第三个变量,tracepoint不可用

retval: kretprobe 中获取函数返回值

args->ret: kretprobe 中获取函数返回值

自定义变量

以'$'标志起来定义与引用变量,例如:$idx = 0;

Map 变量

Map 变量是用于内核向用户空间传递数据的一种存储结构,定义方式是以'@'符 号作为标志

@path[tid] = nsecs;

@path[pid, $fd] = nsecs;

Bpftrace 默认在结束时会打印从内核接收到的map变量

内置函数

Function Description

printf("...") Print formatted string

time("...") Print formatted time

join(char *arr[]) Join array of strings with a space

str(char *s [, int length]) Return string from s pointer

buf(void *p [, int length]) Return a hexadecimal string from p pointer

strncmp(char *s1, char *s2, int length) Compares two strings up to length

sizeof(expression) Returns the size of the expression

kstack([limit]) Kernel stack trace up to limit frames

ustack([limit]) User-level stack trace up to limit frames

ksym(void *p) Resolve kernel address to symbol

usym(void *p) Resolve user-space address to symbol

kaddr(char *name) Resolve kernel symbol name to address

uaddr(char *name) Resolve user-space symbol name to address

ntop([int af,]int|char[4:16] addr) Convert IP address data to text

reg(char *name) Return register value

cgroupid(char *path) Return cgroupid for /sys/fs/cgroup/... path

time("...") Print formatted time

system("...") Run shell command

cat(char *filename) Print file content

signal(char[] sig | int sig) Send a signal to the current task

override(u64 rc) Override a kernel function return value

exit() Exits bpftrace

@ = count() Count events

@ = sum(x) Sum the value

@ = hist(x) Power-of-2 histogram for x

@ = lhist(x, min, max, step) Linear histogram for x

@ = min(x) Record the minimum value seen

@ = max(x) Record the maximum value seen

@ = stats(x) Return the count, average, and total for this value

delete(@x[key]) Delete the map element

clear(@x) Delete all keys from the map

2.4. bpftrace 基础用法

1)查找探针

        使用 bpftrace -l 命令可以列出所有的探针。

        比如,我们想检测 tcp的 connect ,可以执行 bpftrace -l "tcp*connect"

        

2)单行语句

#监控 tcpv4 connect
bpftrace -e 'kprobe:tcp_v4_connect { printf("socket connct comm[%s] pid[%d] \n", comm, pid); }'

下图示例为调用 bpftrace 监控 tcp connect 接口是否被调用,在另外一个窗口调用 curl 访问百度时,监测到的结果。  

3)文件形式

除了上面讲的当行语句以外,bpftrace 还支持文件的方式,可以实现复杂度更高的功能。

用法:bpftrace test.bt

#!/usr/sbin/bpftrace

tracepoint:raw_syscalls:sys_enter
/filter/
{

}

 

3. bpftrace 使用实例

使用 bpftrace 监控正在运行的服务器accept 执行的次数。

#!/usr/sbin/bpftrace

BEGIN
{
    printf("Tracing TCP connections for PID %d...\n", $1);
}

kprobe:__sys_accept4
{
    if (pid == $1) {
        @tcp_accepts[tid] = count();
    }
}

END
{
    printf("PID %d: TCP connections:\n", $1);
    print(@tcp_accepts);
}

        可以看到, pid为25822 的服务器接调用了三次 accept 函数。

        bpftrace可以使用系统调用拦截技术(如kprobes、tracepoints等)来截获系统调用和其他事件,然后在事件发生时获取到相关的进程信息,比如PID、进程名称等。

  • 16
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值