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?


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.schucha...@canonical.com

To: Tom Rini <tr...@konsulko.com>
To: Heinrich Schuchardt <heinrich.schucha...@canonical.com>
Cc: Simon Glass <s...@chromium.org>
Cc: Marek Vasut <marek.vasut+rene...@mailbox.org>
Cc: Ben Dooks <ben.do...@codethink.co.uk>
Cc: Rick Chen <r...@andestech.com>
Cc: Leo <ycli...@andestech.com>
Cc: Ilias Apalodimas <ilias.apalodi...@linaro.org>
Cc: u-boot@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)



.

Reply via email to