crash_dumps.rst 4.7 KB

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