From fcce84c634e2e1800fa3c43c1b1b41ba3c71cc1a Mon Sep 17 00:00:00 2001 From: Yuanhe Shu Date: Wed, 7 Dec 2022 11:55:00 +0800 Subject: [PATCH] Add Cloud Kernel Series course Signed-off-by: Yuanhe Shu --- .../.DS_Store" | Bin 0 -> 6148 bytes .../index.yaml" | 13 ++++ .../finish.md" | 5 ++ .../index.yaml" | 16 +++++ .../start.md" | 11 +++ .../step2.md" | 56 +++++++++++++++ .../step3.md" | 19 +++++ .../step4.md" | 10 +++ .../finish.md" | 5 ++ .../index.yaml" | 16 +++++ .../start.md" | 21 ++++++ .../step2.md" | 68 ++++++++++++++++++ .../step3.md" | 17 +++++ .../step4.md" | 35 +++++++++ 14 files changed, 292 insertions(+) create mode 100644 "anolis-courses/Cloud Kernel \347\263\273\345\210\227\350\257\276\347\250\213/.DS_Store" create mode 100644 "anolis-courses/Cloud Kernel \347\263\273\345\210\227\350\257\276\347\250\213/index.yaml" create mode 100644 "anolis-courses/Cloud Kernel \347\263\273\345\210\227\350\257\276\347\250\213/\345\234\250 Anolis \344\270\212\347\274\226\345\206\231\345\271\266\346\217\222\345\205\245\344\270\200\344\270\252\345\206\205\346\240\270\346\250\241\345\235\227/finish.md" create mode 100644 "anolis-courses/Cloud Kernel \347\263\273\345\210\227\350\257\276\347\250\213/\345\234\250 Anolis \344\270\212\347\274\226\345\206\231\345\271\266\346\217\222\345\205\245\344\270\200\344\270\252\345\206\205\346\240\270\346\250\241\345\235\227/index.yaml" create mode 100644 "anolis-courses/Cloud Kernel \347\263\273\345\210\227\350\257\276\347\250\213/\345\234\250 Anolis \344\270\212\347\274\226\345\206\231\345\271\266\346\217\222\345\205\245\344\270\200\344\270\252\345\206\205\346\240\270\346\250\241\345\235\227/start.md" create mode 100644 "anolis-courses/Cloud Kernel \347\263\273\345\210\227\350\257\276\347\250\213/\345\234\250 Anolis \344\270\212\347\274\226\345\206\231\345\271\266\346\217\222\345\205\245\344\270\200\344\270\252\345\206\205\346\240\270\346\250\241\345\235\227/step2.md" create mode 100644 "anolis-courses/Cloud Kernel \347\263\273\345\210\227\350\257\276\347\250\213/\345\234\250 Anolis \344\270\212\347\274\226\345\206\231\345\271\266\346\217\222\345\205\245\344\270\200\344\270\252\345\206\205\346\240\270\346\250\241\345\235\227/step3.md" create mode 100644 "anolis-courses/Cloud Kernel \347\263\273\345\210\227\350\257\276\347\250\213/\345\234\250 Anolis \344\270\212\347\274\226\345\206\231\345\271\266\346\217\222\345\205\245\344\270\200\344\270\252\345\206\205\346\240\270\346\250\241\345\235\227/step4.md" create mode 100644 "anolis-courses/Cloud Kernel \347\263\273\345\210\227\350\257\276\347\250\213/\345\234\250 Anolis \344\270\212\351\200\232\350\277\207vmcore\345\210\206\346\236\220\345\206\205\346\240\270panic\345\216\237\345\233\240/finish.md" create mode 100644 "anolis-courses/Cloud Kernel \347\263\273\345\210\227\350\257\276\347\250\213/\345\234\250 Anolis \344\270\212\351\200\232\350\277\207vmcore\345\210\206\346\236\220\345\206\205\346\240\270panic\345\216\237\345\233\240/index.yaml" create mode 100644 "anolis-courses/Cloud Kernel \347\263\273\345\210\227\350\257\276\347\250\213/\345\234\250 Anolis \344\270\212\351\200\232\350\277\207vmcore\345\210\206\346\236\220\345\206\205\346\240\270panic\345\216\237\345\233\240/start.md" create mode 100644 "anolis-courses/Cloud Kernel \347\263\273\345\210\227\350\257\276\347\250\213/\345\234\250 Anolis \344\270\212\351\200\232\350\277\207vmcore\345\210\206\346\236\220\345\206\205\346\240\270panic\345\216\237\345\233\240/step2.md" create mode 100644 "anolis-courses/Cloud Kernel \347\263\273\345\210\227\350\257\276\347\250\213/\345\234\250 Anolis \344\270\212\351\200\232\350\277\207vmcore\345\210\206\346\236\220\345\206\205\346\240\270panic\345\216\237\345\233\240/step3.md" create mode 100644 "anolis-courses/Cloud Kernel \347\263\273\345\210\227\350\257\276\347\250\213/\345\234\250 Anolis \344\270\212\351\200\232\350\277\207vmcore\345\210\206\346\236\220\345\206\205\346\240\270panic\345\216\237\345\233\240/step4.md" diff --git "a/anolis-courses/Cloud Kernel \347\263\273\345\210\227\350\257\276\347\250\213/.DS_Store" "b/anolis-courses/Cloud Kernel \347\263\273\345\210\227\350\257\276\347\250\213/.DS_Store" new file mode 100644 index 0000000000000000000000000000000000000000..38d1a3317d27d1a96bd0370c641975998ae964a1 GIT binary patch literal 6148 zcmeHKu}T9$5Phpbf;MRs5rnl9J3GrW#5QmSyiU|h(8%eD!L(juZCWco$KEgSQ+%_t z5f87H5N2Ta&Cbru?moEP8vw5RG&}@40NQMVPLu`_bK}%XbQW|WM~MPsOyK+L4T%=f zBzxb?_Th1id;Hq}^H%zHKFvSVQ6K$-^yTL0b}!3@lf1Yp%Yw(nZd2H7=k)_q+#zSO zM~qI_u4fXA2V8Q2G4jFt+1EVHA~IroG6swRW55_#b_V1TqqH{^tv3dY0b}5Y0l6PM zn_v>LQVdrIyHElUTQmouF13Wj_=riwN|7@Zr=dg*b+N>78cw^9eo4eiQN!WF%FGj2 zo)<4JtWLWR?r@2s^~QiPP-kFOhaGwUPx#3+7WwrM8yN$}z>+cGTD?K9%R|Mt_0RF- xt@UgdY$D=Ui9(@X`w8Gc?vd> +#include +#include + +MODULE_DESCRIPTION("My first kernel module"); +MODULE_AUTHOR("Me"); +MODULE_LICENSE("GPL"); + +static int dummy_init(void) +{ + pr_info("Hello World\n"); + return 0; +} + +static void dummy_exit(void) +{ + pr_info("Bye\n"); +} + +module_init(dummy_init); +module_exit(dummy_exit); +``` + +4. 编写Makefile文件 +[[ vim Makefile ]] +将以下内容复制到Makefile并保存退出(复制过程可能将tab转换为空格,请保证kbuild和clean的下行make前为tab而不是空格,空格会造成make行被红色长条覆盖) + +```s +obj-m:=my_module.o + +KDIR = /lib/modules/`uname -r`/build + +kbuild: + make -C $(KDIR) M=`pwd` + +clean: + make -C $(KDIR) M=`pwd` clean +``` + +错误的Makefile图示 +![wrong_makefile.png](https://anolis-pub-share.oss-cn-hangzhou.aliyuncs.com/anolis-lab/assets/1670380380735-wrong_makefile.png) + +正确的Makefile图示 +![true_makefile.png](https://anolis-pub-share.oss-cn-hangzhou.aliyuncs.com/anolis-lab/assets/1670380387994-true_makefile.png) \ No newline at end of file diff --git "a/anolis-courses/Cloud Kernel \347\263\273\345\210\227\350\257\276\347\250\213/\345\234\250 Anolis \344\270\212\347\274\226\345\206\231\345\271\266\346\217\222\345\205\245\344\270\200\344\270\252\345\206\205\346\240\270\346\250\241\345\235\227/step3.md" "b/anolis-courses/Cloud Kernel \347\263\273\345\210\227\350\257\276\347\250\213/\345\234\250 Anolis \344\270\212\347\274\226\345\206\231\345\271\266\346\217\222\345\205\245\344\270\200\344\270\252\345\206\205\346\240\270\346\250\241\345\235\227/step3.md" new file mode 100644 index 0000000..eaa5ab2 --- /dev/null +++ "b/anolis-courses/Cloud Kernel \347\263\273\345\210\227\350\257\276\347\250\213/\345\234\250 Anolis \344\270\212\347\274\226\345\206\231\345\271\266\346\217\222\345\205\245\344\270\200\344\270\252\345\206\205\346\240\270\346\250\241\345\235\227/step3.md" @@ -0,0 +1,19 @@ +现在已经完成了模块和Makefile的编写,接下来将介绍如何编译和插入一个模块 + +1. 编译my_module模块 +[[ make ]] + +2. 将已编译的文件写入盘内,防止内核crash后数据没刷到盘 +[[ sync ]] + +3. 编译完目录下会生成my_module.ko,使用insmod将模块进行插入 +[[ insmod my_module.ko ]] + +4. 通过lsmod查看模块信息 +[[lsmod | grep my_module ]] + +5. 插入后通过dmesg查看模块插入时的输出 +[[ dmesg | tail ]] +此时能看到Hello World的输出 + +![insmod.png](https://anolis-pub-share.oss-cn-hangzhou.aliyuncs.com/anolis-lab/assets/1670380359376-insmod.png) \ No newline at end of file diff --git "a/anolis-courses/Cloud Kernel \347\263\273\345\210\227\350\257\276\347\250\213/\345\234\250 Anolis \344\270\212\347\274\226\345\206\231\345\271\266\346\217\222\345\205\245\344\270\200\344\270\252\345\206\205\346\240\270\346\250\241\345\235\227/step4.md" "b/anolis-courses/Cloud Kernel \347\263\273\345\210\227\350\257\276\347\250\213/\345\234\250 Anolis \344\270\212\347\274\226\345\206\231\345\271\266\346\217\222\345\205\245\344\270\200\344\270\252\345\206\205\346\240\270\346\250\241\345\235\227/step4.md" new file mode 100644 index 0000000..e429367 --- /dev/null +++ "b/anolis-courses/Cloud Kernel \347\263\273\345\210\227\350\257\276\347\250\213/\345\234\250 Anolis \344\270\212\347\274\226\345\206\231\345\271\266\346\217\222\345\205\245\344\270\200\344\270\252\345\206\205\346\240\270\346\250\241\345\235\227/step4.md" @@ -0,0 +1,10 @@ +现在已经完成了模块的编写和插入,最后再介绍如何卸载一个内核模块 + +1. 通过rmmod卸载内核模块 +[[ rmmod my_module ]] + +2. 卸载后通过dmesg查看模块卸载后的输出 +[[ dmesg | tail ]] +此时能看到Bye的输出 + +![rmmod.png](https://anolis-pub-share.oss-cn-hangzhou.aliyuncs.com/anolis-lab/assets/1670380342534-rmmod.png) \ No newline at end of file diff --git "a/anolis-courses/Cloud Kernel \347\263\273\345\210\227\350\257\276\347\250\213/\345\234\250 Anolis \344\270\212\351\200\232\350\277\207vmcore\345\210\206\346\236\220\345\206\205\346\240\270panic\345\216\237\345\233\240/finish.md" "b/anolis-courses/Cloud Kernel \347\263\273\345\210\227\350\257\276\347\250\213/\345\234\250 Anolis \344\270\212\351\200\232\350\277\207vmcore\345\210\206\346\236\220\345\206\205\346\240\270panic\345\216\237\345\233\240/finish.md" new file mode 100644 index 0000000..389f43f --- /dev/null +++ "b/anolis-courses/Cloud Kernel \347\263\273\345\210\227\350\257\276\347\250\213/\345\234\250 Anolis \344\270\212\351\200\232\350\277\207vmcore\345\210\206\346\236\220\345\206\205\346\240\270panic\345\216\237\345\233\240/finish.md" @@ -0,0 +1,5 @@ +恭喜你完成了内核panic分析 + +如果还有其他问题,欢迎加入**钉钉交流群**咨询(搜索群号:33311793) +或者访问Cloud Kernel Sig 主页 +链接:https://openanolis.cn/sig/Cloud-Kernel \ No newline at end of file diff --git "a/anolis-courses/Cloud Kernel \347\263\273\345\210\227\350\257\276\347\250\213/\345\234\250 Anolis \344\270\212\351\200\232\350\277\207vmcore\345\210\206\346\236\220\345\206\205\346\240\270panic\345\216\237\345\233\240/index.yaml" "b/anolis-courses/Cloud Kernel \347\263\273\345\210\227\350\257\276\347\250\213/\345\234\250 Anolis \344\270\212\351\200\232\350\277\207vmcore\345\210\206\346\236\220\345\206\205\346\240\270panic\345\216\237\345\233\240/index.yaml" new file mode 100644 index 0000000..a791142 --- /dev/null +++ "b/anolis-courses/Cloud Kernel \347\263\273\345\210\227\350\257\276\347\250\213/\345\234\250 Anolis \344\270\212\351\200\232\350\277\207vmcore\345\210\206\346\236\220\345\206\205\346\240\270panic\345\216\237\345\233\240/index.yaml" @@ -0,0 +1,16 @@ +name: 在 Anolis 上通过vmcore分析内核panic原因 +desc: 本课程将介绍如何在 Anolis 通过crash工具对vmcore进行分析,从而找出内核panic的原因 +image: Anolis OS 8.6 ANCK 64位 +live_time: 60min +machine: x86_64-2c8g +max_clients: 10 +details: + steps: + start: start.md + - name: 第一步:编写一个内核测试模块 + content: step2.md + - name: 第二步:做好分析vmcore之前的准备工作 + content: step3.md + - name: 第三步:使用crash、gdb工具分析vmcore + content: step4.md + finish: finish.md diff --git "a/anolis-courses/Cloud Kernel \347\263\273\345\210\227\350\257\276\347\250\213/\345\234\250 Anolis \344\270\212\351\200\232\350\277\207vmcore\345\210\206\346\236\220\345\206\205\346\240\270panic\345\216\237\345\233\240/start.md" "b/anolis-courses/Cloud Kernel \347\263\273\345\210\227\350\257\276\347\250\213/\345\234\250 Anolis \344\270\212\351\200\232\350\277\207vmcore\345\210\206\346\236\220\345\206\205\346\240\270panic\345\216\237\345\233\240/start.md" new file mode 100644 index 0000000..82e91b2 --- /dev/null +++ "b/anolis-courses/Cloud Kernel \347\263\273\345\210\227\350\257\276\347\250\213/\345\234\250 Anolis \344\270\212\351\200\232\350\277\207vmcore\345\210\206\346\236\220\345\206\205\346\240\270panic\345\216\237\345\233\240/start.md" @@ -0,0 +1,21 @@ +# 本课程将介绍如何通过vmcore分析系统panic原因 + +系统环境:龙蜥操作系统 (Anolis OS), kdump, crash, gdb + +## kdump介绍 +Linux内核发生panic时,kdump服务会生成包含系统RAM信息的内核转储文件vmcore,通过分析vmcore可以得到系统panic的原因 + +## crash介绍 +crash工具可用来分析kdump服务生成的vmcore文件 + +## gdb介绍 +gdb是GNU开源组织发布的Linux下的程序调试工具,使用gdb可以做以下四件事 +1. 启动程序,指定可能影响其行为的任何内容。 +2. 使程序在指定条件下停止。 +3. 当程序停止时,检查发生了什么。 +4. 更改程序中的内容,以便可以尝试纠正一个错误的影响并继续了解另一个错误。 + +## 课程结构 +1. 编写一个内核模块 +2. 将内核模块进行插入 +3. 通过crash和gdb工具分析vmcore和对应模块 \ No newline at end of file diff --git "a/anolis-courses/Cloud Kernel \347\263\273\345\210\227\350\257\276\347\250\213/\345\234\250 Anolis \344\270\212\351\200\232\350\277\207vmcore\345\210\206\346\236\220\345\206\205\346\240\270panic\345\216\237\345\233\240/step2.md" "b/anolis-courses/Cloud Kernel \347\263\273\345\210\227\350\257\276\347\250\213/\345\234\250 Anolis \344\270\212\351\200\232\350\277\207vmcore\345\210\206\346\236\220\345\206\205\346\240\270panic\345\216\237\345\233\240/step2.md" new file mode 100644 index 0000000..ad9716a --- /dev/null +++ "b/anolis-courses/Cloud Kernel \347\263\273\345\210\227\350\257\276\347\250\213/\345\234\250 Anolis \344\270\212\351\200\232\350\277\207vmcore\345\210\206\346\236\220\345\206\205\346\240\270panic\345\216\237\345\233\240/step2.md" @@ -0,0 +1,68 @@ +利用上一节课程介绍的模块编写的方法,首先编写一个内核模块并插入 + +1. 在/root目录下新建工作文件夹test并进入 +[[ mkdir /root/test/ ]] +[[ cd /root/test/ ]] + +2. 在test文件夹内使用vim新建test_module.c文件 +[[ vim test_module.c ]] + +3. 将以下内容复制到test_module.c并保存退出 + +```s +#include +#include +#include +#include + +MODULE_DESCRIPTION("test kernel module"); +MODULE_AUTHOR("Me"); +MODULE_LICENSE("GPL"); + +noinline void panic_func(void) +{ + int *addr = 0x0; + *addr = 0xf; +} +int test_module_init(void) +{ + panic_func(); + return 0; +} +void test_module_exit(void) +{ +} +module_init(test_module_init); +module_exit(test_module_exit); +``` + +这个模块在插入后会触发crash,原因是访问了0地址 + + +4. 编写Makefile文件 +[[ vim Makefile ]] +将以下内容复制到Makefile并保存退出(复制过程可能将tab转换为空格,请保证kbuild和clean的下行make前为tab而不是空格,空格会造成make行被红色长条覆盖) + +```s +obj-m:=test_module.o + +KDIR = /lib/modules/`uname -r`/build + +kbuild: + make -C $(KDIR) M=`pwd` + +clean: + make -C $(KDIR) M=`pwd` clean +``` + +错误的Makefile图示 +![wrong_makefile.png](https://anolis-pub-share.oss-cn-hangzhou.aliyuncs.com/anolis-lab/assets/1670384384376-wrong_makefile.png) + +正确的Makefile图示 +![true_makefile.png](https://anolis-pub-share.oss-cn-hangzhou.aliyuncs.com/anolis-lab/assets/1670384390484-true_makefile.png) + +5. 编译该内核模块并插入,sync用于将已编译的文件写入盘内,防止内核crash后数据没刷到盘 +[[ make && sync ]] +[[ insmod test_module.ko ]] + +6. 输入任意键重新连接 \ No newline at end of file diff --git "a/anolis-courses/Cloud Kernel \347\263\273\345\210\227\350\257\276\347\250\213/\345\234\250 Anolis \344\270\212\351\200\232\350\277\207vmcore\345\210\206\346\236\220\345\206\205\346\240\270panic\345\216\237\345\233\240/step3.md" "b/anolis-courses/Cloud Kernel \347\263\273\345\210\227\350\257\276\347\250\213/\345\234\250 Anolis \344\270\212\351\200\232\350\277\207vmcore\345\210\206\346\236\220\345\206\205\346\240\270panic\345\216\237\345\233\240/step3.md" new file mode 100644 index 0000000..3646dfc --- /dev/null +++ "b/anolis-courses/Cloud Kernel \347\263\273\345\210\227\350\257\276\347\250\213/\345\234\250 Anolis \344\270\212\351\200\232\350\277\207vmcore\345\210\206\346\236\220\345\206\205\346\240\270panic\345\216\237\345\233\240/step3.md" @@ -0,0 +1,17 @@ +为了分析vmcore,需要做好如下准备 + +1. 验证vmcore是否成功生成 +[[ ls /var/crash/127*/ ]] +如果有vmcore文件代表vmcore已经成功生成 + +2. 使能yum debuginfo仓库 +[[ yum install -y yum-utils ]] +[[ yum-config-manager --enable Plus-debuginfo ]] + + +3. 安装内核版本对应的debuginfo +[[ yum install kernel-debuginfo-$(uname -r) -y ]] +rpm包较大,下载安装过程中请耐心等待 + +4. 安装crash和gdb工具 +[[ yum install crash gdb -y ]] \ No newline at end of file diff --git "a/anolis-courses/Cloud Kernel \347\263\273\345\210\227\350\257\276\347\250\213/\345\234\250 Anolis \344\270\212\351\200\232\350\277\207vmcore\345\210\206\346\236\220\345\206\205\346\240\270panic\345\216\237\345\233\240/step4.md" "b/anolis-courses/Cloud Kernel \347\263\273\345\210\227\350\257\276\347\250\213/\345\234\250 Anolis \344\270\212\351\200\232\350\277\207vmcore\345\210\206\346\236\220\345\206\205\346\240\270panic\345\216\237\345\233\240/step4.md" new file mode 100644 index 0000000..2757fc5 --- /dev/null +++ "b/anolis-courses/Cloud Kernel \347\263\273\345\210\227\350\257\276\347\250\213/\345\234\250 Anolis \344\270\212\351\200\232\350\277\207vmcore\345\210\206\346\236\220\345\206\205\346\240\270panic\345\216\237\345\233\240/step4.md" @@ -0,0 +1,35 @@ +接下来开始分析vmcore + +1. 进入vmcore所在目录 +[[ cd /var/crash/127* ]] + +2. 使用crash工具分析vmcore +[[ crash /usr/lib/debug/lib/modules/$(uname -r)/vmlinux vmcore ]] + +3. 进入crash工具,输入log查看发生panic时的log信息 +[[ log ]] +在log信息中使用 [[ /RIP ]] 搜索 RIP 相关信息,如下图所示 +![RIP.png](https://anolis-pub-share.oss-cn-hangzhou.aliyuncs.com/anolis-lab/assets/1670384435185-RIP.png) + +```s +[ 1408.535985] RIP: 0010:panic_func+0x5/0x20 [test_module] +``` +代表panic发生在panic_func的0x5地址 + +4. 按q退出log信息,并输入exit退出crash +[[ exit ]] + +5. 使用gdb工具对test_module.ko进行反汇编 +[[ gdb /root/test/test_module.ko ]] + +6. 通过disas命令打印panic_func函数的汇编指令 +[[ disas /s panic_func ]] +观察如下信息: +```s +12 int *addr = 0x0; +13 *addr = 0xf; + 0x0000000000000045 <+5>: movl $0xf,0x0 +``` +可以发现在panic_func的+5地址,将0xf赋给*addr,也就是访问了0地址,造成内核panic + +7. 内核panic原因已查明,按ctrl+d退出gdb \ No newline at end of file -- Gitee