编辑
2024-12-17
工作知识
0
请注意,本文编写于 171 天前,最后修改于 171 天前,其中某些信息可能已经过时。

目录

一:内核源码
二:编译
三 编译systemtap
四 简单测试
参考链接:

在ldd上看到了systemtap这个东西,他是基于kprobe的内核调试工具,这里主要描述一下systemtap前期的环境搭建,和运行简单的systemtap命令

主要有如下几个步骤

  1. 拉取内核源码

  2. 配置内核config和编译

  3. 编译systemtap源码

  4. 使用stap命令进行简单的测试使用

一:内核源码

这里我使用的是ubuntu2004,可用直接通过apt命令拉取内核代码

apt download linux-source-5.13.0 得到linux-source-5.13.0_5.13.0-37.42_all.deb

安装这个deb

dpkg -i linux-source-5.13.0_5.13.0-37.42_all.deb 得到/usr/src/linux-source-5.13.0 tar xvjf linux-source-5.13.0.tar.bz2 cp -rf debian linux-source-5.13.0

二:编译

在内核里面可用看到默认的defconfig arch/x86/configs/x86_64_defconfig

编译defconfig

make x86_64_defconfig

安装编译内核相关的依赖包

apt-get build-dep linux-source-5.13.0

systemtap依赖一些内核选项

CONFIG_DEBUG_FS CONFIG_DEBUG_KERNEL CONFIG_DEBUG_INFO CONFIG_KPROBES

这里修改.config加上即可

直接编译内核即可

make bindeb-pkg -j16

编译完成之后,会在上级目录生成对应的deb文件如下

linux-headers-5.13.19_5.13.19-3_amd64.deb linux-image-5.13.19-dbg_5.13.19-3_amd64.deb linux-image-5.13.19_5.13.19-3_amd64.deb linux-libc-dev_5.13.19-3_amd64.deb

直接安装上述deb即可

重启机器,让系统从新的内核上启动,开机之后,可用uname -a查看内核版本

/boot/vmlinuz -> vmlinuz-5.13.19 uname -a Linux kylin 5.13.19 #3 SMP Tue Apr 19 17:19:44 CST 2022 x86_64 x86_64 x86_64 GNU/Linux

三 编译systemtap

内核准备好了,但是因为内核是5.13.19。而系统中默认安装的systemtap支持不了这么高的内核版本,如果使用ubuntu2004默认提供的systemtap,会报如下错误

fails with vermagic.h:6:2: error: #error "This header can be included from kernel/module.c or *.mod.c only"

所以需要编译新的systemtap

从git拉systemtap的仓库代码

git clone git://sourceware.org/git/systemtap.git

默认使用最新的分支

安装编译的依赖

apt-get build-dep systemtap

编译

./configure make all -j8 make install -j8

编完之后,stap默认安装在local目录

/usr/local/bin/stap --version Systemtap translator/driver (version 4.6/0.176, non-git sources) Copyright (C) 2005-2021 Red Hat, Inc. and others This is free software; see the source for copying conditions. tested kernel versions: 2.6.32 ... 5.15.0-rc7 enabled features: AVAHI BOOST_STRING_REF BPF LIBSQLITE3 NLS NSS

创建软链接

ln -s /usr/local/bin/stap /usr/bin/stap

从上面可用看到,这个stap可以支持最高到5.15.0-rc7的内核版本

四 简单测试

stap -l 'kernel.function("acpi_*")'

上面命令运行之后,会查看到内核的以acpi_开头的所有函数

如果需要使用stp文件进行加载,最简单的hello world如下

probe begin { print ("Hello World\n") exit () }

通过stap命令运行

stap -v hello.stp

能够出现Hello World即可正常

下面测试最简单的内核ko。

编写hello驱动

cat hello.c #include <linux/init.h> #include <linux/module.h> MODULE_LICENSE("Dual BSD/GPL"); static int hello_init(void) { printk(KERN_ALERT "Hello, world\n"); return 0; } static void hello_exit(void) { printk(KERN_ALERT "Goodbye, cruel world\n"); } module_init(hello_init); module_exit(hello_exit);
cat Makefile # If KERNELRELEASE is defined, we've been invoked from the # kernel build system and can use its language. CFLAGS_MODULE += -g ifneq ($(KERNELRELEASE),) obj-m := hello.o # Otherwise we were called directly from the command # line; invoke the kernel build system. else KERNELDIR ?= /lib/modules/$(shell uname -r)/build PWD := $(shell pwd) default: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules endif

make生成hello.ko

将其拷贝到stap识别的目录上

mkdir /usr/lib/modules/`uname -r`/extra/ cp hello.ko /usr/lib/modules/5.13.19/extra/hello.ko

查看stap能否识别到hello.ko

stap -l 'module("hello").function("*")' module("hello").function("hello_exit@/root/ko/hello.c:10") module("hello").function("hello_init@/root/ko/hello.c:5")

编写hello.stp 做简单测试

cat hello.stp #!/usr/bin/stap probe module("hello").function("hello_exit").call { printf("Stap say hello world!\n"); }

先加载ko

insmod /usr/lib/modules/5.13.19/extra/hello.ko

然后加载stap脚本

stap -v hello.stp Pass 1: parsed user script and 481 library scripts using 103440virt/86100res/7488shr/78676data kb, in 420usr/80sys/507real ms. Pass 2: analyzed script: 1 probe, 0 functions, 0 embeds, 0 globals using 105444virt/89108res/8400shr/80680data kb, in 40usr/90sys/123real ms. Pass 3: using cached /root/.systemtap/cache/2a/stap_2a22c74fa0e66004c4e56eb4b264ae1b_1029.c Pass 4: using cached /root/.systemtap/cache/2a/stap_2a22c74fa0e66004c4e56eb4b264ae1b_1029.ko Pass 5: starting run.

看到Pass 5了,说明脚本在监听了

在另一个终端卸载ko驱动 就能监听到hello_exit函数的调用了

rmmod hello 后终端会如下显示 Stap say hello world!

参考链接:

https://wiki.debian.org/BuildADebianKernelPackage
https://wiki.ubuntu.com/Kernel/Systemtap
https://sourceware.org/systemtap/wiki