Systemtap的另类用法
November 10th, 2010
原创文章,转载请注明: 转载自系统技术非业余研究
本文链接地址: Systemtap的另类用法
通常我们在做内核编程的时候,会用到内核的数据结构,比如说textsearch提供了几种算法用于支付串查找。在用于正式的项目前,我们会希望考察下他的用法以及想体验下。最通常的做法是自己写个module,写个makefile,编译,运行,然后去dmesg里面看printk的结果。这个过程没啥问题,就是太罗嗦。好了,现在我们有更方便的方法了:systemtap.
Systemtap是个脚本,先翻译成c kernel模块代码,然后编译,插入到内核运行,同时提供最基本的内核和应用模块的通讯管道,在应用模块这里收集信息。 它还支持guru模式,让用户直接插入c代码。 这样我们就可以利用stap的这一特性来做我们的实验。
底下我们来演示下:
# cat ts.stp %{ #include <linux/textsearch.h> %} function test_textsearch:long (algo:string) %{ /* pure */ /* unprivileged */ struct ts_config* ts; struct ts_state state; ts = textsearch_prepare(THIS->algo, "world", 5, GFP_KERNEL, TS_AUTOLOAD); if(IS_ERR(ts)) goto err; _stp_printf("%s\n", "prepare ok!"); if(UINT_MAX==textsearch_find_continuous(ts, &state, "hello world", 11)) goto err; _stp_printf("%s\n", "find ok!"); textsearch_destroy(ts); THIS->__retvalue = 0; return; err: _stp_printf("%s\n", "init error!"); THIS->__retvalue = -1; return; %} probe begin { printf("result:%d\n", test_textsearch(@1)); exit(); } %%请注意我们上面用到了 _stp_printf,代替printk, 这个是stap的runtime的基础服务。 # stap -gu ts.stp bm %%我们用的是BM算法 prepare ok! find ok! result:0
cool吧! 把c语言当脚本编写啦。
但是这个stap有个缺点,就是头文件必须是内核include路径里面的,如果我们用到了其他头文件,编译的时候就出错。
# touch xyz.h #建个空的头文件 # diff -u ts.stp ts1.stp --- ts.stp 2010-11-08 12:04:54.000000000 +0800 +++ ts1.stp 2010-11-10 14:19:47.000000000 +0800 @@ -1,5 +1,6 @@ %{ #include <linux/textsearch.h> +#include "xyz.h" %} # stap -gu ts1.stp bm /tmp/stapKuLo9R/stap_90d03f83d4d4a8efa7b721a6ff0093fe_2503.c:169:17: error: xyz.h: No such file or directory make[1]: *** [/tmp/stapKuLo9R/stap_90d03f83d4d4a8efa7b721a6ff0093fe_2503.o] Error 1 make: *** [_module_/tmp/stapKuLo9R] Error 2 Pass 4: compilation failed. Try again with another '--vp 0001' option.
这个问题挺烦人的,但是我们有探索精神,不怕的,我们来crack下吧
# diff systemtap-1.3/buildrun.cxx systemtap-1.3.patched/buildrun.cxx 235a236,238 > > o << "EXTRA_CFLAGS += $(STAP_CFLAGS)" << endl; > 237a241 > # ./configure --prefix=/usr && make && make install
到现在为止 stap是crack过的. 我们再来实验下吧!首先把我们的头文件所在的路径通知到systemtap,它会在让编译模块的时候加上我们的头文件路径。
# export STAP_CFLAGS="-I`pwd`" # printenv STAP_CFLAGS -I/home/wentong # stap -gu ts1.stp bm prepare ok! find ok! result:0
哈哈,成功了。
大家可以这样的方式用stap写很多好玩的东西,祝玩的开心。
Post Footer automatically generated by wp-posturl plugin for wordpress.
顶沙发
Yu Feng Reply:
November 10th, 2010 at 2:31 pm
谢谢文通支持哦!!!
果然需要一定的底层基础。。。
好东西要顶
还游离在printf pid()的路过
我果然还要再看三百年才能搞到这层次么
直接拷贝走源码了
Yu Feng Reply:
November 10th, 2010 at 2:38 pm
工具嘛!熟练了了能提高生产力!
褚霸兄非常了不起,把我们从麻烦的module_init()/module_exit()中解救出来了,
不仅方便,还大大降低了一些需要硬编码指针地址的风险
Yu Feng Reply:
November 10th, 2010 at 3:06 pm
子团兄过奖了,你才是真正的牛人哦!!!
真羡慕啊~~做底层一直是我的梦想
Yu Feng Reply:
November 10th, 2010 at 5:16 pm
底层开发貌似会感觉有成就感些!
确实好用,不过对底层知识的要求貌似较高啊..
Yu Feng Reply:
November 15th, 2010 at 11:40 am
探测用户空间的程序就无需懂太多内核知识。
hi, 你分享的方法,确实是很有用。
我想通过systemtap插入c++代码。
我发现一个问题,如果自定义的文件里面有c++的头文件的话,就会提示找不到头文件。 分析原因发现,systemtap将脚本翻译成c语言,然后用gcc来编译。这样的话,找不到头文件。
那我有什么办法可以通过systemtap插入c++代码呢?感谢
Yu Feng Reply:
April 11th, 2013 at 1:29 am
kernel是c实现的,用c++很不安全。
翻到您的这篇古文:)将俺从手写include文件路径中解脱出来了。谢谢谢谢
Yu Feng Reply:
May 15th, 2013 at 1:32 pm
呵呵,方便你就好~