bpftrace 也提供了常见的流程控制语句:
- 条件语句
- 循环语句
如果你熟悉 C 或者 Java,它们看起来会相当眼熟。
条件语句
bpftrace 的条件语句与 C 语言完全一样:
if(condition){
statements; //A
} else {
statements; //B
}
当满足条件时执行 A 处语句,否则执行 B 处语句。当然也可能有以下更简单的形式,没有 else
部分:
if(condition){
statements; //A
}
statements; //B
条件满足时执行 A 处语句,然后执行 B 处语句,否则跳过 A 处语句。
多个 if-else
也可能连接在一起:
if(condition){
statements; //A
} else if(condition){
statements; //B
} else if(condition){
statements; //C
} else {
statements; //D
}
下面是一个简单的例子:
#!/bin/env bpftrace
BEGIN{
$score = $1;
if($score >= 90){
$rate = "A";
} else if($score >= 80){
$rate = "B";
} else if($score >= 70){
$rate = "C";
} else if($score >= 60){
$rate = "D";
} else {
$rate = "not passed";
}
printf("your rate: %s\n", $rate);
exit();
}
$score
、$rate
都是局部变量,仅在当前 action 有效。$1
比较特殊,表示 bfptrace 脚本的参数,上面的代码可以保存为文件 if_else.bt,并赋予执行权限,直接在 shell 中运行。
# ./if_else.bt 40
Attaching 1 probe...
your rate: not passed
# ./if_else.bt 60
Attaching 1 probe...
your rate: D
# ./if_else.bt 80
Attaching 1 probe...
your rate: B
不要忘记最后一行exit()
,它可以免去 ctl+c
的麻烦,立刻输出结果。
循环
bpftrace 支持一种最常见的循环形式:
while(condition){
// do something
}
当然,也支持 continue
跳过当前循环剩余部分,break
提前结束循环,这与 C 语言完全相同。需要注意的是,如果用变量作为循环条件,应当初始化正确的值。
# bpftrace -e 'BEGIN{ $i = 0; while($i < 10){printf("i = %d\n", $i); $i++} exit();}'
Attaching 1 probe...
i = 0
i = 1
i = 2
i = 3
i = 4
i = 5
i = 6
i = 7
i = 8
i = 9
另外支持 unroll
,用于执行确定次数的循环, 比如打印 5 次 hello。
# bpftrace -e 'BEGIN{ unroll(5){printf("hello\n");} exit()}'
Attaching 1 probe...
hello
hello
hello
hello
hello