linux内核调试工具之kprobe

Posted 为了维护世界和平_

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux内核调试工具之kprobe相关的知识,希望对你有一定的参考价值。

目录

一、探测内核函数

二、在内核模块上使用动态kprobe跟踪


前一章使用kprobe编程,需要编码手动编译。

本章使用trace追踪技术,在任何函数上设置动态kprobe(通过kprobe事件)。

一、探测内核函数

1、切换到tracing目录下

# cd /sys/kernel/debug/tracing

2、查询可动态探测的函数

#cat available_filter_functions | grep do_sys_open*
do_sys_openat2
do_sys_open

3、设置动态探测函数

echo "p: <kprobe-name> <function-to-probe> [...] >> kprobe_events

#echo "p:my_sys_open3 do_sys_openat2 file=+0(%si):string" > /sys/kernel/debug/tracing/kprobe_events

以上是在x86上运行的寄存器为 RDI,[R]SI,RDX,RCX,R8,R9

而在ARM_32上使用的寄存器r0、r1 、r2、 r3

在ARM_64上使用的寄存器为X0-X7

4、查看设置探测的点

#/sys/kernel/debug/tracing# ls -lR events/kprobes/
events/kprobes/:
total 0
-rw-r----- 1 root root 0 10月 26 07:42 enable
-rw-r----- 1 root root 0 10月 26 07:42 filter
drwxr-x--- 2 root root 0 10月 26 07:42 my_sys_open3

events/kprobes/my_sys_open3:
total 0
-rw-r----- 1 root root 0 10月 26 07:43 enable
-rw-r----- 1 root root 0 10月 26 07:42 filter
-r--r----- 1 root root 0 10月 26 07:42 format
-r--r----- 1 root root 0 10月 26 07:42 hist
-r--r----- 1 root root 0 10月 26 07:42 id
--w------- 1 root root 0 10月 26 07:42 inject
-rw-r----- 1 root root 0 10月 26 07:42 trigger

5、使能 

#echo 1 > events/kprobes/my_sys_open3/enable 

6、输出结果

cat trace

   systemd-oomd-656     [003] .....  1628.449020: my_sys_open3: (do_sys_openat2+0x0/0x160) file="/proc/meminfo"
           a.out-5386    [002] .....  1628.450621: my_sys_open3: (do_sys_openat2+0x0/0x160) file="/home/kprobe.c"
           a.out-5386    [002] .....  1628.461429: my_sys_open3: (do_sys_openat2+0x0/0x160) file="/home/kprobe.c"
           a.out-5386    [002] .....  1628.472403: my_sys_open3: (do_sys_openat2+0x0/0x160) file="/home/kprobe.c"
           a.out-5386    [002] .....  1628.483314: my_sys_open3: (do_sys_openat2+0x0/0x160) file="/home/kprobe.c"
           a.out-5386    [002] .....  1628.494283: my_sys_open3: (do_sys_openat2+0x0/0x160) file="/home/kprobe.c"

7、关闭

//首先禁用
echo 0 > events/kprobes/my_sys_open3/enable

//清除单个函数
echo "-: <kprobe-name>" >> kprobe_events


//清楚所有探测点
echo > /sys/kernel/tracing/kprobe_events

或者使用如下,单个探测点

echo 0 > events/kprobes/my_sys_open3/enable
echo "-:my_sys_open3" >> kprobe_events

二、在内核模块上使用动态kprobe跟踪

1、测试的内核模块,读写设备文件 miscdrv_rdwr.ko

加载内核模块

insmod miscdrv_rdwr.ko

在内核全局符号表中查找模块

root@ubuntu:~# grep miscdrv /proc/kallsyms 
ffffffffc0687000 t write_miscdrv_rdwr	[miscdrv_rdwr]
ffffffffc0687922 t write_miscdrv_rdwr.cold	[miscdrv_rdwr]
ffffffffc0687290 t open_miscdrv_rdwr	[miscdrv_rdwr]
ffffffffc0687480 t close_miscdrv_rdwr	[miscdrv_rdwr]

内核模块加载完成

2、探测函数设置

root@ubuntu:/sys/kernel/tracing# echo "p:mymiscdrv_wr read_miscdrv_rdwr" >> kprobe_events 
root@ubuntu:/sys/kernel/tracing# echo "p:mymiscdrv_wr write_miscdrv_rdwr" >> kprobe_events 
root@ubuntu:/sys/kernel/tracing# echo "p:mymiscdrv_wr open_miscdrv_rdwr" >> kprobe_events 

查看设置的事件

root@ubuntu:/sys/kernel/tracing# cat kprobe_events 
p:kprobes/mymiscdrv_wr read_miscdrv_rdwr
p:kprobes/mymiscdrv_wr write_miscdrv_rdwr
p:kprobes/mymiscdrv_wr open_miscdrv_rdwr

 使能

root@ubuntu:/sys/kernel/tracing# echo 1 > events/kprobes/mymiscdrv_wr/enable 

读取 (阻塞)

root@ubuntu:/sys/kernel/tracing# cat trace_pipe 

启用另外一个终端在应用层,读写内核模块函数

//写
root@ubuntu# ./rdwr_test_secret w /dev/llkd_miscdrv_rdwr  "hello world"
Device file /dev/llkd_miscdrv_rdwr opened (in write-only mode): fd=3
./rdwr_test_secret: wrote 12 bytes to /dev/llkd_miscdrv_rdwr

//读
root@ubuntu# ./rdwr_test_secret r /dev/llkd_miscdrv_rdwr
Device file /dev/llkd_miscdrv_rdwr opened (in read-only mode): fd=3
./rdwr_test_secret: read 11 bytes from /dev/llkd_miscdrv_rdwr
The 'secret' is:
 "hello world"

在第一个终端中的显示如下,探测到所监测的内核模块函数

root@ubuntu:/sys/kernel/tracing# cat trace_pipe 
 rdwr_test_secre-8530    [000] .... 77924.632520: mymiscdrv_wr: (open_miscdrv_rdwr+0x0/0x1f0 [miscdrv_rdwr])
 rdwr_test_secre-8530    [000] .... 77924.632824: mymiscdrv_wr: (write_miscdrv_rdwr+0x0/0x290 [miscdrv_rdwr])
 rdwr_test_secre-8533    [003] .... 77943.415055: mymiscdrv_wr: (open_miscdrv_rdwr+0x0/0x1f0 [miscdrv_rdwr])
 rdwr_test_secre-8533    [003] .... 77943.415123: mymiscdrv_wr: (read_miscdrv_rdwr+0x0/0x270 [miscdrv_rdwr])

参考

Kprobe-based Event Tracing — The Linux Kernel documentation

perf-tools/kprobe at master · brendangregg/perf-tools · GitHub

ABI相关

Overview of ARM64 ABI conventions | Microsoft Learn

https://cs.brown.edu/courses/cs033/docs/guides/x64_cheatsheet.pdf

Overview of ARM ABI Conventions | Microsoft Learn

以上是关于linux内核调试工具之kprobe的主要内容,如果未能解决你的问题,请参考以下文章

Linux内核调试技术——jprobe使用与实现

Linux内核调试技术——kretprobe使用与实现

Linux内核调试技术——jprobe使用与实现

当前的 Linux 内核调试技术

Linux-5.10.13 kprobe源码分析

eBPF监控工具bcc系列八BPF C