用kprobes实现内核反射机制

来源:百度文库 编辑:神马文学网 时间:2024/06/12 03:39:24
这是 Google 对http://www.91linux.com/html/article/kernel/20070823/6399.html 的缓存。 这是该网页在 2008年6月27日 05:00:02 GMT 的快照。 当前页在此期间可能已经更改。 了解详情 »
纯文字版本突出显示以下搜索字词: python 反射 机制
高级搜索 收藏本站 网站地图 RSS订阅 首页 新闻 Ubuntu Fedora Gentoo Mandriva Slackware Suse 红旗 LFS C++ JAVA Perl PHP Python Ruby 入门 命令 多媒体 服务器 内核 嵌入式 软件 SHELL DB2 MySQL Oracle PostgreSQL Sybase    智能模糊搜索 仅搜索标题  热门关键字:  ubuntu  分区  linux系统进程  Fedora  函数
当前位置 :| 主页>Linux教程>内核研究> 用kprobes实现内核反射机制来源: 作者: 时间:2007-08-23 Tag: 点击: 32
前几天在设计事件管理器时,我就在考虑磁盘满的问题,磁盘满是一个典型的系统事件,没有什么好说的,问题是应该何时何地触发它呢?如果由应用程序在操作文件时触发,那将有很多地方需要修改,这不是我们期望的。如果能在一个地方统一处理,那就省事多了,说到统一处理,我们自然会想到修改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
#include
#include
#include
static const char *probed_func = "sys_open";
/* Return-probe handler: If the probed function fails, log the return value. */
static int ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
{
int retval = regs_return_value(regs);
if (retval < 0) {
printk("%s returns %d\n", probed_func, retval);
}
return 0;
}
static struct kretprobe my_kretprobe = {
.handler = ret_handler,
/* Probe up to 20 instances concurrently. */
.maxactive = 20
};
static int __init kretprobe_init(void)
{
int ret;
my_kretprobe.kp.symbol_name = (char *)probed_func;
if ((ret = register_kretprobe(&my_kretprobe)) < 0) {
printk("register_kretprobe failed, returned %d\n", ret);
return -1;
}
printk("Planted return probe at %p\n", my_kretprobe.kp.addr);
return 0;
}
static void __exit kretprobe_exit(void)
{
unregister_kretprobe(&my_kretprobe);
printk("kretprobe unregistered\n");
/* nmissed > 0 suggests that maxactive was set too low. */
printk("Missed probing %d instances of %s\n",
my_kretprobe.nmissed, probed_func);
}
module_init(kretprobe_init)
module_exit(kretprobe_exit)
MODULE_LICENSE("GPL");
Makefile
obj-m := kretprobe-example.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
clean:
rm -f *.mod.c *.ko *.o
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。
作者联系方式:李先静
[收藏] [推荐] [评论] [打印] [关闭] 0顶一下上一篇:Linux系统内核分析 使用GDB和QEMU来调试
下一篇:Linux操作系统下编译支持NTFS的内核模块 最新评论共有 4 位网友发表了评论 查看所有评论发表评论
评论内容:不能超过250字,需审核,请自觉遵守互联网相关政策法规。  用户名: 密码:  匿名?  注册 栏目列表 linux安装 Linux命令 Linux入门 Shell开发 编程开发 多媒体应用 分区和文件系统 服务器管理 热点关注深入理解LINUX内核中文版Linux内核下载linux ioctl()函数全面的framebuffer详解Linux 2.6 字符设备驱动程Linux重新编译内核指南linux内核IOCTL网络控制框Linux编译内核详解Linux内核编程实战经验谈Linux 2.6.16 udev问题升级linux内核到2.6.24linux2.6内核下的一个按键kmalloc, vmalloc分配的内linux 内核升级和系统引导如何编译Linux的内核Linux 2.6内核的编译步骤linux kernel API文档2.4内核编译详解Linux操作系统源代码详细Linux操作系统内核中工作 相关文章利用udev、sys动态创建linLinux内核bootsplash功能Linux下malloc/free与new/电压不足导致的内核BUG linux 内核调试(二)linux 内核调试(一)机制与策略-内核执行机制Linux2.6 内核的 Initrd Linux内核可移植性(一)-Linux内核可移植性(二)- 91Linux!
本文来自: (www.91linux.com) 详细出处参考:http://203.208.33.101/search?q=cache:jF1cX0DutRAJ:www.91linux.com/html/article/kernel/20070823/6399.html+python+%E5%8F%8D%E5%B0%84%E6%9C%BA%E5%88%B6&hl=zh-CN&ct=clnk&cd=21&gl=cn&st_usg=ALhdy28ifm_EP2b_DO7wRaBBucVJys_psg