用kprobes实现内核反射机制
时间:2007-08-22 11:24:17 来源:CUBLOG 作者:李先静
前几天在设计事件管理器时,我就在考虑磁盘满的问题,磁盘满是一个典型的系统事件,没有什么好说的,问题是应该何时何地触发它呢?如果由应用程序在操作文件时触发,那将有很多地方需要修改,这不是我们期望的。如果能在一个地方统一处理,那就省事多了,说到统一处理,我们自然会想到修改glibc或者内核的代码。
但修改glibc或者内核的代码也非我所愿,对于这些标准的软件包,除非是有BUG,否则我是不情愿去修改它们的,特别是加入这种专用功能,因为那让以后的维护比较麻烦,升级不方便。最好的办法就是不用修改代码,而动态的改变某些函数的行为。
gcc有一个选项-finstrument-functions,它可以在函数调用前后注入指定代码,利用这些注入的代码来改变函数的行为,这是一个非常酷的特性,常用作高级的调试技巧。但我可不想给glibc中每一个函数调用都注入代码,那可能会对性能造成严重的影响。
ELF文件都是由/lib/ld-linux.so.2加载的,ld-linux提供了一种PRELOAD机制,它用于优先加载指定的共享库,可以通过LD_PRELOAD环境变量或/etc/preload.conf配置文件来指定共享库。这倒是一个不错的方法,在PRELOAD的共享库去实现部分文件操作函数,这样就可以方便的为这些函数增加新功能了。
今天无意中发现了一种更酷的方法,原来内核提供了一种称为kprobes的功能,利用它我们可以很容易实现反射机制,动态的修改某些函数的行为。下面是一个从linux-2.6.21/Documentation/kprobes.txt中抄出来的例子:
kretprobe-example.c
Makefile
Make之后用inmod插入kretprobe-example.ko:
make;insmod kretprobe-example.ko
再用vim打开/var/log/messages,可以看到诸如:
May 29 20:35:49 lixj kernel: sys_open returns -2
之类的信息。
不过,遗憾的是它只支持下面几个平台,没有ARM版本的实现,让我白开心了一回。
- i386
- x86_64 (AMD-64, EM64T)
- ppc64
- ia64 (Does not support probes on instruction slot1.)
- sparc64 (Return probes not yet implemented.)
更详细的内容可以阅读linux-2.6.21/Documentation/kprobes.txt。
作者联系方式:李先静 xianjimli@hotmail.com
原文链接: http://blog.chinaunix.net/u1/43721/showart_344464.html
参考资源:
http://blog.linux.org.tw/~jserv/archives/2007_01.html
http://research.microsoft.com/sn/detours/
linux-2.6.21/Documentation/kprobes.txt