2013年8月25日星期日

SystemTap----将SystemTap脚本编译成内核模块

  当运行SystemTap脚本时,会根据脚本生成一个内核模块,然后插入到系统中执行后退出。这个过程总共分为5个阶段:parse, elaborate, translate, compile, run,对应的编号为1-5.stap命令的-p选项可以用来指定在哪个阶段停止,利用这个选项可以将脚本编译成内核模块。
正常情况下,SystemTap脚本只能在部署了SystemTap执行环境(安装内核的开发包和debuginfo包)的机器,如果要在十台机器上执行,就要在这些机器上都部署这样的环境。如果将脚本编译成内核模块,借助staprun命令(需要systemtap-runtime包)就可以像直接使用stap命令执行脚本一样。当然,也可以直接使用insmod或modprobe命令直接将内核模块插入到系统中运行。除此之外,还可以利用生成的内核模块来修改系统的一些行为,具体可以参考褚霸的文章《Systemtap辅助设置tcp_init_cwnd,免对操作系统打Patch》。
下面介绍一下具体的步骤:
1、编写脚本
示例脚本如下:
probe begin {
%{ printk(KERN_ALERT "Hello, World!\n") %};
exit();
}
在上面的脚本中嵌入了C代码,将“hello World"输入到系统日志,这个脚本其实很简单,之所以贴出来,是因为在分别使用insmod和staprun命令来执行生成的内核模块时,表现不一样,后面再说。将脚本保存为hello.stp。
2、生成内核模块
命令如下:
stap -p4 -gu -m hello hello.stp
-p选项用来指定在哪个阶段停止,这里是在compile阶段。
因为在脚本中嵌入了C代码,所以要指定-g选项进入guru模式,-u选项是禁止优化的选项,可选。
-m是指定生成的内核模块名称,这里生成的内核模块就是hello.ko。如果不使用-m选项,systemtap会将生成的内核模块放在用户目录的.systemtap目录下。没有指定的情况下,我的机器上生成的路径为/root/.systemtap/cache/e9/stap_e9ff1bc604b35641b8cec15699c7bfa0_791.ko,所以你懂的,最好要指定一下哦。
3、运行内核模块
命令如下:
staprun hello.ko
这里生成的hello.ko模块在使用staprun命令运行的时候,会在系统日志中显示"Hello,World!",但是直接使用insmod时,则没有看到,具体原因目前不详,有知道的希望不吝赐教,拜谢。


   除非必须,不要把日志输出到系统日志,特别是量比较大的时候,否则会将重要的系统信息给冲掉。还是建议大家在使用的时候使用staprun命令来执行生成的内核模块,不要使用insmod或modprobe。在使用staprun的时候还可以使用-o选项来指定的输出的文件,如果不指定的话,脚本中的printf函数输出的信息是看不到的。

没有评论:

发表评论