[PATCH v5 09/10] lib: expose unwind_stack() and call it from panic()

Casey Connolly casey.connolly at linaro.org
Tue Jul 29 18:07:30 CEST 2025


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.connolly at linaro.org>
---
 arch/arm/lib/interrupts_64.c | 4 ++--
 include/symbols.h            | 7 +++++++
 lib/panic.c                  | 7 +++++++
 3 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/arch/arm/lib/interrupts_64.c b/arch/arm/lib/interrupts_64.c
index 973ade4b3b2b649b76fa6b67742a247dbacf7ffa..949ae0f94168fd53036c1dff376b574808ebf9ea 100644
--- a/arch/arm/lib/interrupts_64.c
+++ b/arch/arm/lib/interrupts_64.c
@@ -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 f91f249e7cc49e4bce338517b5d00624a05360d5..845f993060f042139df46bcc51a0180faadc35bc 100644
--- a/include/symbols.h
+++ b/include/symbols.h
@@ -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();
 }
 

-- 
2.50.0



More information about the U-Boot mailing list