On 7/29/25 17:52, Casey Connolly wrote:
unwind_stack() will walk the callstack and show the symbol names
if available by using the architecture-specific framepointer
implementation.

When available, call unwind_stack() during a panic to give more
information about what caused the panic and help with debugging.

Adjust the interrupt handlers to call panic_str() to avoid duplicating
the backtrace.

Signed-off-by: Casey Connolly <casey.conno...@linaro.org>
---
  arch/arm/lib/interrupts_64.c | 8 ++++----
  include/symbols.h            | 9 ++++++++-
  lib/panic.c                  | 7 +++++++
  3 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/arch/arm/lib/interrupts_64.c b/arch/arm/lib/interrupts_64.c
index 
08d81ca7f654c586521ff97bb5ca37229c9b939d..949ae0f94168fd53036c1dff376b574808ebf9ea
 100644
--- a/arch/arm/lib/interrupts_64.c
+++ b/arch/arm/lib/interrupts_64.c
@@ -109,10 +109,10 @@ struct stack_frame {
static void print_sym(unsigned long lr)
  {
        /* Print the symbol address and the offset to the LR */
-       printf("\t<%#016lx> %s+%#lx\n", lr - (gd->flags & GD_FLG_RELOC ? 
gd->reloc_off : 0),
-              symname, offset);
+       printf("\t<%#016lx> %pS\n", lr - (gd->flags & GD_FLG_RELOC ? 
gd->reloc_off : 0),
+              (void *)lr);

Oops, I fluffed this fixup commit.


  }
/**
   * show_backtrace - show backtrace using frame pointers
@@ -228,9 +228,9 @@ static void except_msg(const char *msg, struct pt_regs 
*pt_regs)
        show_regs(pt_regs);
        if (CONFIG_IS_ENABLED(FRAMEPOINTER))
                show_backtrace(pt_regs->elr, pt_regs->regs[30], 
pt_regs->regs[29]);
        show_efi_loaded_images(pt_regs);
-       panic("Resetting CPU ...\n");
+       panic_str("Resetting CPU ...\n");
  }
/*
   * do_bad_sync handles the impossible case in the Synchronous Abort vector.
@@ -279,9 +279,9 @@ void do_sync(struct pt_regs *pt_regs)
        show_regs(pt_regs);
        if (CONFIG_IS_ENABLED(FRAMEPOINTER))
                show_backtrace(pt_regs->elr, pt_regs->regs[30], 
pt_regs->regs[29]);
        show_efi_loaded_images(pt_regs);
-       panic("Resetting CPU ...\n");
+       panic_str("Resetting CPU ...\n");
  }
/*
   * do_irq handles the Irq exception.
diff --git a/include/symbols.h b/include/symbols.h
index 
c5267edbe768f304bc0f6235e71a39b6c3835a67..845f993060f042139df46bcc51a0180faadc35bc
 100644
--- a/include/symbols.h
+++ b/include/symbols.h
@@ -4,9 +4,9 @@
  #include <string.h>
#define KSYM_NAME_LEN 127 -#if IS_ENABLED(CONFIG_SYMBOL_LOOKUP)
+#if CONFIG_IS_ENABLED(SYMBOL_LOOKUP)
  const char * __attribute__((weak)) symbol_lookup(unsigned long addr, unsigned 
long *symaddr, unsigned long *offset,
                           char *namebuf);
  #else
  static inline const char *symbol_lookup(unsigned long addr, unsigned long 
*symaddr, unsigned long *offset,
@@ -21,4 +21,11 @@ static inline const char *symbol_lookup(unsigned long addr, 
unsigned long *symad
        namebuf[3] = '\0';
        return namebuf;
  }
  #endif
+
+#if CONFIG_IS_ENABLED(FRAMEPOINTER)
+/**
+ * unwind_stack - unwind the callstack and print a backtrace.
+ */
+void unwind_stack(void);
+#endif
diff --git a/lib/panic.c b/lib/panic.c
index 
0f578b5b5131589d215f5f4b16b95d9c9f3e8ce3..6f8bd7cc1eef7e5d97ba925bef65cc46924b4418
 100644
--- a/lib/panic.c
+++ b/lib/panic.c
@@ -14,8 +14,9 @@
  #include <command.h>
  #endif
  #include <linux/delay.h>
  #include <stdio.h>
+#include <symbols.h>
static void panic_finish(void) __attribute__ ((noreturn)); static void panic_finish(void)
@@ -44,8 +45,14 @@ void panic(const char *fmt, ...)
        va_list args;
        va_start(args, fmt);
        vprintf(fmt, args);
        va_end(args);
+
+       if (CONFIG_IS_ENABLED(FRAMEPOINTER)) {
+               puts("\n");
+               unwind_stack();
+       }
+
  #endif
        panic_finish();
  }

Reply via email to