systemtap probe point followed by ! or ? or if (expr)

4 minute read

背景

首先截取 man stapprobes 中的一段介绍 :

       However,  a  probe point may be followed by a "?" character, to indicate that it is optional, and that no error  
       should result if it fails to resolve.  Optionalness passes down through all levels of alias/wildcard expansion.  
       Alternately,  a probe point may be followed by a "!" character, to indicate that it is both optional and suffi-  
       cient.  (Think vaguely of the Prolog cut operator.) If it does resolve, then no further  probe  points  in  the  
       same comma-separated list will be resolved.  Therefore, the "!"  sufficiency mark only makes sense in a list of  
       probe point alternatives.  
  
       Additionally, a probe point may be followed by a "if (expr)" statement, in order to  enable/disable  the  probe  
       point  on-the-fly. With the "if" statement, if the "expr" is false when the probe point is hit, the whole probe  
       body including alias’s body is skipped. The condition is stacked up through all levels of alias/wildcard expan-  
       sion. So the final condition becomes the logical-and of conditions of all expanded alias/wildcard.  
  
       These  are  all  syntactically  valid probe points.  (They are generally semantically invalid, depending on the  
       contents of the tapsets, and the versions of kernel/user software installed.)  
  
              kernel.function("foo").return  
              process("/bin/vi").statement(0x2222)  
              end  
              syscall.*  
              sys**open  
              kernel.function("no_such_function") ?  
              module("awol").function("no_such_function") !  
              signal.*? if (switch)  
              kprobe.function("foo")  

正常情况下, 如果probe point在路径中搜索不到, 会报错, 如下notexists这个point不存在, 所以报错了.

[root@db-172-16-3-39 ~]# stap --vp 5 -e "probe notexists { exit() }"  
Parsed kernel "/lib/modules/2.6.18-348.12.1.el5/build/.config", containing 1977 tuples  
Parsed kernel /lib/modules/2.6.18-348.12.1.el5/build/Module.symvers, which contained 3546 vmlinux exports  
Searched: " /usr/share/systemtap/tapset/x86_64/*.stp ", found: 4, processed: 4  
Searched: " /usr/share/systemtap/tapset/*.stp ", found: 81, processed: 81  
Pass 1: parsed user script and 85 library script(s) using 147256virt/23696res/3012shr/21852data kb, in 170usr/10sys/172real ms.  
semantic error: while resolving probe point: identifier 'notexists' at <input>:1:7  
        source: probe notexists { exit() }  
                      ^  
  
semantic error: probe point mismatch at position 0  (alternatives: __nfs __scheduler __signal __tcpmib __vm _linuxmib _signal _sunrpc _syscall _vfs begin begin(number) end end(number) error error(number) generic ioblock ioblock_trace ioscheduler ioscheduler_trace ipmib irq_handler kernel kprobe kprocess linuxmib module(string) nd_syscall netdev netfilter never nfs nfsd perf process process(number) process(string) procfs procfs(string) scheduler scsi signal socket softirq stap staprun sunrpc syscall tcp tcpmib timer tty udp vfs vm workqueue): identifier 'notexists' at :1:7  
        source: probe notexists { exit() }  
                      ^  
  
Pass 2: analysis failed.  Try again with another '--vp 01' option.  

使用?表示如果这个point不存在, 也不会报错, 如下.

[root@db-172-16-3-39 ~]# stap --vp 5 -e "probe notexists ? { exit() }"  
Parsed kernel "/lib/modules/2.6.18-348.12.1.el5/build/.config", containing 1977 tuples  
Parsed kernel /lib/modules/2.6.18-348.12.1.el5/build/Module.symvers, which contained 3546 vmlinux exports  
Searched: " /usr/share/systemtap/tapset/x86_64/*.stp ", found: 4, processed: 4  
Searched: " /usr/share/systemtap/tapset/*.stp ", found: 81, processed: 81  
Pass 1: parsed user script and 85 library script(s) using 147756virt/23716res/3012shr/22352data kb, in 160usr/10sys/172real ms.  
semantic error: no probes found  
Pass 2: analysis failed.  Try again with another '--vp 01' option.  

!和?差不多, 具有不存在着不报错的功能, 如下 :

[root@db-172-16-3-39 ~]# stap --vp 5 -e "probe notexists ! { exit() }"  
Parsed kernel "/lib/modules/2.6.18-348.12.1.el5/build/.config", containing 1977 tuples  
Parsed kernel /lib/modules/2.6.18-348.12.1.el5/build/Module.symvers, which contained 3546 vmlinux exports  
Searched: " /usr/share/systemtap/tapset/x86_64/*.stp ", found: 4, processed: 4  
Searched: " /usr/share/systemtap/tapset/*.stp ", found: 81, processed: 81  
Pass 1: parsed user script and 85 library script(s) using 146788virt/23696res/3012shr/21384data kb, in 170usr/10sys/172real ms.  
semantic error: no probes found  
Pass 2: analysis failed.  Try again with another '--vp 01' option.  

!同时还具备一个功能, 如果一个probe 中定义了多个point, 那么使用了!的point只要被检索到了, 这个列表中的其他point都不会被解析. 例如.

[root@db-172-16-3-39 ~]# cat test.stp  
probe a=begin {  
  printf("a\n")  
}  
probe b=begin {  
  printf("b\n")  
}  
probe c !, b !, a {  
  printf("optinal and suffieince\n")  
}  
  
[root@db-172-16-3-39 ~]# stap --vp 5 test.stp   
Parsed kernel "/lib/modules/2.6.18-348.12.1.el5/build/.config", containing 1977 tuples  
Parsed kernel /lib/modules/2.6.18-348.12.1.el5/build/Module.symvers, which contained 3546 vmlinux exports  
Searched: " /usr/share/systemtap/tapset/x86_64/*.stp ", found: 4, processed: 4  
Searched: " /usr/share/systemtap/tapset/*.stp ", found: 81, processed: 81  
Pass 1: parsed user script and 85 library script(s) using 146868virt/23712res/3008shr/21464data kb, in 170usr/0sys/172real ms.  
b  
optinal and suffieince  

point a不存在, 使用!不报错.

point b存在, 同时使用了!, 所以位于b后面的point a不会被解析.

如果把!放在a后面, b可以被解析, 因为b在a前面.

[root@db-172-16-3-39 ~]# vi test.stp   
probe a=begin {  
  printf("a\n")  
}  
probe b=begin {  
  printf("b\n")  
}  
probe c !, b , a ! {  
  printf("optinal and suffieince\n")  
}  
  
[root@db-172-16-3-39 ~]# stap --vp 5 test.stp   
Parsed kernel "/lib/modules/2.6.18-348.12.1.el5/build/.config", containing 1977 tuples  
Parsed kernel /lib/modules/2.6.18-348.12.1.el5/build/Module.symvers, which contained 3546 vmlinux exports  
Searched: " /usr/share/systemtap/tapset/x86_64/*.stp ", found: 4, processed: 4  
Searched: " /usr/share/systemtap/tapset/*.stp ", found: 81, processed: 81  
Pass 1: parsed user script and 85 library script(s) using 146796virt/23700res/3008shr/21392data kb, in 160usr/10sys/173real ms.  
b  
optinal and suffieince  
a  
optinal and suffieince  

再如 :

[root@db-172-16-3-39 ~]# cat test.stp   
probe a=begin {  
  printf("a\n")  
}  
probe b=begin {  
  printf("b\n")  
}  
probe c !, b, b, a, a !, b, a {  
  printf("optinal and suffieince\n")  
}  
  
[root@db-172-16-3-39 ~]# stap --vp 5 test.stp   
Parsed kernel "/lib/modules/2.6.18-348.12.1.el5/build/.config", containing 1977 tuples  
Parsed kernel /lib/modules/2.6.18-348.12.1.el5/build/Module.symvers, which contained 3546 vmlinux exports  
Searched: " /usr/share/systemtap/tapset/x86_64/*.stp ", found: 4, processed: 4  
Searched: " /usr/share/systemtap/tapset/*.stp ", found: 81, processed: 81  
Pass 1: parsed user script and 85 library script(s) using 146808virt/23700res/3008shr/21404data kb, in 160usr/10sys/172real ms.  
b  
optinal and suffieince  
b  
optinal and suffieince  
a  
optinal and suffieince  
a  
optinal and suffieince  

最后是在probe point后面使用表达式 if (exp) :

[root@db-172-16-3-39 ~]# cat test.stp  
probe begin if($1) {  
  printf("%d is true\n", $1)  
  exit()  
}  

非0表示true, 被触发

[root@db-172-16-3-39 ~]# stap --vp 5 test.stp 1  
Parsed kernel "/lib/modules/2.6.18-348.12.1.el5/build/.config", containing 1977 tuples  
Parsed kernel /lib/modules/2.6.18-348.12.1.el5/build/Module.symvers, which contained 3546 vmlinux exports  
Searched: " /usr/share/systemtap/tapset/x86_64/*.stp ", found: 4, processed: 4  
Searched: " /usr/share/systemtap/tapset/*.stp ", found: 81, processed: 81  
Pass 1: parsed user script and 85 library script(s) using 147760virt/23712res/3008shr/22356data kb, in 160usr/10sys/172real ms.  
  
  
1 is true  
0表示false, 那么这个事件不会被触发.  
[root@db-172-16-3-39 ~]# stap --vp 5 test.stp 0  
Parsed kernel "/lib/modules/2.6.18-348.12.1.el5/build/.config", containing 1977 tuples  
Parsed kernel /lib/modules/2.6.18-348.12.1.el5/build/Module.symvers, which contained 3546 vmlinux exports  
Searched: " /usr/share/systemtap/tapset/x86_64/*.stp ", found: 4, processed: 4  
Searched: " /usr/share/systemtap/tapset/*.stp ", found: 81, processed: 81  
Pass 1: parsed user script and 85 library script(s) using 146788virt/23684res/3008shr/21384data kb, in 170usr/0sys/172real ms.  

参考

1. man stapprobes

Flag Counter

digoal’s 大量PostgreSQL文章入口