09月29, 2022

bpftrace 入门(6) 控制语句

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

本文链接:http://www.thinkinpython.com/post/bpftrace_tutorial_6.html

-- EOF --