Kprobe在Linux kernel debug中的应用
2016-02-01 00:00
921 查看
http://www.linuxidc.com/Linux/2013-01/77578.htm
一直在做kernel开发方面的工作,也一直苦于kernel
debug的困惑,到底如何进行kernel开发的debug的工作?今天经美国同事的推荐,我认为kprobe是一个非常好的debug工具。其本质原
理就是在你需要probe的地方放入断点指令,然后在断点处调用你的调试/测试程序,从而可以实现对kernel程序的调试/测试。
Kprobe只是提供了一种机制,使得用户可以在系统运行时调试/测试内核程序。使用Kprobe需要做如下几件事情:
1,需要找到测试点所对应的内存地址。这件工作可能是最麻烦的,如果测试点是函数,那么可以通过/proc/kallsyms接口得到需要测试函数
的内存地址,当然也可以通过kallsyms_lookup_name函数找到函数的内存地址。如果测试点是函数中间的某个位置,那么需要通过通过反汇编
找到这个内存地址,这一步可以通过objdump来完成。目前,我不知道是不是有现成的程序可以完成测试点内存地址的查找工作,我觉得完全可以开发一个
perl脚本对ko文件解析,从而获取测试点的内存地址。
2,写一个kernel module,完成信息收集,测试等工作,所有的测试代码需要在这个kernel module中完成。
下面是我今天的一个测试程序,用Kprobe测试一个内核函数所用的jiffies时间,基本上是一个Kprobe kernel module的基本框架,仅供参考:
点击(此处)折叠或打开
/*
* kprobe_jiffies.c
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/kprobes.h>
#include <linux/kallsyms.h>
/* global probe object */
struct kprobe probe;
/* jiffies record */
unsigned long jiffies_enter = 0;
unsigned long jiffies_exit = 0;
/*
* enter the probe pointer
*/
static int pre_probe(struct kprobe *probe, struct pt_regs *regs)
{
jiffiesjiffies_enter = jiffies;
return 0;
}
/*
* exit the probe pointer
*/
static void post_probe(struct kprobe *probe, struct pt_regs *regs, unsigned long flags)
{
unsigned long diff;
jiffiesjiffies_exit = jiffies;
diff = jiffies_exit - jiffies_enter;
printk("spending time: %lu, enter: %lu, exit: %lu\n",
diff, jiffies_enter, jiffies_exit);
}
static int __init kprobe_jiffies_init(void)
{
probe.pre_handler = pre_probe;
probe.post_handler = post_probe;
probe.addr = (kprobe_opcode_t *) kallsyms_lookup_name("probe_function");
if (probe.addr == NULL) {
printk("Cannot find out 'dd_xor_encode_sse' in system\n");
return 1;
}
register_kprobe(&probe);
printk("register probe jffies driver.\n");
return 0;
}
static void __exit kprobe_jiffies_exit(void)
{
unregister_kprobe(&probe);
printk("unregister probe jffies driver.\n");
return;
}
module_init(kprobe_jiffies_init);
module_exit(kprobe_jiffies_exit);
MODULE_AUTHOR("xxx");
MODULE_DESCRIPTION("kernel probe driver");
MODULE_LICENSE("GPL");
我想Kprobe是个非常不错的东西,如果在Kprobe的基础上包装一下,使得用户更加容易的使用,那么对内核程序的调试将是会发生革命性的变化。我想有时间我应该在Kprobe的基础上做一个内核调试工具了。
一直在做kernel开发方面的工作,也一直苦于kernel
debug的困惑,到底如何进行kernel开发的debug的工作?今天经美国同事的推荐,我认为kprobe是一个非常好的debug工具。其本质原
理就是在你需要probe的地方放入断点指令,然后在断点处调用你的调试/测试程序,从而可以实现对kernel程序的调试/测试。
Kprobe只是提供了一种机制,使得用户可以在系统运行时调试/测试内核程序。使用Kprobe需要做如下几件事情:
1,需要找到测试点所对应的内存地址。这件工作可能是最麻烦的,如果测试点是函数,那么可以通过/proc/kallsyms接口得到需要测试函数
的内存地址,当然也可以通过kallsyms_lookup_name函数找到函数的内存地址。如果测试点是函数中间的某个位置,那么需要通过通过反汇编
找到这个内存地址,这一步可以通过objdump来完成。目前,我不知道是不是有现成的程序可以完成测试点内存地址的查找工作,我觉得完全可以开发一个
perl脚本对ko文件解析,从而获取测试点的内存地址。
2,写一个kernel module,完成信息收集,测试等工作,所有的测试代码需要在这个kernel module中完成。
下面是我今天的一个测试程序,用Kprobe测试一个内核函数所用的jiffies时间,基本上是一个Kprobe kernel module的基本框架,仅供参考:
点击(此处)折叠或打开
/*
* kprobe_jiffies.c
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/kprobes.h>
#include <linux/kallsyms.h>
/* global probe object */
struct kprobe probe;
/* jiffies record */
unsigned long jiffies_enter = 0;
unsigned long jiffies_exit = 0;
/*
* enter the probe pointer
*/
static int pre_probe(struct kprobe *probe, struct pt_regs *regs)
{
jiffiesjiffies_enter = jiffies;
return 0;
}
/*
* exit the probe pointer
*/
static void post_probe(struct kprobe *probe, struct pt_regs *regs, unsigned long flags)
{
unsigned long diff;
jiffiesjiffies_exit = jiffies;
diff = jiffies_exit - jiffies_enter;
printk("spending time: %lu, enter: %lu, exit: %lu\n",
diff, jiffies_enter, jiffies_exit);
}
static int __init kprobe_jiffies_init(void)
{
probe.pre_handler = pre_probe;
probe.post_handler = post_probe;
probe.addr = (kprobe_opcode_t *) kallsyms_lookup_name("probe_function");
if (probe.addr == NULL) {
printk("Cannot find out 'dd_xor_encode_sse' in system\n");
return 1;
}
register_kprobe(&probe);
printk("register probe jffies driver.\n");
return 0;
}
static void __exit kprobe_jiffies_exit(void)
{
unregister_kprobe(&probe);
printk("unregister probe jffies driver.\n");
return;
}
module_init(kprobe_jiffies_init);
module_exit(kprobe_jiffies_exit);
MODULE_AUTHOR("xxx");
MODULE_DESCRIPTION("kernel probe driver");
MODULE_LICENSE("GPL");
我想Kprobe是个非常不错的东西,如果在Kprobe的基础上包装一下,使得用户更加容易的使用,那么对内核程序的调试将是会发生革命性的变化。我想有时间我应该在Kprobe的基础上做一个内核调试工具了。
相关文章推荐
- (OK) 调试cBPM—CentOS7—gdb—gdbserver—问题的解决—2—段错误
- Linux内核kprobe机制实现浅析
- 世界上最差的系统就是linux,双击不能安装软件
- linux awk命令详解
- linux下为php添加curl扩展的方法
- (OK) 调试cBPM—CentOS7—gdb—gdbserver—问题的解决—3—段错误
- Hashcat——Cracking WPA2 WPA with Hashcat in Kali Linux
- (OK) 调试cBPM—CentOS7—gdb—gdbserver—问题的解决—4—段错误
- 2013上半年—Linux操作系统—中考
- arm linux 内核生成过程
- (OK) mkisofs——in linux
- 向日葵远程控制软件发布Linux被控端1.0Beta版
- 2014上半年—Linux操作系统—嵌入式开发—中考
- Skype—set font size —in CentOS/Fedora/RHEL—修改Skype字体大小
- 打造自己的多功能USB启动盘——grub2引导WinPE、Archlinux安装镜像和Ubuntu liveCD
- (OK) 运行cBPM—CentOS7
- jq : Linux下json的命令行工具
- Andriod被排出Linux内核的原因
- centos搭建SmokePing监控IDC丢包延迟
- Linux实时性分析-schedule-调度器