简介
systemtap 是利用Kprobe 提供的API来实现动态地监控和跟踪运行中的Linux内核的工具,相比Kprobe,systemtap更加简单,提供给用户简单的命令行接口,以及编写内核指令的脚本语言。对于开发人员,systemtap是一款难得的工具内核调试工具。
安装说明
首先确定内核版本:
uname -r: 3.10.0-123.el7.x86_64
对应于我们使用的内核版本,需要安装以下安装包:
kernel-debug-debuginfo-3.10.0-123.el7.x86_64.rpm
kernel-debug-devel-3.10.0-123.el7.x86_64.rpm
kernel-debuginfo-3.10.0-123.el7.x86_64.rpm
kernel-debuginfo-common-x86_64-3.10.0-123.el7.x86_64.rpm
kernel-headers-3.10.0-123.el7.x86_64.rpm
将上述安装包拷贝到本地虚机,执行一下命令rpm -ivh kernel-debuginfo-common-x86_64-3.10.0-862.el7.x86_64.rpm
安装上述安装包之后,systemtap便可以使用。
执行一下命令检测systemtap是否可以使用:
stap -e 'probe vfs.read {printf("read performed\n"); exit()}'
输出结果
下面简单说下5个pass的作用:
Pass 1 - parse:这个阶段主要是检查输入脚本是否存在语法错误,例如大括号是否匹配,变量定义是否规范等
Pass 2 - elaborate:这个阶段主要是对输入脚本中定义的探测点或者用到的函数展开,不但需要综合SystemTap的预定义脚本库,还需要分析内核或者内核模块的调试信息
Pass 3 -translate: 在这个阶段,将展开后的脚本转换成C文件。前三个阶段的功能类似于编译器,将.stp文件编译成为完整的.c文件,因此又被合起来称为转换器(translator)
Pass 4 - build:在这个阶段,将C源文件编译成内核模块,在这过程中还会用到SystemTap的运行时库函数。
Pass 5 - run:这个阶段,将编译好的内核模块插入内核,开始进行数据收集和传输。
NOTE:
1、我们linux系统中默认安装systetap,上述安装的是一些debug信息的安装包;
2、不同的内核版本需要对应与之相对应的debug信息安装包,例如kernel-debug-devel-XXXX.rpm,其中'XXXX'对应相应的内核版本号。
使用说明
本章旨在对systemtap使用手册中的systemtap的基本使用方法及我们调试内核可能用到的方法进行总结归纳。
1、stap指令执行方式
Systemtap可以通过指令执行,也通过脚本执行。通过指令执行使用'-e'选项,例如:
stap -e 'probe vfs.read {printf("read performed\n"); exit()}'
其中,【''】内为执行的内容,probe vfs.read为event, {printf("read performed\n"); exit()}为handler。即当event发生时,执行handler的内容。
2、Systemtap可以通过脚本执行
上例可写成脚本test.stp如下:
probe vfs.read
{
printf("read performed\n");
exit();
}
运行时,执行stap test.stp即可。
探针模式例子
探针类型 说明
begin 在脚本开始时触发
end 在脚本结束时触发
kernel.function("sys_sync") 调用sys_sync时触发
kernel.function("sys_sync").call 同上
kernel.function("sys_sync").return 返回sys_sync时触发
kernel.syscall.* 进行任何系统调用时触发
kernel.function("*@kernel/fork.c:934") 到达 fork.c的第 934行时触发
module("ext3").function("ext3_file_write") 调用 ext3write函数时触发
timer.jiffies(1000) 每隔 1000个内核 jiffy触发一次
timer.ms(200).randomize(50) 每隔 200毫秒触发一次,带有线性分布的随机附加时间(-50到 +50)
SystemTap 的语言元素
语句