【记录 bpftrace】

一、bpftrace简介
bpftrace 是基于ebpf内核vm扩展出来的trace工具。

    bpftrace 是 Linux 高级追踪工具和语言。该工具基于 eBPF 和 BBC 实现了通过探针机制采集内核和程序运行的信息,然后用图表等方式将信息展示出来,帮助开发者找到隐藏较深的 Bug、安全问题和性能瓶颈。

## bpftrace进行内核跟踪
#### bpftrace 命令行操作
单行命令工具:

bpftrace -e 'program'


bpftrace直接跟-e选项后面加单行命令,一些示例,比如:

bpftrace -e 'BEGIN { printf("Hello world!\n"); }'
bpftrace -e 'kprobe:vfs_read { @[tid] = count();}'
bpftrace -e 'kprobe:vfs_read  /pid == 123/ { @[tid, comm] = count();}'
bpftrace -e 't:block:block_rq_insert { @[kstack] = count(); }'


单行命令工具可以按ctrl-c也结束,只有结束后才会打印输出结果。

#### bpftrace 编写脚本工具
bpftrace支持脚本编写,只需要在其实出添加#!/usr/local/bin/bpftrace,会被认为是一个bpftrace脚本。


#!/usr/local/bin/bpftrace
// this program times vfs_read()
kprobe:vfs_read
{
    @start[tid] = nsecs;
} 
retprobe:vfs_read
/@start[tid]/
{
    $duration_us = (nsecs - @start[tid]) / 1000;
    @us = hist($duration_us);
    delete(@start[tid]);
}



#### debug调试

bpftrace -d
bpftrace -v


bpftrace语法结构
bpftrace编程语言参考了awk的语法,基础结构:

probes /filter/ { actions }


它是一种事件驱动的运行方式。
probes表示的就是事件,包括tracepoint、kprobe、kretprobe、uprobe等等。除了这些跟踪点,还有两个特殊的事件BEGIN、END,用于在脚本开始处和结束处执行。

filter表示的是过滤条件,当一个事件触发时,会先判断该条件,满足条件才会执行后面的action行为。

action表示的具体执行的操作。
示例:

bpftrace -e 'kprobe:vfs_read  /pid == 123/ { @[tid, comm] = count();}'


#### bpftrace 脚本变量

内部变量(built-in)

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中获取函数返回值

备注:

bpftrace -lv tracepoint:syscalls:sys_enter_read

这个命令-lv可以用来查看一个tracepoint对应的参数都有哪些。

自定义临时变量
以"$"标志起始来定义和引用一个变量

Map变量
map变量是用于内核向用户空间传递数据的一种存储结构,定义方式是以"@"符号作为其实标记。
这个map可以有单个key或者多个key:

@path[tid] = nsecs
@path[pid, $fd] =nsecs

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

#### 函数

exit():退出bpftrace程序
str(char *):转换一个指针到string类型
system(format[, arguments ...]):运行一个shell命令
join(char *str[]):打印一个字符串列表并在每个前面加上空格,比如可以用来输出args->argv
ksym(addr):用于转换一个地址到内核symbol
kaddr(char *name):通过symbol转换为内核地址
print(@m [, top [, div]]):可选择参数打印map中的top n个数据,数据可选择除以一个div值


#### map函数
bpftrace内构的一些map函数,用于传递数据给map变量,注意接收他们的变量是map类型。常用的包括:

count():用于计算次数
sum(int n):用于累加计算
avg(int n):用于计算平均值
min(int n):用于计算最小值
max(int n):用于计算最大值
hist(int n):数据分布直方图(范围为2的幂次增长)
lhist(int n):数据线性直方图
delete(@m[key]):删除map中的对应的key数据
clear(@m):删除map中的所有数据
zero(@m):map中的所有值设置为0



#### 附件
常用的一些单行命令示例:

bpftrace -e 'tracepoint:block:block_rq_i* { @[probe] = count(); } interval:s:1 { print(@); clear(@); }'
bpftrace -e 'tracepoint:syscalls:sys_exit_read /args->ret > 0/ { @bytes = sum(args->ret); }'
bpftrace -e 'tracepoint:syscalls:sys_exit_read { @ret = hist(args->ret); }'
bpftrace -e 'tracepoint:syscalls:sys_exit_read { @ret = lhist(args->ret, 0, 1000, 100); }'
bpftrace -e 'tracepoint:syscalls:sys_exit_read /args->ret < 0/ { @[- args->ret] = count(); }'
bpftrace -e 'kprobe:vfs_* { @[probe] = count(); } END { print(@, 5); clear(@); }'
bpftrace -e 'kprobe:vfs_read { @start[tid] =nsecs; } kretprobe:vfs_read /@start[tid]/ { @ms[comm] = sum(nsecs - @start[tid]); delete(@start[tid]); } END { print(@ms, 0, 1000000); clear(@ms); clear(@start); }'
bpftrace -e 'k:vfs_read { @[pid] = count(); }'
bpftrace -e 'tracepoint:syscalls:sys_enter_execve { printf("%s -> %s\n", comm, str(args->filename)); }'
bpftrace -e 'tracepoint:syscalls:sys_enter_execve { join(args->argv); }'
bpftrace -e 'tracepoint:syscalls:sys_enter_openat { printf("%s %s\n", comm, str(args->filename)); }'
bpftrace -e 'tracepoint:raw_syscalls:sys_enter {@[comm] = count(); }'
bpftrace -e 'tracepoint:syscalls:sys_enter_* {@[probe] = count(); }'
bpftrace -e 'tracepoint:raw_syscalls:sys_enter {@[pid, comm] = count(); }'
bpftrace -e 'tracepoint:syscalls:sys_exit_read /args->ret/ { @[comm] = sum(args->ret); }'
bpftrace -e 'tracepoint:syscalls:sys_exit_read { @[comm] = hist(args->ret); }'
bpftrace -e 'tracepoint:block:block_rq_issue { printf("%d %s %d\n", pid, comm, args->bytes); }'
bpftrace -e 'software:major-faults:1 { @[comm] = count(); }'
bpftrace -e 'software:faults:1 { @[comm] = count(); }'
bpftrace -e 'tracepoint:syscalls:sys_enter_clone { printf("-> clone() by %s PID %d\n", comm, pid); } tracepoint:syscalls:sys_exit_clone { printf("<- clone() return %d, %s PID %d\n", args->ret, comm, pid); }'
bpftrace -e 'tracepoint:syscalls:sys_enter_setuid { printf("setuid by PID %d (%s), UID %d\n", pid, comm, uid); }'
bpftrace -e 'tracepoint:syscalls:sys_exit_setuid { printf("setuid by %s returned %d\n", comm, args->ret); }'
bpftrace -e 'tracepoint:block:block_rq_insert { printf("Block I/O by %s\n", kstack); }'
bpftrace -e 'tracepoint:syscalls:sys_enter_connect /pid == 123/ { printf("PID %d called connect()\n", $1); }'
bpftrace -e 'tracepoint:timer:hrtimer_start { @[ksym(args->function)] = count(); }'
bpftrace -e 't:syscalls:sys_enter_read { @reads = count(); } interval:s:5 { exit(); }'
bpftrace -e 'kprobe:vfs_read {@ID = pid;} interval:s:2 {printf("ID:%d\n", @ID);}'

相关推荐

  1. 记录 bpftrace

    2024-01-13 08:54:05       38 阅读
  2. HSQL 记录

    2024-01-13 08:54:05       43 阅读
  3. bug 记录

    2024-01-13 08:54:05       38 阅读
  4. QT 记录

    2024-01-13 08:54:05       44 阅读
  5. QtConcurrent记录

    2024-01-13 08:54:05       38 阅读
  6. 学习记录————

    2024-01-13 08:54:05       43 阅读
  7. Vue<span style='color:red;'>记录</span>

    Vue记录

    2024-01-13 08:54:05      33 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-01-13 08:54:05       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-13 08:54:05       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-13 08:54:05       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-13 08:54:05       18 阅读

热门阅读

  1. node连接Mysql失败

    2024-01-13 08:54:05       35 阅读
  2. Dubbo的服务降级策略剖析

    2024-01-13 08:54:05       39 阅读
  3. vue表格插件vxe-table导出 excel

    2024-01-13 08:54:05       40 阅读
  4. Spark十:故障排除

    2024-01-13 08:54:05       31 阅读
  5. static关键字的作用

    2024-01-13 08:54:05       43 阅读
  6. C语言-蓝桥杯算法提高VIP-产生数

    2024-01-13 08:54:05       35 阅读
  7. xdoj购票系统(多次循环)

    2024-01-13 08:54:05       31 阅读
  8. VSCODE插件开发API

    2024-01-13 08:54:05       29 阅读
  9. 孩子兄弟结构体【】

    2024-01-13 08:54:05       37 阅读
  10. Apache配置ssl证书-实现https访问

    2024-01-13 08:54:05       30 阅读