|
#!/usr/local/bin/stap
global count
function report(stat) {
printf("stat=%d\n", stat)
}
probe kernel.function("sys_read") {
++count
}
probe end {
report()
}
|
- 探测点(probe):每个systemtap脚本中至少需要定义一个探测点,也就是指定了在内核的什么位置进行探测。探测点名称后面紧跟的一组大括号内定义了每次内核运行到该探测点时需要运行的操作,这些操作完成后再返回探测点,继续下面的指令。这里给出了systemtap目前支持的所有探测点类型。
- 全局变量(global):用来定义全局变量。单个探测点函数体中使用的局部变量不需要预先定义,但是如果一个变量需要在多个探测点函数体中使用,则需要定义为全局变量。
- 函数(function):用来定义探测点函数体中需要用到的函数。除了可以用脚本语言定义函数以外,还可以用C语言来定义函数,只是这时函数名后面的大括号对需要换成%{ %}。例如,前面的report()函数可以写成:
function report(stat) %{
_stp_printf("stat=%d\n", THIS->stat);
%}
|
SystemTap的例子
了解了SystemTap的基本用法,下面让我们来看几个有趣的例子。
统计当前系统中调用最多的前10个系统调用
在进行性能分析的时候,我们常常需要知道那些函数调用次数最多,才能有的放矢地展开分析。下面这个简单的例子可以打印出在过去的5秒钟里调用次数最多的那些系统调用。
#!/usr/bin/env stap
#
# display the top 10 syscalls called in last 5 seconds
#
global syscalls
function print_top () {
cnt=0
log ("SYSCALL\t\t\t\tCOUNT")
foreach ([name] in syscalls-) {
printf("%-20s\t\t%5d\n",name, syscalls[name])
if (cnt++ == 10)
break
}
printf("--------------------------------------\n")
delete syscalls
}
probe syscall.* {
syscalls[probefunc()]++
}
probe timer.ms(5000) {
print_top ()
}
|
它的输出结果一目了然:
看看是谁在偷偷动我的文件
有时候,我们如果中了恶意的病毒软件,会发现某些文件莫名其妙的被修改,下面这个例子可以帮你监视谁在修改你的文件。
#!/usr/bin/env stap
#
# monitor who is messing my file of secrets
#
probe generic.fop.open {
if(filename == "secrets")
printf("%s is opening my file: %s\n", execname(), filename)
}
|
我们运行这个脚本,在另外一个窗口做一些操作,来看看它的输出结果:
打印ANSI字符串
SystemTap不仅仅是一个简单的调试工具,强大的脚本语言能力让它同样能做一些有趣的事情,下面这个例子就可以对输出的字符进行美化:
#!/usr/bin/env stap
#
# print colorful ANSI strings
#
probe begin {
printf("a \\ b |");
for (c = 40; c < 48; c++)
printf(" %d ", c);
printf("\12");
for (l = 0; l < 71; l++)
printf("-");
printf("\12");
for (r = 30; r < 38; r++)
for (t = 0; t < 2; t++) {
printf("%d |", r);
for (c = 40; c < 48; c++)
printf("\033[%d;%d%s %s \033[0;0m",
r, c, !t ? "m" : ";1m", !t ? "Normal" : "Bold ");
printf("\12");
}
exit();
}
|
共3页: 上一页 [1] 2 [3] 下一页
|