-
-
[原创][原创]在调试器下看Panic机制及oops信息分析
-
2021-7-26 17:42 5108
-
穷理者,因其所已知而及其所未知,因其所已达而及其所未达。人之良知,本所固有。然不能穷理者,只是足于已知已达,而不能穷其未知未达,故见得一截,又不曾见得一截,此其所以于理未精也。然仍须功夫日日增加。今日既格得一物,明日又格得一物,工夫更不住地做。如左脚进得一步,右脚又进一步;右脚进得一步,左脚又进,接续不已,自然贯通。
借钟馗与GDK7之合力捉”鬼“,保佑代码平安顺利、风调雨顺,再无”鬼怪出现“。
oops
当你见到oops这个单词时,第一时间想到的或许就是“哎呦*****“;同样的当你在Linux内核中碰到oops时,你也会第一时间说出“哎呦*****”,因为此时你很清楚的明白Linux内核陷入到了一场不算小的意外当中。
Linux内核发生异常后会输出的oops信息(异常相关的信息),oops信息可以辅助我们进行调试,从而找出导致Linux内核出现异常的问题所在。
oops信息内没有源代码信息,因为oops信息的产生不依赖dwarf符号,所以不能产生源代码信息。
oops-tracing.txt:介绍oops信息的格式;oops-tracing.txt可以在内核源代码文件夹中的Documentation文件夹内找到,如图下图所示。
Panic机制与oops的关系
Linux内核碰到某些不严重的oops后,内核仍然可以正常运行,但是如果Linux内核碰到一些比较严重的oops后,内核将无法继续运行,同时Linux内核会进入Panic机制,而Panic机制会使系统重启。
Panic机制的关系与oops的关系如下图所示。
调试Panic
1号CPU的状况
将附件中的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正在执行,如下图所示。
查看栈回溯,如下图所示。
Child-SP RetAddr Call Site ffffac05`c28efb78 ffffffff`9b8337ba lk!panic+0x28 [/build/linux-hwe-zHO4ZF/linux-hwe-5.0.0/kernel/panic.c @ 162] ffffac05`c28efb78 00000000`00000880 lk!oops_end+0xda [/build/linux-hwe-zHO4ZF/linux-hwe-5.0.0/arch/x86/kernel/dumpstack.c @ 354]
0、2及3号CPU的状况(重启前)
在0号CPU下查看栈回溯(如下图所示);很可惜并没有捕捉到相应的栈回溯,显然不是0号CPU在执行llaolao。
切换到2号CPU下查看栈回溯(如下图所示);如0号CPU一样并没有捕捉到相应的栈回溯,显然不是2号CPU在执行llaolao。
切换到3号CPU下查看栈回溯(如下图所示);当切换到3号CPU之后会自动弹出common.c,同时查看栈回溯,不难看出此时3号CPU正在执行系统调用,因此自然也就不是3号CPU在执行llaolao。
oops信息分析
第1部分:概要介绍
[ 192.174205] reboot: Restarting system [ 0.000000] tsc: Fast TSC calibration failed [ 0.878127] BUG: unable to handle kernel NULL pointer dereference at 00000008 [ 0.881181] IP: [<c155b954>] kallsym_init+0x134/0x260 [ 0.882117] *pdpt = 0000000000000000 *pde = f000ff53f000ff53 [ 0.883045] Oops: 0000 [#1] SMP [ 0.885233] Modules linked in: [ 0.885703] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 3.11.0gedu #9 [ 0.890017] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006 [ 0.894979] task: df480000 ti: df44a000 task.ti: df44a000 [ 0.898298] EIP: 0060:[<c155b954>] EFLAGS: 00010246 CPU: 0 [ 0.903263] EIP is at kallsym_init+0x134/0x260 [ 0.909127] EAX: 00000000 EBX: c17f6ab8 ECX: 00000009 EDX: 00000000 [ 0.911950] ESI: c17f626c EDI: c17f672c EBP: df44beac ESP: df44be90 [ 0.916195] DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068 [ 0.916973] CR0: 8005003b CR2: 00000008 CR3: 01a62000 CR4: 000406f0 [ 0.917816] DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000 [ 0.920026] DR6: fffe0ff0 DR7: 00000400
行1:代表在192.174205秒时,重启系统。
行2:日志信息;快速tsc校准失败。
//tsc是一种高精度的cpu时钟
行3:Bug信息;不能访问空指针,空指针的地址为00000008。
//空指针不可以访问;0及小于一定数值的地址都是是空指针;故00000008也是空指针。
行4:IP信息;显示做非法访问的函数的所在位置信息。
行5:页表信息。
行6:oops信息;SMP-对称多处理。
行7-8:模块信息;显示做非法访问的函数的所在模块及进程的相关信息。
行9:硬件信息。
行10:task指针的地址信息。
行11:显示做非法访问的函数的所在位置信息(与IP信息内的内容一致)及寄存器信息。
行12:显示符号信息(由做非法访问的函数的所在位置信息翻译得到)。
行13-18:寄存器信息;特别注意CR2,因为CR2存有CPU访问错误地址时的地址信息。
//如果启用调试选项输出CR2,CR2的数值可能改变。
第2部分:重要的栈回溯
CPU想要运行一定要有栈空间,而栈空间里则会记录函数返回地址信息(线程的执行轨迹)、参数信息及局部变量信息等内容。
输出oops信息时,内核会自动寻找栈空间内的函数返回地址信息,并会尝试翻译地址信息为函数名。
函数名前的问号代表内核无法不能确定此函数是否执行过,需要进一步的分析;代码如下所示。
void printk_address(unsigned long address, int reliable) { pr_cont(" [<%p>] %s%pB\n", (void *)address, reliable ? "" : "? ", (void *)address); }
[ 0.924014] Stack: [ 0.926206] c18655ce 00012fa6 c16c22d8 c170e174 00000000 00000105 c1a39cd4df44bef8 [ 0.929478] c19ceb1e c1864976 00000060 000080d0 00000301 de3a15a0 de3a15a000000000 [ 0.935932] df44bee8 c13fd5bb c1b3b23c 00000000 00000105 c1a39cd0 df44bef0c1551769 [ 0.940598] Call Trace: [ 0.945476] [<c19ceb1e>] fedcore_init+0x15/0x350 [ 0.946233] [<c13fd5bb>] ? __class_create+0x4b/0x70 [ 0.946993] [<c1551769>] ? create_extcon_class.part.2+0x19/0x30 [ 0.949370] [<c19ceb07>] ? extcon_class_init+0x13/0x15 [ 0.950123] [<c10020fc>] do_one_initcall+0xdc/0x1b0 [ 0.956222] [<c11c5583>] ? __proc_create+0xa3/0xe0 [ 0.956953] [<c19ceb09>] ? extcon_class_init+0x15/0x15 [ 0.957707] [<c1071243>] ? parse_args+0x283/0x480 [ 0.960365] [<c197dbe3>] kernel_init_freeable+0x11c/0x1b9 [ 0.961339] [<c197d514>] ? do_early_param+0x74/0x74 [ 0.962062] [<c1638eb0>] kernel_init+0x10/0xd0 [ 0.963534] [<c164f0f7>] ret_from_kernel_thread+0x1b/0x28 [ 0.967251] [<c1638ea0>] ? rest_init+0x70/0x70
第3部分:汇编指令
显示出问题的汇编指令附件的机器码信息;根据出问题的指针地址信息得到。。
<a1>:尖括号代表出问题的指针地址的机器码信息。
[ 0.969798] Code: be 03 e8 10 f6 ff ff 85 c0 74 14 83 c3 01 0f be 03 e8 01 f6 ff ff 85 c0 75 f1 83 c3 01 eb e0 89 d8 83 e0 03 74 05 29 c3 83 c3 04 <a1> 08 00 00 00 89 1d 3c e5 b4 c1 89 5c 24 0c 31 db 89 7c 24 08 [ 0.984078] EIP: [<c155b954>] kallsym_init+0x134/0x260 SS:ESP 0068:df44be90 [ 0.987013] CR2: 0000000000000008
第4部分:结束标志
oops信息的结束标志如下所示。
[ 0.988500] ---[ end trace 27c8b114d5190fc5 ]--- [ 0.989411] ata2.00: ATAPI: VBOX CD-ROM, 1.0, max UDMA/133 [ 0.990510] ata2.00: configured for UDMA/33 [ 0.992419] Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000009 [ 0.992419] [ 0.999444] atkbd serio0: Spurious ACK on isa0060/serio0. Some program might be trying to access hardware directly.
GDK7的介绍
GDK7通过专用调试电缆与调试目标进行连接,二者通过DCI协议进行通信,也不需要专用的ITP硬件就可以实现JTAG调试和系统追踪。
GDK7提供了一个完整的被调试目标系统,大大减少准备调试环境所需的时间,省去各种因为软件和硬件不兼容所带来的烦恼。与传统的ITP/XDP硬件调试器相比,GDK7的传输速度高达5Gbps,比XDP和ITP提高了10倍还多;可以把GDK7中的数据实时传输到调试主机内,让全量分析多线程软件的执行轨迹成为可能,当然GDK7的强大功能不局限于此。
其他说明
若您有问题咨询及出现链接失效等其他情况请联系邮箱:birdring_NULL@outlook.com。
[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法