1.Systemtap快速开始
1.1 Systemtap安装
为了安装systemtap,需要安装Kernel相关的-devel,-debuginfo和-debuginfo-comon 包。
# yum install kernel-debuginfo kernel-debuginfo-common kernel-devel
# yum install systemtap systemtap-runtime
1.2Systemtap 测试
执行下面的测试命令,如果正常运行说明systemtap可以正常使用。
# stap -v -e 'probe vfs.write {printf("write performed\n"); exit()}'
Pass 1: parsed user script and 96 library script(s) using 198528virt/26496res/3076shr/24132data kb, in 180usr/20sys/198real ms.
Pass 2: analyzed script: 1 probe(s), 1 function(s), 3 embed(s), 0 global(s) using 438212virt/134360res/8536shr/123624data kb, in 1680usr/330sys/2019real ms.
Pass 3: translated to C into "/tmp/stapqH4Ifk/stap_6c286231c95180fb28a26c9f74999f5c_1331_src.c" using 428112virt/130264res/7124shr/123624data kb, in 10usr/0sys/5real ms.
Pass 4: compiled C into "stap_6c286231c95180fb28a26c9f74999f5c_1331.ko" in 1610usr/230sys/1872real ms.
Pass 5: starting run.
write performed
Pass 5: run completed in 10usr/20sys/345real ms.
备注:probe event{ code} 生成一个监控vfs.write事件的探针(probe),花括号内表示事件触发时候的动作。
2.Systemtap原理
systemtap 利用用户自定义脚本深度跟踪linux Kernel的行为。利用它可以诊断复杂的系统性能问题。其基本原理利用探测脚本监视内核行为,并作出相应的操作。运行stap脚本后会生成一个systemtap session。Session按照下面的步骤生成:
2.1 parsed
systemtap 首先检查/usr/share/systemtap/tapset/目录下已经定义好的tap脚本,将定义的事件替换为相应的systemtap脚本库片段。
2.2translated
将tap脚本翻译成c代码,并由c编译器编译成内核模块.ko文件。
2.3load module
systemtap将.ko加载到内核中运行
2.4执行用户自定义动作
当tap脚本中event被触发时,执行相应的操作。
2.5unload module
当一个systemtap session中断(exit)时,systemtap将模块从内核中卸载。
3.Systemtap脚本
3.1 脚本格式
# probeevent {statements}
备注:当然systemtap可以将多个probe的公共statement抽离成函数。其格式
# function function_name(arguments) {statements}
probe event {function_name(arguments)}
3.2 event
Systemtap event分为两类:一种是调用内核函数,另一种是内核函数返回。我的理解是前一种是可以探测函数内部,后一种是探测函数的返回结果。下表列举了一些常见的探针事件。
Event | 说明 |
syscall.system_call | 系统调用是触发 |
vfs.file_operation | vfs操作是触发 |
kernel.function("function") | 内核函数调用时候触发 |
module("module").function("function") | 调用模块中某个函数时触发 |
begin | 执行脚本时触发 |
end | 结束脚本时触发 |
3.3 statements
Systemtap statements的语法类似C语言。可以定义变量,无需声明类型。常见的表达式:
if (condition)
statement1
else
statement2
while (condition)
statement
for (initialization; conditional; increment) statement
foreach (VAR in ARRAY) {}
initialization
while (conditional) {
statement
increment
}
4. 参考资料
https://sourceware.org/systemtap/SystemTap_Beginners_Guide/