123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- .. SPDX-License-Identifier: GPL-2.0+
- .. Copyright (c) 2020 Heinrich Schuchardt
- Analyzing crash dumps
- =====================
- When the CPU detects an instruction that it cannot execute it raises an
- interrupt. U-Boot than writes a crash dump. This chapter describes how such
- dump can be analyzed.
- Creating a crash dump voluntarily
- ---------------------------------
- For describing the analysis of a crash dump we need an example. U-Boot comes
- with a command 'exception' that comes in handy here. The command is enabled
- by::
- CONFIG_CMD_EXCEPTION=y
- The example output below was recorded when running qemu\_arm64\_defconfig on
- QEMU::
- => exception undefined
- "Synchronous Abort" handler, esr 0x02000000
- elr: 00000000000101fc lr : 00000000000214ec (reloc)
- elr: 000000007ff291fc lr : 000000007ff3a4ec
- x0 : 000000007ffbd7f8 x1 : 0000000000000000
- x2 : 0000000000000001 x3 : 000000007eedce18
- x4 : 000000007ff291fc x5 : 000000007eedce50
- x6 : 0000000000000064 x7 : 000000007eedce10
- x8 : 0000000000000000 x9 : 0000000000000004
- x10: 6db6db6db6db6db7 x11: 000000000000000d
- x12: 0000000000000006 x13: 000000000001869f
- x14: 000000007edd7dc0 x15: 0000000000000002
- x16: 000000007ff291fc x17: 0000000000000000
- x18: 000000007eed8dc0 x19: 0000000000000000
- x20: 000000007ffbd7f8 x21: 0000000000000000
- x22: 000000007eedce10 x23: 0000000000000002
- x24: 000000007ffd4c80 x25: 0000000000000000
- x26: 0000000000000000 x27: 0000000000000000
- x28: 000000007eedce70 x29: 000000007edd7b40
- Code: b00003c0 912ad000 940029d6 17ffff52 (e7f7defb)
- Resetting CPU ...
- resetting ...
- The first line provides us with the type of interrupt that occurred.
- (On ARMv8 a synchronous abort is an exception where the return address stored
- in the ESR register indicates the instruction that caused the exception.)
- The second line provides the contents of the elr and the lr register after
- subtracting the relocation offset. - U-Boot relocates itself after being
- loaded. - The relocation offset can also be displayed using the bdinfo command.
- After the contents of the registers we get a line indicating the machine
- code of the instructions preceding the crash and in parentheses the instruction
- leading to the dump.
- Analyzing the code location
- ---------------------------
- We can convert the instructions in the line starting with 'Code:' into mnemonics
- using the objdump command. To make things easier scripts/decodecode is
- supplied::
- $echo 'Code: b00003c0 912ad000 940029d6 17ffff52 (e7f7defb)' | \
- CROSS_COMPILE=aarch64-linux-gnu- ARCH=arm64 scripts/decodecode
- Code: b00003c0 912ad000 940029d6 17ffff52 (e7f7defb)
- All code
- ========
- 0: b00003c0 adrp x0, 0x79000
- 4: 912ad000 add x0, x0, #0xab4
- 8: 940029d6 bl 0xa760
- c: 17ffff52 b 0xfffffffffffffd54
- 10:* e7f7defb .inst 0xe7f7defb ; undefined <-- trapping instruction
- Code starting with the faulting instruction
- ===========================================
- 0: e7f7defb .inst 0xe7f7defb ; undefined
- Now lets use the locations provided by the elr and lr registers after
- subtracting the relocation offset to find out where in the code the crash
- occurred and from where it was invoked.
- File u-boot.map contains the memory layout of the U-Boot binary. Here we find
- these lines::
- .text.do_undefined
- 0x00000000000101fc 0xc cmd/built-in.o
- .text.exception_complete
- 0x0000000000010208 0x90 cmd/built-in.o
- ...
- .text.cmd_process
- 0x00000000000213b8 0x164 common/built-in.o
- 0x00000000000213b8 cmd_process
- .text.cmd_process_error
- 0x000000000002151c 0x40 common/built-in.o
- 0x000000000002151c cmd_process_error
- So the error occurred at the start of function do\_undefined() and this
- function was invoked from somewhere inside function cmd\_process().
- If we want to dive deeper, we can disassemble the U-Boot binary::
- $ aarch64-linux-gnu-objdump -S -D u-boot | less
- 00000000000101fc <do_undefined>:
- {
- /*
- * 0xe7f...f. is undefined in ARM mode
- * 0xde.. is undefined in Thumb mode
- */
- asm volatile (".word 0xe7f7defb\n");
- 101fc: e7f7defb .inst 0xe7f7defb ; undefined
- return CMD_RET_FAILURE;
- }
- 10200: 52800020 mov w0, #0x1 // #1
- 10204: d65f03c0 ret
- This example is based on the ARMv8 architecture but the same procedures can be
- used on other architectures as well.
|