上一篇我们介绍bcc,这一篇我们介绍一个基于 eBPF的debug神器 bpftrace。从这个名字就可以看出它的作用是trace,还记得上一篇我们是通过代码完成的系统调用openat的监控,其实没有那么麻烦,我们可以直接基于bpftrace 轻松搞定。
首先我们查一下监控点:
# bpftrace -l 'tracepoint:syscalls:*openat*'
tracepoint:syscalls:sys_enter_openat
tracepoint:syscalls:sys_exit_openat
tracepoint:syscalls:sys_enter_openat2
tracepoint:syscalls:sys_exit_openat2
看到了进入openat的两个系统调用sys_enter_openat2 和sys_enter_openat。然后查看一下这个系统的调用参数。
# bpftrace -lv 'tracepoint:syscalls:sys_enter_openat2'
tracepoint:syscalls:sys_enter_openat2
int __syscall_nr;
int dfd;
const char * filename; //文件名,请记住这个参数
struct open_how * how;
size_t usize;
那么就简单了,我们可以直接基于bpftrace 监控这个两个系统调用(用逗号分割)。
bpftrace -e 'tracepoint:syscalls:sys_enter_openat2,tracepoint:syscalls:sys_enter_openat { printf("%d %s %s \n", pid, comm, str(args->filename)); }'
打印pid和comm(命令),这两个是bpftrace自带的,后面通过str 方法将指针filename转出字符串。后面的printf 就是C的语法风格。
当面我们执行这个命令行,在另外一个窗口cat 一个文件,就可以看到下面的一行输出了
59491 cat /tmp/a
prefect ,是不是比上一篇更加简单。
万变不离其宗,原理还是一样的,我们看一下bpftrace的原理,是不是和普通的ebpf程序没有两样,而且它也用到了上一篇所说的 bcc。
不仅如此,bpftrace还可以debug golang代码,这个下一篇我们接着聊!