systemtap 能动态的往内核插入代码,可以用来进行Linux kernel的debug ,也可以进行性能监测和分析。最近实验了systemtap dump kernel function call stack ,以及函数entry parameters的trace,这两种初级的对systemtap的使用。
1. trace 内核函数的调用关系
在分析内核的时候,有时候希望得到函数的调用关系(call trace),在内核代码中插入dump_stack()可以做到。使用systemtap 得到调用关系更加高效,不用修改内核代码及重新编译内核。使用systemtap 得到call trace 的例子如下:
stap --all-modules -v -e 'probe module("dm-cache").function("cache_lookup"){print_backtrace();println("");}'
stap 是systemtap 的用户层命令,加入--all-modules option 可以解决函数名无法解析的问题,参考了http://blog.yufeng.info/archives/1229。-v 是verbose,能够print出执行过程,-e 后就是根据systemtap 脚本规则写的插入点以及在插入点进行的动作。这里的print_backtrace()函数会打印出call trace。可以看到cache_lookup 函数在内核中的栈。当然,也可以换一种方式来输入-e 后的参数,即是将probe module("dm-cache").function("cache_lookup"){print_backtrace();println("");} 写入一个后缀为.stp 的文件,然后stap --all-modules -v xxx.stap 也可以。
2. trace 内核函数的输入参数
在分析内核函数时,得到内核函数在运行时的参数能够帮助分析。可以用stap -L 列出 probe 点可以查看的参数。eg: stap -L 'module("dm-cache").function("cache_lookup")'可以列出cache_lookup的参数。$号后为函数参数的名字,:号后为参数的数据类型。trace 输入参数的例子:stap -v -e 'probe module("dm-cache").function("cache_lookup"){printf("block=%d\n",$block);println("");}'。
通过以上简单的例子可以一窥systemtap 的用法。