1.. SPDX-License-Identifier: GPL-2.0+ 2.. Copyright (c) 2020 Heinrich Schuchardt 3 4Analyzing crash dumps 5===================== 6 7When the CPU detects an instruction that it cannot execute it raises an 8interrupt. U-Boot then writes a crash dump. This chapter describes how such 9dump can be analyzed. 10 11Creating a crash dump voluntarily 12--------------------------------- 13 14For describing the analysis of a crash dump we need an example. U-Boot comes 15with a command 'exception' that comes in handy here. The command is enabled 16by:: 17 18 CONFIG_CMD_EXCEPTION=y 19 20The example output below was recorded when running qemu\_arm64\_defconfig on 21QEMU:: 22 23 => exception undefined 24 "Synchronous Abort" handler, esr 0x02000000 25 elr: 00000000000101fc lr : 00000000000214ec (reloc) 26 elr: 000000007ff291fc lr : 000000007ff3a4ec 27 x0 : 000000007ffbd7f8 x1 : 0000000000000000 28 x2 : 0000000000000001 x3 : 000000007eedce18 29 x4 : 000000007ff291fc x5 : 000000007eedce50 30 x6 : 0000000000000064 x7 : 000000007eedce10 31 x8 : 0000000000000000 x9 : 0000000000000004 32 x10: 6db6db6db6db6db7 x11: 000000000000000d 33 x12: 0000000000000006 x13: 000000000001869f 34 x14: 000000007edd7dc0 x15: 0000000000000002 35 x16: 000000007ff291fc x17: 0000000000000000 36 x18: 000000007eed8dc0 x19: 0000000000000000 37 x20: 000000007ffbd7f8 x21: 0000000000000000 38 x22: 000000007eedce10 x23: 0000000000000002 39 x24: 000000007ffd4c80 x25: 0000000000000000 40 x26: 0000000000000000 x27: 0000000000000000 41 x28: 000000007eedce70 x29: 000000007edd7b40 42 43 Code: b00003c0 912ad000 940029d6 17ffff52 (e7f7defb) 44 Resetting CPU ... 45 46 resetting ... 47 48The first line provides us with the type of interrupt that occurred. 49On ARMv8 a synchronous abort is an exception thrown when hitting an unallocated 50instruction. The exception syndrome register ESR register contains information 51describing the reason for the exception. Bit 25 set here indicates that a 32 bit 52instruction led to the exception. 53 54The second line provides the contents of the elr and the lr register after 55subtracting the relocation offset. - U-Boot relocates itself after being 56loaded. - The relocation offset can also be displayed using the bdinfo command. 57 58After the contents of the registers we get a line indicating the machine 59code of the instructions preceding the crash and in parentheses the instruction 60leading to the dump. 61 62Analyzing the code location 63--------------------------- 64 65We can convert the instructions in the line starting with 'Code:' into mnemonics 66using the objdump command. To make things easier scripts/decodecode is 67supplied:: 68 69 $echo 'Code: b00003c0 912ad000 940029d6 17ffff52 (e7f7defb)' | \ 70 CROSS_COMPILE=aarch64-linux-gnu- ARCH=arm64 scripts/decodecode 71 Code: b00003c0 912ad000 940029d6 17ffff52 (e7f7defb) 72 All code 73 ======== 74 0: b00003c0 adrp x0, 0x79000 75 4: 912ad000 add x0, x0, #0xab4 76 8: 940029d6 bl 0xa760 77 c: 17ffff52 b 0xfffffffffffffd54 78 10:* e7f7defb .inst 0xe7f7defb ; undefined <-- trapping instruction 79 80 Code starting with the faulting instruction 81 =========================================== 82 0: e7f7defb .inst 0xe7f7defb ; undefined 83 84Now lets use the locations provided by the elr and lr registers after 85subtracting the relocation offset to find out where in the code the crash 86occurred and from where it was invoked. 87 88File u-boot.map contains the memory layout of the U-Boot binary. Here we find 89these lines:: 90 91 .text.do_undefined 92 0x00000000000101fc 0xc cmd/built-in.o 93 .text.exception_complete 94 0x0000000000010208 0x90 cmd/built-in.o 95 ... 96 .text.cmd_process 97 0x00000000000213b8 0x164 common/built-in.o 98 0x00000000000213b8 cmd_process 99 .text.cmd_process_error 100 0x000000000002151c 0x40 common/built-in.o 101 0x000000000002151c cmd_process_error 102 103So the error occurred at the start of function do\_undefined() and this 104function was invoked from somewhere inside function cmd\_process(). 105 106If we want to dive deeper, we can disassemble the U-Boot binary:: 107 108 $ aarch64-linux-gnu-objdump -S -D u-boot | less 109 110 00000000000101fc <do_undefined>: 111 { 112 /* 113 * 0xe7f...f. is undefined in ARM mode 114 * 0xde.. is undefined in Thumb mode 115 */ 116 asm volatile (".word 0xe7f7defb\n"); 117 101fc: e7f7defb .inst 0xe7f7defb ; undefined 118 return CMD_RET_FAILURE; 119 } 120 10200: 52800020 mov w0, #0x1 // #1 121 10204: d65f03c0 ret 122 123This example is based on the ARMv8 architecture but the same procedures can be 124used on other architectures as well. 125