Chinaunix首页 | 论坛 | 博客
  • 博客访问: 104672
  • 博文数量: 76
  • 博客积分: 50
  • 博客等级: 民兵
  • 技术积分: 400
  • 用 户 组: 普通用户
  • 注册时间: 2007-07-18 21:41
文章分类

全部博文(76)

文章存档

2011年(76)

我的朋友

分类:

2011-08-24 17:40:09

原文地址:systemtap 学习笔记(1) 作者:liujunwei1234

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_operationvfs.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



阅读(829) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~