bpftrace可以用来追踪系统调用,在分析问题的时候会用到。 可以参考jvns的这篇文章1

安装

参考安装说明2, 使用手册3

sudo snap install --devmode bpftrace
sudo snap connect bpftrace:system-trace
sudo apt install linux-headers-$(uname -r)
export BPFTRACE_KERNEL_SOURCE=/usr/src/linux-headers-$(uname -r)

使用

执行的命令

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_* {@[comm] = count()}'

# 按进程
bpftrace -e 'tracepoint:raw_syscalls:sys_enter {@[pid, comm] = count()}'

按程序统计读取字节数

bpftrace -e 'tracepoint:syscalls:sys_exit_read /args->ret/{@[comm] = sum(args->ret)}'

read大小分布

bpftrace -e 'tracepoint:syscalls:sys_exit_read /args->ret/{@[comm] = hist(args->ret)}'

vfs_read 计时

bpftrace -e 'kprobe:vfs_read{@start[comm]=nsecs;} kretprobe:vfs_read /@start[comm]/ {$duration = (nsecs - @start[comm]) / 1000; @us = hist($duration); delete(@start[comm])
}'


bpftrace -lv t:syscalls:sys_enter_read

一个程序如果输出都被重定向到/dev/null了,不重启的情况下,依然是可以用bpftrace看到stderr内容的

python x.py >/dev/null 2>&1 

bpftrace -e 'tracepoint:syscalls:sys_enter_write /pid == $1/
	{ printf("<%s>\n", str(args->buf, args->count)); }' `pgrep -f x.py`

统计各个程序发包的数量

bpftrace -e 'k:sock_sendmsg {@[comm] = count()}'

跟踪用户程序

gcc -g 1.c -o 1
bpftrace -e 'uprobe:./1:main {printf("%d", arg0); join(arg1)}'
bpftrace -e 'uretprobe:./1:main {printf("ret: %d\n", retval); }'

追踪bash

sudo bpftrace -e 'uretprobe:/bin/bash:readline {printf("%d execute %s\n", uid, str(retval))}'