bpftrace可以用来追踪系统调用,在分析问题的时候会用到。 可以参考jvns的这篇文章1
安装
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))}'