Kprobes 是 Linux 中的轻量级装置,可以将断点插入到正在运行的内核之中。Kprobes 可以地收集处理器寄存器和全局数据结构等调试信息。甚至可以使用 Kprobes 来修改 寄存器值和全局数据结构的值。

Kprobes 向运行的内核中给定地址写入断点指令,插入一个探测器。 执行被探测的指令会导致断点错误。Kprobes 钩住(hook in)断点处理器并收集调试信息。Kprobes 甚至可以单步执行被探测的指令。

内核编译中开启CONFIG_KPROBE_EVENTS=y.即可动态添加kprobe

 

1.   工作原理

用户指定一个探测点,并把一个用户定义的处理函数关联到该探测点,当内核执行到该探测点时,相应的关联函数被执行,然后继续执行正常的代码路径。

kprobe实现了三种类型的探测点: kprobes, jprobes和kretprobes (也叫返回探测点)。 kprobes是可以被插入到内核的任何指令位置的探测点,jprobes则只能被插入到一个内核函数的入口,而kretprobes则是在指定的内核函数返回时才被执行。

l? ?  安装一个kprobes探测点,kprobe先备份被探测的指令,然后使用断点指令来取代被探测指令的头一个或几个字节。

l? ?  当执行到探测点时,将因运行断点指令而执行trap操作,保存CPU的寄存器,调用相应的trap处理函数。

l? ?  trap处理函数将调用相应的notifier_call_chain中注册的所有notifier函数,kprobe正是通过向trap对应的notifier_call_chain注册关联到探测点的处理函数来实现探测处理的。

l? ?  首先执行关联到探测点的pre_handler函数,并把相应的kprobe struct和保存的寄存器作为该函数的参数,最后kprobe执行post_handler。等所有这些运行完毕后,最后紧跟在被探测指令后的指令流。

如下图:

Linux中动态探针kprobes-LMLPHP

 

2.   kprobe初始化

kprobes作为一个模块,其初始化函数为init_kprobes,代码路径kernel/kprobes.c

 

Linux中动态探针kprobes-LMLPHP

3.   通过ftrace接口使用

可以通过

/sys/kernel/debug/tracing/kprobe_events,

https://yq.aliyun.com/articles/603176?utm_content=m_1000002940
12-11 06:14