【开发工具】【JTAG】系统崩溃后如何使用JTAG排查?【四】

285 阅读7分钟

相关链接:

JTAG基础

JTAG调试原理

JTAG调试实例

模拟系统崩溃,使用JTAG调试找到崩溃点

模拟系统崩溃,使用JTAG调试找到崩溃点

既然都知道怎么使用JTAG了,那就实战练练手吧~

内核添加sysrq模块

编译内核(添加sysrq功能)

make menuconfig 添加“MAGIC_SYSRQ”配置项后,执行make编译内核镜像。

​编辑

运行内核(使用sysrq触发模拟系统panic)

  1. 关闭看门狗(防止系统重启,模拟一个系统异常卡死的环境)

devmem 0x4804c194 32 0x40000000

注:根据自己实际板卡,设置关闭看门狗

  1. 通过sysrq触发系统异常(echo "c" > /proc/sysrq-trigger表示产生空指针panic事件,人为导致系统崩溃)

关于sysrq的详细信息,参考:文档:Linux_Sysrq魔术键使用.note

note.youdao.com/noteshare?i…

~ # echo "c" > /proc/sysrq-trigger 

SysRq : Trigger a crash
Unable to handle kernel NULL pointer dereference at virtual address 00000000
pgd = 8fbe0000
[00000000] *pgd=8fbe8031, *pte=00000000, *ppte=00000000
Internal error: Oops: 817 [#1]
last sysfs file: /sys/devices/platform/omap/omap_i2c.1/i2c-1/1-0048/temp1_input
Modules linked in: pppoe pppox ppp_synctty ppp_generic slhc
CPU: 0    Not tainted  (2.6.37-g7c4b7a14-dirty #1)
PC is at sysrq_handle_crash+0x24/0x30
LR is at __handle_sysrq+0xb4/0x180
pc : [<802660d4>]    lr : [<802663d4>]    psr: 20000093
sp : 8f247f08  ip : 8f247f18  fp : 8f247f14
r10: 60000013  r9 : 00000008  r8 : 00000000
r7 : 805d35a0  r6 : 00000063  r5 : 805ead74  r4 : 805eac74
r3 : 00000000  r2 : 00000001  r1 : 60000093  r0 : 00000063
Flags: nzCv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment user
Control: 10c5387d  Table: 8fbe0019  DAC: 00000015
Process sh (pid: 125, stack limit = 0x8f2462e8)
Stack: (0x8f247f08 to 0x8f248000)
7f00:                   8f247f44 8f247f18 802663d4 802660bc 8f247f78 00000002
7f20: 802664a0 001f1e68 8f247f78 8004f808 8f246000 00000000 8f247f5c 8f247f48
7f40: 802664d8 8026632c 8fa94380 802664a0 8f247f74 8f247f60 801527f8 802664ac
7f60: 00000002 8f27b880 8f247fa4 8f247f78 80102694 801527bc 00000000 00000000
7f80: 800ffc94 00000000 00000002 001f1e68 00000001 00000004 00000000 8f247fa8
7fa0: 8004f660 8010259c 00000002 001f1e68 00000001 001f1e68 00000002 001ee328
7fc0: 00000002 001f1e68 00000001 00000004 00000000 00000002 00000001 00000000
7fe0: 001ef4c0 7efed8b0 0000c128 00008e0c 60000010 00000001 ffffffff ffffffff
Backtrace: 
[<802660b0>] (sysrq_handle_crash+0x0/0x30) from [<802663d4>] (__handle_sysrq+0xb4/0x180)
[<80266320>] (__handle_sysrq+0x0/0x180) from [<802664d8>] (write_sysrq_trigger+0x38/0x40)
[<802664a0>] (write_sysrq_trigger+0x0/0x40) from [<801527f8>] (proc_reg_write+0x48/0x90)
 r5:802664a0 r4:8fa94380
[<801527b0>] (proc_reg_write+0x0/0x90) from [<80102694>] (sys_write+0x104/0x140)
 r5:8f27b880 r4:00000002
[<80102590>] (sys_write+0x0/0x140) from [<8004f660>] (ret_fast_syscall+0x0/0x30)
 r7:00000004 r6:00000001 r5:001f1e68 r4:00000002
Code: e3a02001 e5832000 f57ff04f e3a03000 (e5c32000) 
---[ end trace 08fa18d2ec21349a ]---
Kernel panic - not syncing: Fatal exception
Backtrace: 
[<80053e50>] (dump_backtrace+0x0/0x130) from [<8049325c>] (dump_stack+0x18/0x1c)
 r7:802660d4 r6:00000000 r5:8f247cf7 r4:80600490
[<80493244>] (dump_stack+0x0/0x1c) from [<804932d4>] (panic+0x74/0x1b0)
[<80493260>] (panic+0x0/0x1b0) from [<800542f8>] (die+0x378/0x4c0)
 r3:806008cc r2:00000001 r1:000045b7 r0:80540dfc
[<80053f80>] (die+0x0/0x4c0) from [<8005787c>] (__do_kernel_fault+0x7c/0x90)
[<80057800>] (__do_kernel_fault+0x0/0x90) from [<80498b84>] (do_page_fault+0x94/0x260)
 r9:00000817 r8:8f227334 r7:00000000 r6:8f227300 r5:8f247ec0
r4:00010000
[<80498af0>] (do_page_fault+0x0/0x260) from [<8003f2ec>] (do_DataAbort+0x3c/0xa0)
[<8003f2b0>] (do_DataAbort+0x0/0xa0) from [<80496a2c>] (__dabt_svc+0x4c/0x60)
Exception stack(0x8f247ec0 to 0x8f247f08)
7ec0: 00000063 60000093 00000001 00000000 805eac74 805ead74 00000063 805d35a0
7ee0: 00000000 00000008 60000013 8f247f14 8f247f18 8f247f08 802663d4 802660d4
7f00: 20000093 ffffffff
[<802660b0>] (sysrq_handle_crash+0x0/0x30) from [<802663d4>] (__handle_sysrq+0xb4/0x180)
[<80266320>] (__handle_sysrq+0x0/0x180) from [<802664d8>] (write_sysrq_trigger+0x38/0x40)
[<802664a0>] (write_sysrq_trigger+0x0/0x40) from [<801527f8>] (proc_reg_write+0x48/0x90)
 r5:802664a0 r4:8fa94380
[<801527b0>] (proc_reg_write+0x0/0x90) from [<80102694>] (sys_write+0x104/0x140)
 r5:8f27b880 r4:00000002
[<80102590>] (sys_write+0x0/0x140) from [<8004f660>] (ret_fast_syscall+0x0/0x30)
 r7:00000004 r6:00000001 r5:001f1e68 r4:00000002

通过上面的异常崩溃打印,可以看到系统最终是在sysrq_handle_crash上停住了,对应的PC、LR地址都打印出来了。

那么,通过JTAG调试,最后获取到的PC、LR、R0~R15上的值,和上面的打印会一样吗?

使用JTAG调试(获取PC、LR寄存器对应地址)

通过之前描述的JTAG调试,获取到的PC、LR值分别为(0x801ff280、0x80493350)

和系统崩溃时打印出来的堆栈信息不一样,这是为什么呢?(后面会解释)

​编辑

接着继续解析PC、LR上的地址分别代表什么含义。

反汇编内核镜像(获取每一行地址对应运行的函数)

在Linux下反汇编内核镜像(vmlinux),得到对应的反汇编文件。

反汇编相关的知识参考文档:objdump -- 反汇编uboot、uImage、vmli...

有道云笔记

输入如下命令得到反汇编文件vmlinux.txt:

objdump -DS vmlinux > vmlinux.txt

将JTAG调试获取的PC、LR寄存器对应地址,在vmlinux反汇编文件中找到对应函数。

解析

通过JTAG获取到PC、LR等指针;

通过反汇编获取到这些指针地址对应的函数;

最后分析代码的执行流程。