From: https://www.cnblogs.com/honpey/p/4575928.html

kprobe原理解析(一)

kprobe是linux内核的一个重要特性,是一个轻量级的内核调试工具,同时它又是其他一些更高级的内核调试工具(比如perf和systemtap)的“基础设施”,4.0版本的内核中,强大的eBPF特性也寄生于kprobe之上,所以kprobe在内核中的地位就可见一斑了。本文想把kprobe的原理掰碎了给大家看。

怎么讲kprobe,我把整个讲述分为两部分,第一部分是kprobe怎么用,第二是kprobe的原理。本篇博客先说kprobe怎么用。

kprobe是什么?

如何高效地调试内核?printk是一种方法,但是printk终归是毫无选择地全量输出,某些场景下不实用,于是你可以试一下tracepoint,我使能tracepoint机制的时候才输出。对于傻傻地放置printk来输出信息的方式,tracepoint是个进步,但是tracepoint只是内核在某些特定行为(比如进程切换)上部署的一些静态锚点,这些锚点并不一定是你需要的,所以你仍然需要自己部署tracepoint,重新编译内核。那么kprobe的出现就很有必要了,它可以在运行的内核中动态插入探测点,执行你预定义的操作。

kprobe怎么使用?

kprobe主要有两种使用方法,一是通过模块加载;二是通过debugfs接口。

模块加载的方式:内核源码下有目录下 samples/kprobes,该目录下有许多kprobes的例子,可以仿照这些例子写自己的kprobe模块。以kprobe_example.c为例,首先声明一个kprobe结构体,然后定义其中几个关键成员变量,包括symbol_name,pre_handler,post_handler。其中,symbol_name是函数名(kprobe_example.c中该项为do_fork),告诉内核我的探测点放置在了函数do_fork处,pre_hander和post_hander分别表示在执行探测点之前和之后执行的钩子函数。然后通过register_kprobe函数注册kprobe即可。将kprobe_example.ko inmod进内核之后,每当系统新启动一个进程,比如执行ls,cat等,都会输出:

  1. pre_hander: p->addr = 0x***, ip = ****.
  2. post_handler: p->addr = 0x***, pc = ****.

第一行是执行pre_handler钩子函数的输出,第二行是执行post_handler钩子函数的输出,当然这些都是内核中案例的写法,你可以写自己的钩子函数。

通过debugfs接口注册kprobe:模块加载的终究不是很方便,尤其对于一些不带gcc的嵌入式系统,需要交叉编译ko,将ko拷贝到单板,然后insmod,不便。debugfs下(确切地说,应该是ftrace)提供了一套注册、使能、注销kprobe的接口,可以很方便地操作kprobe。

用法如下:

1. cd /sys/kernel/debug/tracing【有些系统没有挂载debugfs,需要先挂载下 mount -t debugfs nodev /sys/kernel/debug】

2. 进入到tracing目录,这里就是传说中ftrace的天下了,执行:

  1. echo "p:sys_write_event sys_write" > kprobe_events

向kprobe_events写入"p:sys_write sys_write",注册kprobe事件。你会发现,当前目录下的events下,新增一个kprobes目录,该目录下:

  1. root@station:/sys/kernel/debug/tracing/events/kprobes# ls
  2. enable filter sys_write_event

即,我们注册的kprobe事件生效了。那么"p:sys_write_event sys_write"是什么意思呢?首先p表示我们要注册一个kprobe,如果要注册retprobe,此处应为r;sys_write_event表示这个kprobe叫什么名字;sys_write表示我们的插入点在哪里。那么,“p:sys_write_event sys_write”的语义就很明显了:在函数sys_write处插入一个kprobe点,这个点的名字叫sys_write_event。

3. 使能kprobe。执行:

  1. cd /sys/kernel/debug/tracing/events/kprobes/events/sys_write_event
  2. echo 1 > enable
  3. cd ../../.. 【退回到/sys/kernel/debug/tracing,查看trace文件的输出】
  4. cat trace

trace文件的输出是如下的:

  1. .....
  2.    bash-808 [003] d... 42715.347565: sys_write_event: (SyS_write+0x0/0xb0)
  3. .....

解释下置红的这条输出:pid为808的进程bash,在自本次开机42715.345565秒的时候,调用了一次函数sys_write。

4. 撤消kprobe。执行

  1. cd /sys/kernel/debug/tracing/events/kprobes/events/sys_write_event
  2. echo 0 > enable【首先先关闭kprobe
  3. cd ../../..
  4.    echo "-:kprobes/sys_write_event" >> kprobe_events 【注销kprobe

以上就是kprobe的两种注册及使用方式:通过模块加载以及通过debugfs注册。这两种使用方法有什么联系?

使用模块加载的方式,是kprobe的一种原始用法:在kprobe结构体里定义插入点、钩子函数,然后通过register_kprobe注册上这个kprobe即可。ftrace接口是kprobe的一种应用,它是一套trace的框架,下面的trace机制包括tracepoint、function trace等,kprobe仅仅是这些trace机制中的一员。上面的讲述我们也已经看出来了,通过ftrace注册的kprobe的输出是在ftrace的输出:trace文件。模块加载模式中我们可以自定义kprobe的钩子函数pre_handler和post_handler,但是在ftrace下注册的kprobe的钩子是ftrace接口默认的,我们设置不了,但是具体输出什么,我们可以在echo “p:sys_write_event sys_write"时指定,比如指定x1寄存器的内容等,所以ftrace下注册的kprobe功能同样很强大。同时,由于ftrace下kprobe的输出基于ftrace的输出框架,所以输出信息包含当前进程、CPU、时间戳等信息,对于trace来说非常有用。

好了,kprobe的用法先介绍到这里了,这都是最简单的用法,高级用法可以参看内核文档:kprobes.txt 以及 kprobetrace.txt。kprobe的原理将在下面一篇博客中详细介绍。

[转载] kprobe原理解析(一)的更多相关文章

  1. kprobe原理解析(一)

    kprobe是linux内核的一个重要特性,是一个轻量级的内核调试工具,同时它又是其他一些更高级的内核调试工具(比如perf和systemtap)的“基础设施”,4.0版本的内核中,强大的eBPF特性 ...

  2. kprobe原理解析(二)

    上一篇文章和大家简要说明了下kprobe到底应该怎样用,那么现在我们就揭开kprobe神秘的面纱,刨根问底,一睹kprobe的庐山真面目. kprobe的工作过程大致如下: 1)注册kprobe.注册 ...

  3. kprobe原理解析

    参考  http://www.cnblogs.com/honpey/p/4575928.html kprobe是linux内核的一个重要特性,是一个轻量级的内核调试工具,同时它又是其他一些更高级的内核 ...

  4. 【转载】Java类加载原理解析

    Java类加载原理解析 原文出处:http://www.blogjava.net/zhuxing/archive/2008/08/08/220841.html 1       基本信息 摘要: 每个j ...

  5. appium 原理解析(转载雷子老师博客)

    appium 原理解析 原博客地址:https://www.cnblogs.com/leiziv5/p/6427609.html Appium是 c/s模式的appium是基于 webdriver 协 ...

  6. Objective-C通过联合存储为类增加属性及原理解析

    联合存储实现方式及底层原理解析 作者:wangzz 原文地址:http://blog.csdn.net/wzzvictory_tjsd/article/details/9347981 转载请注明出处 ...

  7. 爱加密Android APk 原理解析

    转载请标明出处:http://blog.csdn.net/u011546655/article/details/45921025 爱加密Android APK加壳原理解析 一.什么是加壳? 加壳是在二 ...

  8. JSONP跨域的原理解析及其实现介绍

    JSONP跨域的原理解析及其实现介绍 作者: 字体:[增加 减小] 类型:转载 时间:2014-03-22 JSONP跨域GET请求是一个常用的解决方案,下面我们来看一下JSONP跨域是如何实现的,并 ...

  9. 秋色园QBlog技术原理解析:性能优化篇:缓存总有失效时,构造持续的缓存方案(十四)

    转载自:http://www.cyqdata.com/qblog/article-detail-38993 文章回顾: 1: 秋色园QBlog技术原理解析:开篇:整体认识(一) --介绍整体文件夹和文 ...

随机推荐

  1. Broccoli & Babel使用演示样例

    1 创建项目project文件夹:test 2 在test下运行 npm init 按提示填写package.json文件 3 安装broccoli命令行工具broccoli-cli npm inst ...

  2. 剑指Offer面试题29(java版):数组中出现次数超过一半的数字

    题目:数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字. 比如输入一个长度为9的数组{1,2,3,2.2,2.5,4,2}.因为数字2在数组中出现5次,超过数组长度的一半,因此输出2. 解 ...

  3. Razor基础,视图里如何调用controller里的函数

    1.单行代码书写 @代码 2.多行代码书写 @{ //@加个大括号就可以在里面写C#代码了. C#代码第一行 C#代码第二行 } 3.Razor模板引擎会自动判别代码块,但是当代码存在二义性的时候,可 ...

  4. VC++ 模拟"CLICK事件"关闭指定窗体

    今天改动一个工具时遇到一个有意思的问题,打开某个窗体时弹出一些不相关的窗体.须要用户自己去手动点击后才干继续.保证不了自己主动处理,如今解说决方案记录一下,例如以下 主要使用windows提供的Fin ...

  5. NSoup解析处理Html

    以前在做网页静态生成的时候,使用正则表达式分析提取网页链接.最近搜索了解到java有个Jsoup解析网页,对应.net有个nsoup.处理网页非常好用. Document doc = NSoupCli ...

  6. 【OI】对拍

    对拍的方法是先用生成器生成几组随机数据,然后用暴力算法和当前算法对比结果来确保正确性. 数据生成器: 引入cstdlib与ctime两个库,然后通过srand初始化随机数: srand(time(0) ...

  7. eclipse android开发,文本编辑xml文件,给控件添加ID后,R.java,不自动的问题。

    直接编辑xml文件给控件添加id,不自动更新.原来的id写法:@id/et_tel 然后改写成这样:@+id/et_tel  然后就好了!操`1

  8. CPU上电时序详细分析

    首先是RTC电源,这部分电力是永远不关闭的,除非电池(纽扣电池)没电并且没接任何外部电源(比如电池和电源适配器). RTC用以保持机器内部时钟的运转和保证CMOS配置信息在断电的情况下不丢失:其次,在 ...

  9. YTU 2500: 二元表达式计算

    2500: 二元表达式计算 时间限制: 1 Sec  内存限制: 128 MB 提交: 38  解决: 23 题目描述 根据输入的含有两个二元运算的表达式,编程计算并输出表达式的值.如输入:  2+9 ...

  10. build_native.py文件分析(2)

    def build(ndk_build_param,android_platform,build_mode): ////获取ndk_root -- NDK_ROOT = os.environ['NDK ...