[PATCH v2 0/7] arm64: stack backtraces

Heinrich Schuchardt xypron.glpk at gmx.de
Tue Jul 29 17:34:09 CEST 2025


On 29.07.25 14:34, Casey Connolly wrote:
> 
> 
> On 7/25/25 17:23, Heinrich Schuchardt wrote:
>> On 25.07.25 14:57, Casey Connolly wrote:
>>> Implement support for printing stack backtraces on ARM64, make
>>> framepointer support configurable by the build system with
>>> CONFIG_FRAMEPOINTER and teach U-Boot to walk the framepointers and
>>> unwind the stack when an exception occurs. Also show all 64 bits of the
>>> exception syndrom register (ESR).
>>>
>>> Additionally, a new global unwind_stack() function is added, this can
>>> be called from anywhere to print a backtrace which can be useful when
>>> debugging certain problems.
>>>
>>> In the future, stack unwinding with symbol support could be extended
>>> to for example only emit log messages when a function is called in a
>>> specific code path. This would allow for less noise when debugging hot
>>> paths under certain conditions, but this feature is left as future work.
>>>
>>> === Handling relocation ===
>>>
>>> Since U-Boot relocates itself at runtime, and can be built to be
>>> position independent in the first place (effectively "relocating" itself
>>> when it first starts too), we can't really rely on gd->reloc_off.
>>>
>>> The approach taken here is to subtract CONFIG_TEXT_BASE from the address
>>> of each symbol in the lookup table (while it's being generated), then
>>> when decoding we just subtract the address of the _start label since it
>>> is always correct pre and post relocation. This allows us to avoid all
>>> the awkward maths since the symbols are always relative to 0x0 in the
>>> lookup table.
>>>
>>> Example output:
>>>
>>> "Synchronous Abort" handler, esr 0x0000000096000004, far 0xfffffffffffff
>>> elr: 000000009fc6f768 lr : 000000009fc6f710 (reloc)
>>> elr: 00000001ffe49768 lr : 00000001ffe49710
>>> x0 : 000fffffffffffff x1 : 0000000000000009
>>> x2 : 00000001efdbadd0 x3 : 0000000000000000
>>> x4 : 00000001efd99a28 x5 : 00000001ffec7676
>>> x6 : 00000001efdbac70 x7 : 0000000000000000
>>> x8 : 0000000000000002 x9 : 0000000000000034
>>> x10: 000000000000000d x11: 0000000000000006
>>> x12: 0000000000001000 x13: 00000000c3400000
>>> x14: 00000000fffffff8 x15: 00000001efd99837
>>> x16: 00000001ffe146b8 x17: 0000000000000000
>>> x18: 00000001efdbac70 x19: 000000000a6f8800
>>> x20: 00000001efe06fd0 x21: 0000000000000001
>>> x22: 00000001ffef5b80 x23: 00000001ffee08c0
>>> x24: 0000000000000002 x25: 0000000000000000
>>> x26: 0000000000000000 x27: 0000000000000000
>>> x28: 00000001efe512c0 x29: 00000001efd99c80
>>>
>>> Code: 2a010000 b9001260 d5033fbf 92fffe00 (39400001)
>>>
>>> CONFIG_TEXT_BASE   : 0x9fc00000
>>> Relocated base addr: 0x1ffdda000
>>> Backtrace:
>>>     <0x000001ffe496d0> dwc3_qcom_glue_configure+0x40
>>>     <0x000001ffe494a4> dwc3_glue_probe+0x10c
>>>     <0x000001ffe1757c> device_probe+0x254
>>>     <0x000001ffe1757c> device_probe+0x114
>>>     <0x000001ffe4ff70> usb_init+0x158
>>>     <0x000001ffe00fe4> do_usb_start+0xc
>>>     <0x000001ffe01018> do_usb+0x78
>>>     <0x000001ffe0dec4> cmd_process+0x140
>>>     <0x000001ffe04e24> run_list_real+0x6f0
>>>     <0x000001ffe05554> parse_stream_outer+0x148
>>>     <0x000001ffe04d30> parse_string_outer+0x90
>>>     <0x000001ffe0d148> run_command_list+0x50
>>>     <0x000001ffe02be0> main_loop+0x28
>>>     <0x000001ffe065c0> board_init_r+0x3c8
>>>     <0x000001ffddd00c> relocation_return+0x4
>>>
>>> Resetting CPU ...
>>
>> Thank you Casey for picking this up.
>>
>> It working fine but there are some points to think about:
> 
> Thanks for taking a look!
> 
>>
>> It would make sense to show both the relocated and the non-relocated 
>> addresses like we do for elr and lr. The value after subtracting the 
>> relocation address is what I need when looking at the objdump.
> 
> OK, I can see why that would be useful, I'll give it a whirl.
> 
>>
>> The format of addresses with and without symbols does not match:
>>
>> Backtrace:
>>          <0x0000007f6ba868> cmd_process+0x130
>>          <0x0000007f6af900> run_list_real+0x718
>>          <0x0000007f6b0058> parse_stream_outer+0x14c
>>          <0x0000007f6b06b4> parse_file_outer+0x34
>>          <0x0000007f6b9dfc> cli_loop+0x18
>>          <0x0000007f6ad6b0> main_loop+0x50
>>          <0x0000007f6b0f94> board_init_r+0x378
>>          <0x0000007f68400c> relocation_return+0x4
>>
>> Backtrace:
>>          (0x0000007f6d394c)
>>          (0x0000007f6c8fcc)
>>          (0x0000007f6c9158)
>>          (0x0000007f6c969c)
>>          (0x0000007f6d2dc8)
>>          (0x0000007f6c66b4)
>>          (0x0000007f6ca2c0)
>>          (0x0000007f69d010)
>>
>> I don't think parentheses are needed. But if we use them they should 
>> look the same for the same content.
> 
> I was trying to differentiate between the addresses being symbol 
> addresses vs lr addresses, but yeah maybe the different parentheses 
> doesn't add much here. I used the <> to follow the kernel style.
> 
>>
>> I guess symbol lookup could be used in other places in future. I don't 
>> see a necessity to let it depend on frame-pointers. Instead frame- 
>> pointers should imply symbol-lookup. 'imply' should also work on RISC- 
>> V where symbol-lookup is still missing.
> 
> Makes sense to me.
> 
>>
>> There should be at least one defconfig for 32-bit and one defconfig 
>> for 64-bit that builds with both.
> 
> Hmm, well I'll enable it in qcom_defconfig for sure, I don't have any 
> 32-bit boards to test though, can you help with this?

QEMU is good enough for ensure compilation and manually testing using 
the exception instruction or lib/efi_selftest/efi_selftest_exception.

I did not test your code with a crash in an EFI application yet.

Best regards

Heinrich

> 
>>
>> I am missing the function name and offset for the function where the 
>> exception actually occurred. Could we treat the value of elr like a 
>> framepointer and add it as first line?
> 
> Oh yeah, I messed this up actually we should pass elr in except_msg(), 
> I'll fix that.
> 
> Kind regards,
> // Casey (she/her)
> 
>>
>> Best regards
>>
>> Heinrich
>>
>>>
>>> ---
>>> Changes in v2:
>>> - Include calling function in backtrace (current LR)
>>> - Implement support for runtime symbol lookup
>>> - Use symbol lookup to print more informative backtraces when available
>>> - Adjust backtrace format and print U-Boot base address
>>> - Link to v1: https://lore.kernel.org/u-boot/20250703051951.43372-1- 
>>> heinrich.schuchardt at canonical.com
>>>
>>> To: Tom Rini <trini at konsulko.com>
>>> To: Heinrich Schuchardt <heinrich.schuchardt at canonical.com>
>>> Cc: Simon Glass <sjg at chromium.org>
>>> Cc: Marek Vasut <marek.vasut+renesas at mailbox.org>
>>> Cc: Ben Dooks <ben.dooks at codethink.co.uk>
>>> Cc: Rick Chen <rick at andestech.com>
>>> Cc: Leo <ycliang at andestech.com>
>>> Cc: Ilias Apalodimas <ilias.apalodimas at linaro.org>
>>> Cc: u-boot at lists.denx.de
>>>
>>> ---
>>> Casey Connolly (3):
>>>        drop unused kallsyms support
>>>        add support for symbol lookups
>>>        arm64: implement printing backtraces with symbols
>>>
>>> Heinrich Schuchardt (4):
>>>        cmd/exception: missing include string.h
>>>        Kconfig: make CONFIG_FRAMEPOINTER available on arm64
>>>        arm64: initialize the frame pointer register
>>>        arm64: simplify interrupt code
>>>
>>>   Kconfig                      |  25 ++
>>>   Makefile                     |  24 +-
>>>   arch/arm/Makefile            |   9 +-
>>>   arch/arm/lib/crt0_64.S       |   1 +
>>>   arch/arm/lib/interrupts_64.c | 133 ++++++---
>>>   arch/riscv/Kconfig           |  21 --
>>>   common/Makefile              |   1 -
>>>   common/kallsyms.c            |  42 ---
>>>   common/system_map.c          |   8 -
>>>   include/exception.h          |   1 +
>>>   include/symbols.h            |  22 ++
>>>   lib/Kconfig                  |   9 +
>>>   lib/symbols.c                | 141 ++++++++++
>>>   tools/Makefile               |   3 +
>>>   tools/symbols.c              | 646 ++++++++++++++++++++++++++++++++ 
>>> + ++++++++++
>>>   15 files changed, 965 insertions(+), 121 deletions(-)
>>> ---
>>> base-commit: f2f451d9d6d3756458d5037e3e5135e5211582d7
>>>
>>> // Caleb (they/them)
>>>
>>>
>>
> .



More information about the U-Boot mailing list