systemmap 使用记录

一:内核支持

编译内核以支持systemtap :首先让内核中有调试信息,编译内核时需要加上 -g 标志;其次,你还需要在配置内核时将 Kprobe 和 debugfs 开关打开。

最终效果是,你能在内核 .config 文件中看到下面四个选项是设置的:

  CONFIG_DEBUG_INFO
  CONFIG_KPROBES
  CONFIG_DEBUG_FS
  CONFIG_RELAY

二:获取systemtap源码 

从此地址 https://sourceware.org/systemtap/ftp/releases下载已经发布的systemtap的源代码

依赖库:https://sourceware.org/elfutils/ftp/

 

$./configure  --host=arm-linux CC=aarch64-linux-gnu-gcc CXX=aarch64-linux-gnu-g++  --prefix=/home/workspace/systemtap-3.3/finstall   --disable-translator  --with-elfutils=/home/liushichang/arm_gcc_elfutil/include/elfutils    --disable-option-checking   --disable-nls   --enable-FEATRUE=no   CFLAGS="-I/home/arm_gcc_elfutil/include/elfutils -I/home/arm_gcc_elfutil/include" 

 

参考:SystemTap

ftbuild stap -r /home/kernel_tmp/linux-4.4.x-klinux  -a arm64 -B CROSS_COMPILE=aarch64-linux-gnu- -m soft soft.stp

编译完成后在对应主机上执行如下:

./bin/staprun  -x 6717(pid) ./soft.ko
./bin/staprun  -x 6717 ./soft.ko 
==irq number:dev_name
3,arch_timer->1420
10,eth0->10
14,PHYT0003:00->9
46,0000:0a:00.0->1
==workqueue wq_thread:work_func


==irq number:dev_name
3,arch_timer->1505
14,PHYT0003:00->148
10,eth0->34
46,0000:0a:00.0->3
==workqueue wq_thread:work_func

 

1. 从文件(通常以.stp作为文件名后缀)中读入并运行脚本:stap [选项] 文件名

2. 从标准输入中读入并运行脚本: stap [选项] -

3. 运行命令行中的脚本:stap [选项] -e 脚本

4. 直接运行脚本文件(需要可执行属性并且第一行加上#!/usr/bin/stap):./脚本文件名使用"Ctrl+C"中止SystemTap的运行。

systemtap的选项还在不断的扩展和更新中,其中最常用的选项包括:

-v -- 打印中间信息

-p NUM -- 运行完Pass Num后停止(缺省是运行到Pass 5)

-k -- 运行结束后保留临时文件不删除

-b -- 使用RelayFS文件系统来将数据从内核空间传输到用户空间

-M -- 仅当使用-b选项时有效,运行结束时不合并每个CPU的单独数据文件

-o FILE -- 输出到文件,而不是输出到标准输出

-c CMD -- 启动探测后,运行CMD命令,直到命令结束后退出

-g -- 采用guru模式,允许脚本中嵌入C语句

 

 

内核模块签名完成后,便可以使用 staprun 命令手工运行相关内核模块了

命令:

// 注意:签名脚本会将生产的内核模块重命名,需要将名字改回去……(脚本bug)
staprun -x {进程号} {内核模块名} > demo.bt

使用帮助文档:https://spacewander.gitbooks.io/systemtapbeginnersguide_zh/content/index.html

 

systemtap原理

SystemTap采用其他的内核框架做源:静态指针使用tracepoints,动态指针使用Kprobe。用户级别的使用uprobes。

Kprobes 从 2.6.9 版本开始就添加到主流的 Linux 内核中。它提供一些不同的服务,但最重要的两种服务是 Kprobe 和 Kretprobe。

Kprobe 特定于架构,它在需要检查的指令的第一个字节中插入一个断点指令。当调用该指令时,将执行针对探针的特定处理函数。执行完成之后,接着执行原始的指令(从断点开始)。

断点指令(breakpoint instruction):__asm INT 3,机器码为CC。
断点中断(INT3)是一种软中断,当执行到INT 3指令时,CPU会把当时的程序指针(CS和EIP)压入堆栈保存起来,
然后通过中断向量表调用INT 3所对应的中断例程。
INT是软中断指令,中断向量表是中断号和中断处理函数地址的对应表。
INT 3即触发软中断3,相应的中断处理函数的地址为:中断向量表地址 + 4 * 3。

Kretprobes 有所不同,它操作调用函数的返回结果。注意,因为一个函数可能有多个返回点,所以听起来事情有些复杂。不过,它实际使用一种称为 trampoline 的简单技术。您将向函数条目添加一小段代码,而不是检查函数中的每个返回点。这段代码使用 trampoline 地址替换堆栈上的返回地址 (Kretprobe 地址)。当该函数存在时,它没有返回到调用方,而是调用 Kretprobe(执行它的功能),然后从 Kretprobe 返回到实际的调用方。

stap 实用程序将 stap 脚本转换成提供探针行为的内核模块。https://klwork.com/category/018linux/systemtap.html

 

https://sourceware.org/systemtap/documentation.html

 https://files.cnblogs.com/files/codestack/install_systemmap.tar.gz

https://files.cnblogs.com/files/codestack/systemtap-crash.zip

 https://sourceware.org/systemtap/tapsets/

其systemmap api 有:https://sourceware.org/systemtap/tapsets/

可参考blog有:https://klwork.com/category/018linux/systemtap.html

https://sourceware.org/systemtap/wiki/WarStories

 https://sourceware.org/systemtap/SystemTap_Beginners_Guide/index.html

 

对于使用systemstp 探测用户态进程 可以参考: 

https://blog.csdn.net/wangzuxi/article/details/42976577

https://blog.csdn.net/wangzuxi/article/details/44901285

 

posted @ 2021-04-12 12:12  codestacklinuxer  阅读(232)  评论(0编辑  收藏  举报