1 systemtap脚本以.stp结尾,脚本的基本格式:
probe event {statements}
每一个probe可以有多个event,多个event之间用(,)隔开。event执行的顺序按照probe的执行顺序。
下面来看个例子:
function function_name(arguments) {statements}
probe event {function_name(arguments)}
当执行到probe的时候,就去调用函数function_name.
2 event大体上分为两类:synchronous 和asynchronous
(1)主要的同步事件包括:
syscall.system_call 和 syscall.system_call.return,
分别监听系统调用的入口和出口,举个例子:
probe syscall.close{}
probe syscall.close.return {}
vfs.file_operation和vfs.file_operation.close
分别监听虚拟文件系统的操作函数的入口点和返回点
kernel.function("fuction_name") 和 kernel.function("function_name").return
分别监测内核函数的入口点和返回点,举个例子:
kernel.function("sys_open")和kernel.function("sys_open").close
在监测内核函数的时候,可以采用统配符(*),看下面的例子:
probe kernel.function("*@net/socket.c"){}
probe kernel.function("@net/socket.c").return{}
这两个probe分别监视net/socket.c文件中的所有的函数的入口点和返回点。
module("module").function("function_name")和module("module").function("function_name").return
监测模块中的函数,也可以使用通配符(*)。看下面的例子:
probe module("ext3").function("*"){}
probe module("ext3").function("*").return{}
(2)异步事件,主要用来监测计数器(counters), 定时器(timers)和一些类似的结构
• timer.s(milliseconds)
• timer.ms(milliseconds)
• timer.us(microseconds)
• timer.ns(nanoseconds)
• timer.hz(hertz)
• timer.jiffies(jiffies)
举个例子:
probe timer.s(4)
{
printf("hello world\n")
}
每隔4s打印hello world.
3 systemtap 函数
tid() 当前线程的id
uid() 当前用户的id
cpu() 当前cpu的数量
gettimeofday_s() The number of seconds since UNIX epoch (January 1, 1970).
ctime() Convert number of seconds since UNIX epoch to date.
pp() A string describing the probe point currently being handled.
thread_indent() 方便组织输出结果的函数
看下面的例子:
probe kernel.function("*@net/socket.c")
{
printf ("%s -> %s\n", thread_indent(1), probefunc())
}
probe kernel.function("*@net/socket.c").return
{
printf ("%s <- %s\n", thread_indent(-1), probefunc())
}
输出结果:
0 ftp(7223): -> sys_socketcall
1159 ftp(7223): -> sys_socket
2173 ftp(7223): -> __sock_create
2286 ftp(7223): -> sock_alloc_inode
2737 ftp(7223): <- sock_alloc_inode
3349 ftp(7223): -> sock_alloc
3389 ftp(7223): <- sock_alloc
3417 ftp(7223): <- __sock_create
4117 ftp(7223): -> sock_create
4160 ftp(7223): <- sock_create
4301 ftp(7223): -> sock_map_fd
4644 ftp(7223): -> sock_map_file
thread_indent的输出结果包括以下几个部分:
a timestamp: 在当前线程中,thread_indent()第一次调用到现在经过的秒数
程序名(ID) : 调用后面probefunc()中指定函数的程序名和ID
一个箭头:指明函数的入口和返回点
函数名:被前面提到的程序名调用的函数的名称
看下面的例子:
probe syscall.* {
if (pid() == target())
printf("%s/n", name)
}
有一个target()函数和name变量。上面这个脚本要在运行的时候必须这么使用
stap script -x process ID or stap script -c command
上面给出的脚本的意思是:
遍历所有的系统调用,然后打印出进程的id等于target()指定的ID的进程调用的系统调用的名字。
target() = process ID
阅读(3909) | 评论(0) | 转发(1) |