• Linux kprobe初探


    最近学习bcc-tools工具的使用,发现单单会使用还是不行,必须了解到其深层次的原理,所以使用该工具的时候,加了-v指令,分析了下bcc的调用流程,大致如下:

    ^CTraceback (most recent call last):
      File "./funclatency", line 211, in <module>
        b.attach_kretprobe(event_re=pattern, fn_name="trace_func_return")
      File "/usr/lib/python2.7/site-packages/bcc/__init__.py", line 645, in attach_kretprobe
        for line in BPF.get_kprobe_functions(event_re):
      File "/usr/lib/python2.7/site-packages/bcc/__init__.py", line 525, in get_kprobe_functions
        (t, fn) = line.rstrip().split()[1:3]

    从内容来看,采用的kprobe探测功能实现,下面就简短介绍下kprobe的实现原理,后面到bcc熟悉的差不多后再结合bcc相关代码讲其是怎么通过kprobe实现的。

    kprobe作为轻量级内核调试工具,在诊断内核bug时有着先天独厚的优势,相关其他工具,kprobe有如下优点:

    1、不用更新内核

    2、可以以模块的形式加载进内核,用完后直接卸载即可,不会对内核造成污染

    3、动态跟踪,自由构造,灵巧轻便。

     

    kprobe实现原理:

    原汁原味可以查看kernel doc:Documentation/kprobes.txt建议在分析其原理时,一定要看下,此外还可以参考 samples/kprobes编写kprobe探测驱动。

    kprobe实现原理还是容易理解的,在调用跟踪函数前,插入kprobe指令至此执行pre_handler,例如通过软中断方式,进入单步调试,此时执行原先代码本该执行的指令,执行完成后返回会再次进入kprobe状态,执行post_handler,执行完成后再次从异常状态返回到代码顺序执行。从上面描述可知kprobe的实现机制其实就是在被探测的函数前后打点,执行到该点时,进入异常状态,使的程序暂停执行,去执行kprobe相关处理函数,执行完成后又再次从异常状态恢复到正常执行,此过程执行主要涉及到对EIP/SIP等相关寄存器的操作。 

    kprobe实现步骤:

    1. 注册kprobe:register_kprobe,此处关键是需要实现如下三个函数:pre_handler、post_handler和fault_handler
    2. 初始化kprobe:init_kprobe,和驱动的编写一样,实例化结构体,调用内核函数初始化
    3. 实现中断处理函数:跟踪一个函数的目的是什么。

    如何让内核支持kprobe

    1. CONFIG_KPROBES 
    2. CONFIG_MODULES:kprobe是按照驱动的形式加入进入内核的,所以支持驱动加载和卸载时最基本的
    3. CONFIG_MODULE_UNLOAD
    4. CONFIG_KALLSYMS:设置CONFIG_KALLSYMS_ALL为y将更好,此处主要让kprobe可以跟踪的内核函数kprobe。

     

  • 相关阅读:
    kotlin,短小精悍
    最近把Vue又看了下
    https://docs.spring.io/spring-framework/docs/current/reference/html/web-reactive.html#webflux-cors
    os模块——获取上层目录
    启动flask服务:flask run -h 0.0.0.0 -p 5000
    22端口和3389端口之我竟然用3389连接linux服务器,关键是我之前用22端口连接过linux!!!
    datetime 模块
    查看公网ip
    字典——删除元素
    docker端口映射
  • 原文地址:https://www.cnblogs.com/haoxing990/p/12116569.html
Copyright © 2020-2023  润新知