Kprobes

【用途】【参考kernel/Documentation/kprobes.txt帮助文档】

Kprobes是一个轻量级内核调试工具,同时又是其他一些更高级的内核调试工具(如perf和systemtap)的基础,在Linux 4.0内核版本中,eBPF特性也寄生于kprobe之上。

【原理】

Kprobes的主要作用是在指定函数调用前后添加自定义函数,从而实现动态探测点的功能。

Kprobes有两种使用方法:1)模块加载;2)通过debugfs操作。

【接口说明】【参考kernel/sample/kprobes】

关键结构体

#include <linux/kprobes.h>

struct kprobe {

kprobe_opcode_t *addr;                     /* Location of the probe point */

const char *symbol_name;                           /* Allow user to indicate symbol name of the probe point */

kprobe_pre_handler_t pre_handler;      /* Called before addr is executed */

kprobe_pre_handler_t post_handler;    /* Called after addr is executed */

kprobe_pre_handler_t fault_handler;    /* Called if executing addr caused a fault */

};

注册kprobes探测点

int register_kprobe(struct kprobe *p);

注销kprobes探测点

void unregister_kprobe(struct kprobe *p);

【实例】

/*

* NOTE: This example is works on x86 and powerpc.

* Here's a sample kernel module showing the use of kprobes to dump a

* stack trace and selected registers when do_fork() is called.

*  * For more information on theory of operation of kprobes, see

* Documentation/kprobes.txt

*  * You will see the trace data in /var/log/messages and on the console

* whenever do_fork() is invoked to create a new process.

*/

#include <linux/kernel.h>

#include <linux/module.h>

#include <linux/kprobes.h>

/* For each probe you need to allocate a kprobe structure */

static struct kprobe kp = {

.symbol_name    = "do_fork",

};

/* kprobe pre_handler: called just before the probed instruction is executed */

static int handler_pre(struct kprobe *p, struct pt_regs *regs) {

#ifdef CONFIG_X86

printk(KERN_INFO "pre_handler: p->addr = 0x%p, ip = %lx,"             " flags = 0x%lx\r\n",         p->addr, regs->ip, regs->flags);

#endif

#ifdef CONFIG_PPC

printk(KERN_INFO "pre_handler: p->addr = 0x%p, nip = 0x%lx,"             " msr = 0x%lx\r\n",         p->addr, regs->nip, regs->msr);

#endif

#ifdef CONFIG_MIPS

printk(KERN_INFO "pre_handler: p->addr = 0x%p, epc = 0x%lx,"             " status = 0x%lx\r\n",         p->addr, regs->cp0_epc, regs->cp0_status);

#endif

/* A dump_stack() here will give a stack backtrace */

return 0;

}

/* kprobe post_handler: called after the probed instruction is executed */

static void handler_post(struct kprobe *p, struct pt_regs *regs,                 unsigned long flags) {

#ifdef CONFIG_X86

printk(KERN_INFO "post_handler: p->addr = 0x%p, flags = 0x%lx\r\n",         p->addr, regs->flags);

#endif

#ifdef CONFIG_PPC

printk(KERN_INFO "post_handler: p->addr = 0x%p, msr = 0x%lx\r\n",         p->addr, regs->msr);

#endif

#ifdef CONFIG_MIPS

printk(KERN_INFO "post_handler: p->addr = 0x%p, status = 0x%lx\r\n",         p->addr, regs->cp0_status);

#endif

}

/*

* fault_handler: this is called if an exception is generated for any

* instruction within the pre- or post-handler, or when Kprobes

* single-steps the probed instruction.

*/

static int handler_fault(struct kprobe *p, struct pt_regs *regs, int trapnr) {

printk(KERN_INFO "fault_handler: p->addr = 0x%p, trap #%dn",         p->addr, trapnr);

/* Return 0 because we don't handle the fault. */

return 0;

}

static int __init kprobe_init(void) {

int ret;

kp.pre_handler = handler_pre;

kp.post_handler = handler_post;

kp.fault_handler = handler_fault;

ret = register_kprobe(&kp);

if (ret < 0) {

printk(KERN_INFO "register_kprobe failed, returned %d\r\n", ret);

return ret;

}

printk(KERN_INFO "Planted kprobe at %p\r\n", kp.addr);

return 0;

}

static void __exit kprobe_exit(void) {

unregister_kprobe(&kp);

printk(KERN_INFO "kprobe at %p unregistered\r\n", kp.addr);

}

module_init(kprobe_init) module_exit(kprobe_exit) MODULE_LICENSE("GPL");

Linux内核调试方法总结之Kprobes的更多相关文章

  1. Linux内核调试方法总结

    Linux内核调试方法总结 一  调试前的准备 二  内核中的bug 三  内核调试配置选项 1  内核配置 2  调试原子操作 四  引发bug并打印信息 1  BUG()和BUG_ON() 2   ...

  2. Linux内核调试方法总结【转】

    转自:http://my.oschina.net/fgq611/blog/113249 内核开发比用户空间开发更难的一个因素就是内核调试艰难.内核错误往往会导致系统宕机,很难保留出错时的现场.调试内核 ...

  3. 【转】Linux内核调试方法总结

    目录[-] 一  调试前的准备 二  内核中的bug 三  内核调试配置选项 1  内核配置 2  调试原子操作 四  引发bug并打印信息 1  BUG()和BUG_ON() 2  dump_sta ...

  4. Linux内核调试方法【转】

    转自:http://www.cnblogs.com/shineshqw/articles/2359114.html kdb:只能在汇编代码级进行调试: 优点是不需要两台机器进行调试. gdb:在调试模 ...

  5. Linux内核调试方法总结之反汇编

    Linux反汇编调试方法 Linux内核模块或者应用程序经常因为各种各样的原因而崩溃,一般情况下都会打印函数调用栈信息,那么,这种情况下,我们怎么去定位问题呢?本文档介绍了一种反汇编的方法辅助定位此类 ...

  6. Linux内核调试方法总结之栈帧

    栈帧 栈帧和指针可以说是C语言的精髓.栈帧是一种特殊的数据结构,在C语言函数调用时,栈帧用来保存当前函数的父一级函数的栈底指针,当前函数的局部变量以及被调用函数返回后下一条汇编指令的地址.如下图所示: ...

  7. Linux内核调试方法总结之序言

    本系列主要介绍Linux内核死机.异常重启类稳定性问题的调试方法. 在Linux系统中,一切皆为文件,而系统运行的载体,是一类特殊的文件,即进程.因此,我尝试从进程的角度分析Linux内核的死机.异常 ...

  8. Linux内核调试方法总结之ddebug

    [用途] Linux内核动态调试特性,适用于驱动和内核各子系统调试.动态调试的主要功能就是允许你动态的打开或者关闭内核代码中的各种提示信息.适用于驱动和内核线程功能调试. [使用方法] 依赖于CONF ...

  9. Linux内核调试方法总结之调试宏

    本文介绍的内核调试宏属于静态调试方法,通过调试宏主动触发oops从而打印出函数调用栈信息. 1) BUG_ON 查看bug处堆栈内容,主动制造oops Linux中BUG_ON,WARN_ON用于调试 ...

随机推荐

  1. Tomcat 一台机器运行多个Tomcat

    转 https://www.cnblogs.com/andy1234/p/8866588.html 在一台Win10 PC 上面同时开启两个Tomcat系统为例. 1. 硬件环境 2. 到Tomcat ...

  2. python 元组及操作

    # 元组是'不可变'的 list 使用小括号 创建后不允许修改 # 创建# t = ('a','b','c',1,2,3)# print(t)# print(type(t))# # 3# print( ...

  3. 制作的第一个java小游戏

    package java1; import java.awt.*; public class java1 extends Frame { //球桌和桌球图片 Image ball = Toolkit. ...

  4. 计算机系统结构总结_Multiprocessor & cache coherence

    Textbook:<计算机组成与设计——硬件/软件接口>  HI<计算机体系结构——量化研究方法>          QR 最后一节来看看如何实现parallelism 在多处 ...

  5. spring security OAuth2.0之客户端Client的实现

    项目代码:https://github.com/hankuikuide/microservice-spring-security-oauth2 网上多数的项目客户端都是采用纯js写,或用postman ...

  6. C# 各种加密

    using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Sec ...

  7. C++设计模式:访客模式

    访客模式:通俗的说, 就是定义一个访问者角色, 当对指定角色进行访问时要通过访问者进行访问. 访客模式的侵入性适中,仅在被访问的类里面加一个对外提供接待访问者的接口. 访客模式的优点: 符合单一职责原 ...

  8. 05-Django-session-admin

    # session- 为了应对HTTP协议的无状态性- 用来保存用户比较敏感的信息- 属于request的一个属性- 常用操作: - request.session.get(key, defaultV ...

  9. 九、LaTex中的浮动体

    未利用浮动体:

  10. 定时任务crond、crontab

    crontab命令是用来设置定时任务规则的配置命令,配置文件/etc/crontab 与/var/spool/cron/目录下当前用户名的文件. -l 显示当前定时任务 -e 编辑定时任务 对于roo ...