前文提到 bpftrace 的语法:
probe/filter/ {
actions;
}
bpftrace 语法深受 AWK 的影响,{
前的部分相当于 AWK 的 condition,{}
中的部分相当于 AWK 的 action。只不过 bpftrace 执行 actions 的条件是触发 probe 名称指定的事件。
probe
是探针的名称,我们知道内核中函数非常多,为了方便,内核对 probe 做了 namespace 处理,这里的 probe
通常是以冒号 :
分割的一组名称,比如:
tracepoint:timer:tick_stop
kprobe:do_sys_open
显然,最后一部分表示的是函数名称,其他部分则是 namespace,这样做有两点好处:
- 便于查找函数;
- 便于定位不同模块中的同名函数。
对于 uprobe
,其格式可能是这样 :
uprobe:/bin/bash:open
最后一部分依然是准备探测的函数名,第二部分表示用户态程序的名称,其实也是 namespace 的一种情况,因为同样的函数可能在不同的应用程序中存在。
你可以通过: bpftrace -l
打印当前系统支持的所有 probe(但不含 uprobe)。
bpftrace 除了可以监听指定的 probe 事件,还有两个特殊的 probe:
- BEGIN
- END
这与 AWK 类似,它们分别在 bpftrace 程序执行开始、结束时,无条件的执行一些操作,比如完成一些初始化、清理工作等。
#!/bin/env bpftrace
BEGIN{
print("hello world.\n");
}
END {
print("bye world.\n");
}
filter
是可选的,有时候我们只需要探测特定条件下函数的行为,比如参数为某个值的时候,就可以用到 filter,这需要了解 bpftrace 如何访问 probe 的变量,我们稍晚再说。