使用 SystemTap 调试内核
t) {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 syscallsfunction print_top () {cnt=0log (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();}
来看看它的输出:
SystemTap的基本原理
现在,大家已经熟悉了SystemTap的基本用法。在结束之前,让我们再来了解一下SystemTap的基本原理和工作流程以加深理解。
可以看出,SystemTap运行的过程依次分为五个阶段,通常称为Pass 1 - Pass 5。就像前面介绍用法的时候提到的,在命令行中加上-p NUM选项可以使得SystemTap在运行完Pass NUM之后停止,而不是运行到Pass 5。这允许你分析SystemTap在每一个阶段的输出,对于调试脚本尤其有用。
下面来介绍每一个阶段的主要功能:
Pass 1 - parse:这个阶段主要是检查输入脚本是否存在语法错误,例如大括号是否匹配,变量定义是否规范等
Pass 2 - elaborate:这个阶段主要是对输入脚本中定义的探测点或者用到的函数展开,不但需要综合SystemTap的预定义脚本库,还需要分析内核或者内核模块的调试信息
Pass 3 - translate: 在这个阶段,将展开后的脚本转换成C文件。前三个阶段的功能类似于编译器,将.stp文件编译成为完整的.c文件,因此又被合起来称为转换器(translator)
Pass 4 - build:在这个阶段,将C源文件编译成内核模块,在这过程中还会用到SystemTap的运行时库函数。
Pass 5 - run:这个阶段,将编译好的内核模块插入内核,开始进行数据收集和传输。
小结
SystemTap是一个全新的工具,但已经表现出了强大的功能和广泛的适用性。SystemTap使得动态收集Linux内核信息和性能数据变得轻而易举,这就使人可以从繁琐的数据采集中解放出来,而专注于数据的处理和分析,这无疑是内核开发人员和系统管理人员的福音。随着越来越多用户的体
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)