systemtap local & global variables

2 minute read

背景

前几天写过一篇blog, 关于systemtap优化模式下, 对有写, 没读, 或者没写没读的全局变量和本地变量做消除处理.

本文将讲一讲本地变量和全局变量的使用.

首先是变量的命名规范.

变量名可以包含数字,字母_,$符号. 但是必须以字母或_开头, 区分大小写.

Identifiers for variables and functions are alphanumeric sequences, and may include the underscore (_) and the dollar sign ($) characters. They may not start with a plain digit. Each variable is by default local to the probe or function statement block where it is mentioned, and therefore its scope and lifetime is limited to a particular probe or function invocation. Scalar variables are implicitly typed as either string or integer. Associative arrays also have a string or integer value, and a tuple of strings or integers serves as a key. Arrays must be declared as global. Local arrays are not allowed.

The translator performs type inference on all identifiers, including array indexes and function parameters. Inconsistent type-related use of identifiers results in an error.

Variables may be declared global. Global variables are shared among all probes and remain instantiated as long as the SystemTap session. There is one namespace for all global variables, regardless of the script file in which they are found. Because of possible concurrency limits, such as multiple probe handlers, each global variable used by a probe is automatically read- or write-locked while the handler is running. A global declaration may be written at the outermost level anywhere in a script file, not just within a block of code. Global variables which are written but never read will be displayed automatically at session shutdown. The following declaration marks var1 and var2 as global. The translator will infer a value type for each, and if the variable is used as an array, its key types.

global var1[=<value>], var2[=<value>]  

$开头的变量为target variable, 或者context变量. 参考 :

http://blog.163.com/digoal@126/blog/static/16387704020138113455697/

所以不适合用做本地变量或者全局变量名. 来看个例子 :

[root@db-172-16-3-39 ~]# cat test.stp   
probe begin {  
  $abc=222  
  printf("%d\n", $abc)  
  exit()  
}  
  
[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 146804virt/23708res/3008shr/21400data kb, in 160usr/10sys/173real ms.  
semantic error: unresolved target-symbol expression: identifier '$abc' at test.stp:2:3  
        source:   $abc=222  
                  ^  
  
semantic error: unresolved target-symbol expression: identifier '$abc' at :3:18  
        source:   printf("%d\n", $abc)  
                                 ^  
Pass 2: analysis failed.  Try again with another '--vp 01' option.  

本地变量不需要加锁, 如果是多核CPU的情况下, 事件并发触发的话, 每个核管自己的本地变量, 互不干涉.

接下来要说的是全局变量, 全局变量写的时候是要加锁的, 所以有加锁超时的说法, 参见 :

systemtap SAFETY AND SECURITY  

http://blog.163.com/digoal@126/blog/static/163877040201381021752228/

同时全局变量的作用范围, 不仅仅局限在本地脚本, 而是整个stap的检索范围中.

例如 :

在/tmp/p.stp中定义一个全局变量

[root@db-172-16-3-39 ~]# cat /tmp/p.stp   
global a="abc"  

在test.stp中调用这个全局变量.

[root@db-172-16-3-39 ~]# cat test.stp  
probe begin {  
  _a$$vars=123  
  B=123  
  printf("%s, %d, %d, %d\n", a, _a$$vars, B, b)  
  exit()  
}  

使用-I 加载自定义脚本库. 我们看到在tmp/p.stp中定义的a这个全局变量被打印出来了.

[root@db-172-16-3-39 ~]# stap -I /tmp --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  
Searched: " /tmp/*.stp ", found: 2, processed: 2  
Pass 1: parsed user script and 87 library script(s) using 146920virt/23716res/3012shr/21516data kb, in 160usr/20sys/173real ms.  
WARNING: never-assigned local variable 'b' (alternatives: _a$$vars B a): identifier 'b' at test.stp:4:46  
 source:   printf("%s, %d, %d, %d\n", a, _a$$vars, B, b)  
                                                      ^  
abc, 123, 123, 0  

最后, 数组必须定义为全局变量.

参考

1. systemtap optimized for variables

http://blog.163.com/digoal@126/blog/static/16387704020138109459201/

2. https://sourceware.org/systemtap/langref/Components_SystemTap_script.html

3. systemtap probe point’s “context variables” or “target variables”

http://blog.163.com/digoal@126/blog/static/16387704020138113455697/

4. systemtap SAFETY AND SECURITY

http://blog.163.com/digoal@126/blog/static/163877040201381021752228/

Flag Counter

digoal’s 大量PostgreSQL文章入口