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等,都会输出:

pre_hander: p->addr = 0x***, ip = ****.

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的天下了,执行:

   echo "p:sys_write_event sys_write" > kprobe_events

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

root@station:/sys/kernel/debug/tracing/events/kprobes# ls
           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。执行:

      cd /sys/kernel/debug/tracing/events/kprobes/events/sys_write_event

echo 1 > enable

      cd ../../.. 【退回到/sys/kernel/debug/tracing,查看trace文件的输出】

    cat trace

trace文件的输出是如下的:

.....

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

.....

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

4)撤消kprobe。执行

cd /sys/kernel/debug/tracing/events/kprobes/events/sys_write_event

echo 0 > enable【首先先关闭kprobe】

cd ../../..

        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原理解析(一)

    From: https://www.cnblogs.com/honpey/p/4575928.html kprobe原理解析(一) kprobe是linux内核的一个重要特性,是一个轻量级的内核调试工 ...

  2. kprobe原理解析(二)

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

  3. kprobe原理解析

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

  4. [原][Docker]特性与原理解析

    Docker特性与原理解析 文章假设你已经熟悉了Docker的基本命令和基本知识 首先看看Docker提供了哪些特性: 交互式Shell:Docker可以分配一个虚拟终端并关联到任何容器的标准输入上, ...

  5. 【算法】(查找你附近的人) GeoHash核心原理解析及代码实现

    本文地址 原文地址 分享提纲: 0. 引子 1. 感性认识GeoHash 2. GeoHash算法的步骤 3. GeoHash Base32编码长度与精度 4. GeoHash算法 5. 使用注意点( ...

  6. Web APi之过滤器执行过程原理解析【二】(十一)

    前言 上一节我们详细讲解了过滤器的创建过程以及粗略的介绍了五种过滤器,用此五种过滤器对实现对执行Action方法各个时期的拦截非常重要.这一节我们简单将讲述在Action方法上.控制器上.全局上以及授 ...

  7. Web APi之过滤器创建过程原理解析【一】(十)

    前言 Web API的简单流程就是从请求到执行到Action并最终作出响应,但是在这个过程有一把[筛子],那就是过滤器Filter,在从请求到Action这整个流程中使用Filter来进行相应的处理从 ...

  8. GeoHash原理解析

    GeoHash 核心原理解析       引子 一提到索引,大家脑子里马上浮现出B树索引,因为大量的数据库(如MySQL.oracle.PostgreSQL等)都在使用B树.B树索引本质上是对索引字段 ...

  9. alibaba-dexposed 原理解析

    alibaba-dexposed 原理解析 使用参考地址: http://blog.csdn.net/qxs965266509/article/details/49821413 原理参考地址: htt ...

随机推荐

  1. gulp学习

    中文文档:http://www.gulpjs.com.cn/docs/api/ 一.gulp的API 1 gulp.src(); 这个方法是用来获取流的,但这个流里的内容不是原始的文件流,而是一个虚拟 ...

  2. 快速生成PDF书签

    PDF没有书签,就像吃饭没有筷子一样,虽然可以将就,但总不是很方便!现介绍一种快速生成书签的方法. 第一步,打开excel,制作书签目录,前面的一列是书签名称(黑色框),后面一列是PDF页码(红色框) ...

  3. Mssql链接mysql数据库

    最近在做mysql数据库实时同步到mssql数据库的方案,花了一周时间,测试通过了,在实际机器上测试出现了若干问题.第一个问题就是在mssql上链接mysql的问题. 第一步,安装 Mysql ODB ...

  4. SharePoint 2010 文档管理之点击次数

    前言:很多场景下,我们都需要对一篇文章或者文档的点击次数进行统计,然而SharePoint本身并没有给我们设计这样一个字段,所以我们需要通过简单的字段开发来实现这样一个功能. 一.创建项目: 1. 创 ...

  5. GridView自带的分页功能实现

    要实现GrdView分页的功能操作如下:1.更改GrdView控件的AllowPaging属性为true.2.更改GrdView控件的PageSize属性为 任意数值(默认为10)3.更改GrdVie ...

  6. SharePoint Server 2010 & WorkFlow related Limits

    Today, I have come across different workflow related limits for SharePoint Server 2010. Limit Maximu ...

  7. AsyncTask.cancel()的结束问题

    实际项目中有这么一个问题,用户进入详情界面,那么我们就要网络加载数据并展现在UI上,这个加载用线程或者异步. 这里就拿项目中统一用异步任务来获取网络数据把. 用户可能会有这么一个操作,它在一个商品(说 ...

  8. Android-Selector用法

    在项目开发的时候,由于系统给出的控件不够美观,因此开发时领导常常要我更改下界面,用美工给的图片取代系统图片.开始时,我只是给按钮等设置一下背景图片,这样做虽然美观了,但界面看起来却比较死板,比如用户点 ...

  9. Struts2--Helloworld

    搭建Struts2环境时,我们一般需要做以下几个步骤的工作: 1.找到开发Struts2应用需要使用到的jar文件. 2.创建Web工程 3.在web.xml中加入Struts2 MVC框架启动配置 ...

  10. iOS开发笔记10:圆点缩放动画、强制更新、远程推送加语音提醒及UIView截屏

    1.使用CAReplicatorLayer制作等待动画 CALayer+CABasicAnimation可以制作很多简单的动画效果,之前的博客中介绍的“两个动画”,一个是利用一张渐变色图片+CABas ...