find systemtap pre-built probe points & probe points reference manual
背景
systemtap内建了大量的probe event. 以及alias.
一般放在/usr/share/systemtap/tapset/这个目录中, 以stp后缀结尾的文件中.
使用stap –vp 5输出详细信息, 可以看到stap搜索的目录.
[root@db-172-16-3-39 ~]# stap --vp 5 -e "probe begin { 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 147264virt/23696res/3012shr/21860data kb, in 160usr/10sys/171real ms.
如果自己定义了一些probe alias放在.stp文件中, 那么可以通过-I来添加存放自定义stp文件的目录.
man stap
-I DIR Add the given directory to the tapset search directory. See the description of pass 2 for details.
例如 :
[root@db-172-16-3-39 ~]# pwd
/root
[root@db-172-16-3-39 ~]# ll *.stp
-rw-r--r-- 1 root root 107 Sep 6 16:50 p.stp
-rw-r--r-- 1 root root 320 Sep 10 15:13 test.stp
[root@db-172-16-3-39 ~]# stap -I /root --vp 5 -e "probe begin { 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
parse error: command line argument index 1 out of range [1-0]
at: unknown token '$1' at /root/test.stp:6:17
source: for (i=0; i<$1; i++) {
^
1 parse error.
WARNING: tapset '/root/test.stp' has errors, and will be skipped.
在指定的目录中发现两个.stp文件, 处理了1个.
Searched: " /root/*.stp ", found: 2, processed: 1
Pass 1: parsed user script and 86 library script(s) using 146916virt/23728res/3024shr/21512data kb, in 170usr/10sys/174real ms.
一.
查找内建的probe event或者别名, 可以直接去这几个检索的目录中grep, 也可以使用stap命令行参数进行匹配检索.
1. 直接去预装的stp脚本目录中检索举例 :
[root@db-172-16-3-39 ~]# grep -r "^probe " /usr/share/systemtap/tapset/* | less
/usr/share/systemtap/tapset/argv.stp:probe begin(-1) {
/usr/share/systemtap/tapset/i386/nd_syscalls.stp:probe nd_syscall.get_thread_area = kprobe.function("sys_get_thread_area")
/usr/share/systemtap/tapset/i386/nd_syscalls.stp:probe nd_syscall.get_thread_area.return = kprobe.function("sys_get_thread_area").return
/usr/share/systemtap/tapset/i386/nd_syscalls.stp:probe nd_syscall.iopl = kprobe.function("sys_iopl")
/usr/share/systemtap/tapset/i386/nd_syscalls.stp:probe nd_syscall.iopl.return = kprobe.function("sys_iopl").return
... 略
使用这种方法检索到的基本上都是probe alias, 方便我们使用, 其实这些别名都是kernel.funciton或者kprobe.funciton之类的event.
例如syscall :
[root@db-172-16-3-39 ~]# grep -r "^probe " /usr/share/systemtap/tapset/* | grep "probe syscall" | less
/usr/share/systemtap/tapset/i386/syscalls.stp:probe syscall.get_thread_area = kernel.function("sys_get_thread_area")
/usr/share/systemtap/tapset/i386/syscalls.stp:probe syscall.get_thread_area.return = kernel.function("sys_get_thread_area").return
/usr/share/systemtap/tapset/i386/syscalls.stp:probe syscall.iopl = kernel.function("sys_iopl")
/usr/share/systemtap/tapset/i386/syscalls.stp:probe syscall.iopl.return = kernel.function("sys_iopl").return
... 略
2. 使用stap -l 参数检索举例 :
[root@db-172-16-3-39 ~]# stap --vp 5 -l 'syscall.*'|less
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 146604virt/23692res/3008shr/21200data kb, in 160usr/10sys/172real ms.
syscall.accept
syscall.access
syscall.acct
syscall.add_key
syscall.adjtimex
syscall.alarm
syscall.arch_prctl
... 略
使用stap支持通配符查找.
[root@db-172-16-3-39 ~]# stap -l 'syscall.*.return'|less
syscall.accept.return
syscall.access.return
syscall.acct.return
syscall.add_key.return
syscall.adjtimex.return
syscall.alarm.return
syscall.arch_prctl.return
syscall.bdflush.return
... 略
查找kernel.function(“*”) , :
[root@db-172-16-3-39 ~]# stap --vp 5 -l 'kernel.function("*")'|less
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 146604virt/23688res/3008shr/21200data kb, in 170usr/0sys/173real ms.
kernel.function("BDEV_I@fs/block_dev.c:32")
kernel.function("DQUOT_ALLOC_INODE@include/linux/quotaops.h:168")
kernel.function("DQUOT_ALLOC_SPACE@include/linux/quotaops.h:148")
kernel.function("DQUOT_ALLOC_SPACE_NODIRTY@include/linux/quotaops.h:126")
kernel.function("DQUOT_DROP@include/linux/quotaops.h:83")
kernel.function("DQUOT_FREE_INODE@include/linux/quotaops.h:219")
kernel.function("DQUOT_FREE_SPACE@include/linux/quotaops.h:213")
... 略
kernel.function("*")有18124个, 而tapset目录中只有2千多个alias.
所以需要更精细的事件, 还是去kernel.funciton中找吧. 当然2千多个alias日常已经够用了.
[root@db-172-16-3-39 ~]# stap --vp 5 -l 'kernel.function("*")'|wc -l
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 146604virt/23688res/3008shr/21200data kb, in 170usr/0sys/172real ms.
18124
[root@db-172-16-3-39 ~]# grep -r "^probe " /usr/share/systemtap/tapset/|wc -l
2230
常用的查询条件, '*', '*.*' '**'
[root@db-172-16-3-39 ~]# stap --vp 5 -l '*'
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 146608virt/23696res/3008shr/21204data kb, in 160usr/10sys/172real ms.
begin
end
error
never
[root@db-172-16-3-39 ~]# stap --vp 5 -l '*.*'| less
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 146604virt/23700res/3008shr/21200data kb, in 160usr/10sys/173real ms.
_syscall.accept
_vfs.block_prepare_write
_vfs.block_write_begin
_vfs.block_write_end
_vfs.generic_block_bmap
_vfs.generic_commit_write
_vfs.generic_file_readonly_mmap
... 略
[root@db-172-16-3-39 tapset]# stap --vp 5 -l '**'| less
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 146608virt/23696res/3008shr/21204data kb, in 170usr/0sys/172real ms.
__nfs.aop.write_begin
__nfs.aop.write_begin.return
__nfs.aop.write_end
__nfs.aop.write_end.return
__scheduler.kthread_stop.kp
这些通配符的含义可以参考man stapprobes
The general probe point syntax is a dotted-symbol sequence. This allows a breakdown of the event namespace
into parts, somewhat like the Domain Name System does on the Internet. Each component identifier may be
parametrized by a string or number literal, with a syntax like a function call. A component may include a "*"
character, to expand to a set of matching probe points. It may also include "**" to match multiple sequential
components at once. Probe aliases likewise expand to other probe points. Each and every resulting probe point
is normally resolved to some low-level system instrumentation facility (e.g., a kprobe address, marker, or a
timer configuration), otherwise the elaboration phase will fail.
二.
获得event或者alias后, 怎么获得帮助呢? 比如要得到这些事件可用的target variable,
可以通过帮助手册,或者使用stap -L 查找, 或者使用$$vars打印.
例如 :
[root@db-172-16-3-39 ~]# stap -l "*.*"|grep vm.brk
vm.brk
变量获得 :
1. 通过stap -L
[root@db-172-16-3-39 ~]# stap -L vm.brk
vm.brk name:string address:long length:long $addr:long unsigned int $len:long unsigned int $prev:struct vm_area_struct*
man stap
-L PROBE
Similar to "-l", but list probe points and script-level local variables.
2. 通过probe::*
帮助手册 :
取自SystemTap Tapset Reference Manual
[root@db-172-16-3-39 ~]# man probe::vm.brk
PROBE::VM.BRK(3stap) Memory Tapset PROBE::VM.BRK(3stap)
NAME
probe::vm.brk - Fires when a brk is requested (i.e. the heap will be resized)
SYNOPSIS
vm.brk
VALUES
length the length of the memory segment
name name of the probe point
address
the requested address
CONTEXT
The process calling brk.
SystemTap Tapset Reference January 2013 PROBE::VM.BRK(3stap)
3. 还可以使用stap这种的特殊变量$$vars
打印这个event的变量, 但是这种方法必须要当事件被触发才行.
[root@db-172-16-3-39 ~]# cat test.stp
probe vm.brk {
printf("vars: %s\n", $$vars)
exit()
}
[root@db-172-16-3-39 ~]# stap test.stp
vars: addr=0x1fd59000 len=0x21000 mm=? vma=? prev=0xc000003e0000000c flags=? rb_link=? rb_parent=? pgoff=? error=?
使用$$vars
打印出来的是这个内核函数中定义的所有变量, 比stap -L和帮助手册更全面.
expands to a character string that is equivalent to sprintf("parm1=%x ... parmN=%x var1=%x ...
varN=%x", parm1, ..., parmN, var1, ..., varN)
三.
probe points 帮助手册的结构 :
probe::*(3stap), tapset::*(3stap), function::*(3stap)
这三个man手册其实都是源自以下这本手册.