systemtap optimized for variables

2 minute read

背景

在systemtap language reference中的一段话

Note that all variable types are inferred, and that all locals and globals are initialized. Integers are set to 0 and strings are set to the empty string.

所有的变量在脚本解析时都会被自动推断类型, 所有的本地变量和全局变量都会被初始化, 例如整型初始化的值为0, 字符串为空字符串.

Global variables which are written but never read will be displayed automatically at session shutdown.

Unused variables :

The SystemTap translator removes unused variables. Global variable that are never written or read are discarded. Every local variables where the variable is only written but never read are also discarded. This optimization prunes unused variables defined in the probe aliases, but never used in the probe handler. If desired, this optimization can disabled with the -u option.

全局变量, 如果只有写入, 没有读取操作, 那么在脚本结束时会自动显示它的值.

另外, 在优化模式下. 对于未使用的变量, 默认会在解析时删掉. (全局变量没有读和写的操作将丢弃, 本地变量只有写但是没有读的操作也被丢弃)

在probe alias中定义的变量如果在probe handler中未被使用的话也会丢弃掉.

这些优化手段可以通过stap 的-u参数关闭.

例子 :

[root@db-172-16-3-39 ~]# cat test.stp  
global ga, gb  
global gc  
probe begin {  
//  a++  
  printf("a: %d, b: %s\n", a, b)  
  printf("ga: %d, gb: %s\n", ga, gb)  
  exit()  
}  

执行 :

[root@db-172-16-3-39 ~]# stap --vp 01 test.stp   

警告, 因为变量未指派任何值, 直接以指定类型输出.

WARNING: never-assigned local variable 'a' (alternatives: b ga gb gc): identifier 'a' at test.stp:5:28  
 source:   printf("a: %d, b: %s\n", a, b)  
                                    ^  
WARNING: never-assigned local variable 'b' (alternatives: a ga gb gc): identifier 'b' at :5:31  
 source:   printf("a: %d, b: %s\n", a, b)  
                                       ^  
WARNING: never assigned global variable 'ga' (alternatives: gb gc): identifier 'ga' at :1:8  
 source: global ga, gb  
                ^  
WARNING: never assigned global variable 'gb' (alternatives: ga gc): identifier 'gb' at :1:12  
 source: global ga, gb  
                    ^  

gc未在脚本中任何地方使用, 所以自动删除.

WARNING: Eliding unused variable 'gc': identifier 'gc' at :2:8  
 source: global gc  
                ^  
Pass 2: analyzed script: 1 probe(s), 1 function(s), 0 embed(s), 2 global(s) using 147328virt/24440res/3252shr/21924data kb, in 0usr/0sys/6real ms.  
a: 0, b:   
ga: 0, gb:   

如果加上-u参数的话(关闭优化模式), 如果包含未被任何地方使用的变量, 执行时将报错.

[root@db-172-16-3-39 ~]# stap --vp 01 -u test.stp   
semantic error: unresolved type : identifier 'gc' at test.stp:2:8  
        source: global gc  
                       ^  
Pass 2: analyzed script: 1 probe(s), 7 function(s), 0 embed(s), 3 global(s) using 147892virt/24404res/3208shr/22488data kb, in 10usr/0sys/6real ms.  
Pass 2: analysis failed.  Try again with another '--vp 01' option.  

只有写, 但是没有读的全局变量, 在会话结束时自动显示.

[root@db-172-16-3-39 ~]# cat test.stp   
global gc  
probe begin {  
  gc++  
  exit()  
}  

全局变量gc没有读取操作, 所以在结束时自动打印.

[root@db-172-16-3-39 ~]# stap --vp 01 test.stp   
Pass 2: analyzed script: 2 probe(s), 1 function(s), 0 embed(s), 1 global(s) using 147316virt/24420res/3244shr/21912data kb, in 10usr/0sys/6real ms.  
gc=0x1  

既没有读也没有写的全局变量将丢弃.

[root@db-172-16-3-39 ~]# cat test.stp  
global gc  
probe begin {  
  exit()  
}  
[root@db-172-16-3-39 ~]# stap --vp 1 test.stp  
Pass 1: parsed user script and 85 library script(s) using 146792virt/23684res/2996shr/21388data kb, in 170usr/10sys/172real ms.  
WARNING: Eliding unused variable 'gc': identifier 'gc' at test.stp:1:8  
 source: global gc  
                ^  

只有写, 但是没有读的本地变量, 在优化模式下自动丢弃.

[root@db-172-16-3-39 ~]# cat test.stp  
probe begin {  
  c++  
  exit()  
}  

这里的本地变量c将丢弃.

在probe alias这种定义的本地变量, 在probe handler中如果未被使用, 也会被丢弃.

[root@db-172-16-3-39 ~]# cat test.stp  
probe e1=begin {  
  va++  
}  
probe e1 {  
  exit()  
}  

参考

1. https://sourceware.org/systemtap/langref/SystemTap_overview.html

2. man stap

-u     Unoptimized mode.  Disable unused code elision during elaboration.  

3. https://sourceware.org/systemtap/langref/Components_SystemTap_script.html#SECTION00043100000000000000

Flag Counter

digoal’s 大量PostgreSQL文章入口