-
-
[原创][原创]在调试器下看Panic机制及oops信息分析
-
发表于: 2021-7-26 17:42 6075
-
穷理者,因其所已知而及其所未知,因其所已达而及其所未达。人之良知,本所固有。然不能穷理者,只是足于已知已达,而不能穷其未知未达,故见得一截,又不曾见得一截,此其所以于理未精也。然仍须功夫日日增加。今日既格得一物,明日又格得一物,工夫更不住地做。如左脚进得一步,右脚又进一步;右脚进得一步,左脚又进,接续不已,自然贯通。
借钟馗与GDK7之合力捉”鬼“,保佑代码平安顺利、风调雨顺,再无”鬼怪出现“。
当你见到oops这个单词时,第一时间想到的或许就是“哎呦*****“;同样的当你在Linux内核中碰到oops时,你也会第一时间说出“哎呦*****”,因为此时你很清楚的明白Linux内核陷入到了一场不算小的意外当中。
Linux内核发生异常后会输出的oops信息(异常相关的信息),oops信息可以辅助我们进行调试,从而找出导致Linux内核出现异常的问题所在。
oops信息内没有源代码信息,因为oops信息的产生不依赖dwarf符号,所以不能产生源代码信息。
oops-tracing.txt:介绍oops信息的格式;oops-tracing.txt可以在内核源代码文件夹中的Documentation文件夹内找到,如图下图所示。
Linux内核碰到某些不严重的oops后,内核仍然可以正常运行,但是如果Linux内核碰到一些比较严重的oops后,内核将无法继续运行,同时Linux内核会进入Panic机制,而Panic机制会使系统重启。
Panic机制的关系与oops的关系如下图所示。
将附件中的llaolao.zip复制到GDK7当中,并解压文件(具体位置无要求);进入解压得到的llaolao文件夹(cd /......),然后编译模块(make)。
//llaolao模块:模拟内核态栈溢出,无限递归。
将GDK7中llaolao.ko复制到调试主机(与vmlinux处于同一文件夹下),通过Nano Code将GDK7断下来,并加载符号文件(.sympath ......)及源代码文件(.srcpath ......);然后手动加载一下llaolao模块,输入.reload,并查看llaolao模块是否存在;让GDK7重新跑起来。
在GDK7端进入管理员模式(sudo su),在命令行内输入echo 200 > /sys/kernel/debug/llaolao/age,如果发现光标停在下一行不动(如果等待一段时间,会发现GDK7越来越不正常,异常卡顿直到最后直接动不了了)则代表执行成功,并且LInux内核进入到Panic机制当中。
在Nano Code中断GDK7(此时为0号CPU)。
切换到1号CPU下查看栈回溯(如下图所示);但切换到1号CPU之后printk.c会自动打开(猜测一下,就是1号CPU在执行llaolao吗?);继续查看栈回溯,此时我们可以很清楚的知道llaolao在无限递归的过程中不断调用printk,使Linux内核陷入到了Panic机制当中。
//切换CPU:~Xs;X为CPU的号数,如果是2号CPU,则X=2。
由于等待内核栈空间耗完的时间过长,因此我将GDK7重启,并选择使用触发空指针的形式来使Linux内核陷入Panic机制。
重启后,断下GDK7并加载符号及源代码;给panic函数设置断点(bp);恢复GDK7。
在GDK7端的命令行内输入在GDK7端进入管理员模式(sudo su),在命令行内输入echo nullp > /proc/llaolao;如果输入后没有任何输出,则按下方步骤设置内核选项后再重新输入echo nullp > /proc/llaolao。
//1.gedu@gdk:/proc/sys/kernel$ sudo su
//2.root@gdk:/proc/sys/kernel# echo 1 > panic_on_oops
如果echo nullp > /proc/llaolao命令执行成功,则此时GDK7端会立刻卡死,转头看看Nano Code,果不其然断点命中,panic.c自动打开,此时是0号CPU正在执行,如下图所示。
查看栈回溯,如下图所示。
在0号CPU下查看栈回溯(如下图所示);很可惜并没有捕捉到相应的栈回溯,显然不是0号CPU在执行llaolao。
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!