perf-tool工具是针对Linux内核的系统监测和分析工具,包含对网络、IO、系统调用等多种不同类型的内核分析工具,比如:iosnoop(针对IO的分析)、execsnoop(针对系统调用exec的分析)、tcpretrans(针对Linux tcp报文重传的分析工具)等十几种不同工具。
github地址为: git clone
本文是对execsnoop工具使用过程中遇到的问题进行了分析和定位。具体原因如下:在内核版本大于5.9的Linux系统中,使用execsnoop工具会出现下面的错误信息,
仔细分析execsnoop的源代码,在echo写入kprobe do_execve时出现的错误信息,kprobe_events文件在/sys/kernel/debug/tracing/kprobe_events,这里涉及到kprobe的相关知识,在此不多做介绍,不熟悉的请自行查询。向kprobe_events这个文件写入数据,有一定的格式要求和内容要求。
-
echo nop > current_tracer
-
if ! echo $kprobe >> kprobe_events 2>/dev/null; then
-
makeprobe stub_execve
-
if ! echo $kprobe >> kprobe_events 2>/dev/null; then
-
makeprobe do_execve
-
if ! echo $kprobe >> kprobe_events 2>/dev/null; then
-
edie "ERROR: adding a kprobe for execve. Exiting."
-
fi
-
fi
-
fi
上述代码把kprobe中的内容写入到kprobe_events中,在5.9的内核版本上面,kprobe的内容如下:
p:execsnoop_do_execve do_execve +0(+0(%si)):string +0(+8(%si)):string +0(+16(%si)):string +0(+24(%si)):string +0(+32(%si)):string +0(+40(%si)):string +0(+48(%si)):string +0(+56(%si)):string +0(+64(%si)):string
但是在写入kprobe_events文件时,产生上述错误信息,没有写入成功。如果写入成功后在/sys/kernel/debug/tracing/available_events 文件中可以看到一条events的命令。这个文件中包含的都是一些有效的events。
execsnoop脚本其实利用kprobe 内核的do_execve函数,来获取内核系统中的所有的进程信息,kprobe需要获取do_execve函数的地址,该地址可以通过下面两种方式获取到:1) /boot/System.map 2) /proc/kallsyms,在这两个文件中需要能够查找到相应的函数和函数地址后,才能在kprobe中使用。
在 5.9的内核中查找:do_execve函数的结果如下:
在4.19内核上查找:do_execve函数的结果如下:
通过对两个不同内核版本代码的分析可知,在5.9以后的内核中,do_execve函数在内核符号表中都是不存在的,因为do_execve函数在5.9的内核中使用了static定义该函数,因此在内核符号表中无法查找到该函数,具体的git commit为:7fce69dff8db30cb93aace0bbebda09972027af7 。
因此在后续的高版本的内核中,do_execve不在内核符号表中,在system.map中也无法查找到。导致使用execsnoop中出现上面的错误信息。
参考文献:
阅读(1126) | 评论(0) | 转发(0) |