[Concept,08/10] backtrace: Add a command

Message ID 20251129080014.758001-9-sjg@u-boot.org
State New
Headers
Series backtrace: Add runtime support for looking at the backtrace |

Commit Message

Simon Glass Nov. 29, 2025, 7:59 a.m. UTC
  From: Simon Glass <simon.glass@canonical.com>

Add a new 'backtrace' command which prints the current call stack, which
is useful for debugging. The command is enabled by CONFIG_CMD_BACKTRACE

Add docs and a test.

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <simon.glass@canonical.com>
---

 cmd/Kconfig                 |  8 ++++++
 cmd/Makefile                |  1 +
 cmd/backtrace.c             | 30 ++++++++++++++++++++++
 doc/usage/cmd/backtrace.rst | 51 +++++++++++++++++++++++++++++++++++++
 doc/usage/index.rst         |  1 +
 test/cmd/Makefile           |  1 +
 test/cmd/backtrace.c        | 22 ++++++++++++++++
 7 files changed, 114 insertions(+)
 create mode 100644 cmd/backtrace.c
 create mode 100644 doc/usage/cmd/backtrace.rst
 create mode 100644 test/cmd/backtrace.c
  

Patch

diff --git a/cmd/Kconfig b/cmd/Kconfig
index a45df78c8fd..ff5f6f85144 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -136,6 +136,14 @@  config CMD_ADDR_FIND
 	  sufficiently large to hold a file. If successful, it sets the
 	  loadaddr variable to this address.
 
+config CMD_BACKTRACE
+	bool "backtrace"
+	depends on BACKTRACE
+	default y if BACKTRACE
+	help
+	  This command prints a backtrace showing the current call stack.
+	  This can be useful for debugging.
+
 config CMD_ADDRMAP
 	bool "addrmap"
 	depends on ADDR_MAP
diff --git a/cmd/Makefile b/cmd/Makefile
index 2c6a16752bd..ebf66ea0d3c 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -14,6 +14,7 @@  obj-y += version.o
 # command
 obj-$(CONFIG_CMD_ARMFFA) += armffa.o
 obj-$(CONFIG_CMD_2048) += 2048.o
+obj-$(CONFIG_CMD_BACKTRACE) += backtrace.o
 obj-$(CONFIG_CMD_ACPI) += acpi.o
 obj-$(CONFIG_CMD_ADDR_FIND) += addr_find.o
 obj-$(CONFIG_CMD_ADDRMAP) += addrmap.o
diff --git a/cmd/backtrace.c b/cmd/backtrace.c
new file mode 100644
index 00000000000..c54ac057f16
--- /dev/null
+++ b/cmd/backtrace.c
@@ -0,0 +1,30 @@ 
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Backtrace command
+ *
+ * Copyright 2025 Canonical Ltd
+ * Written by Simon Glass <simon.glass@canonical.com>
+ */
+
+#include <backtrace.h>
+#include <command.h>
+
+static int do_backtrace(struct cmd_tbl *cmdtp, int flag, int argc,
+			char *const argv[])
+{
+	int ret;
+
+	ret = backtrace_show();
+	if (ret) {
+		printf("backtrace failed: %d\n", ret);
+		return CMD_RET_FAILURE;
+	}
+
+	return 0;
+}
+
+U_BOOT_CMD(backtrace, 1, 1, do_backtrace,
+	   "Print backtrace",
+	   "\n"
+	   "    - Print a backtrace of the current call stack"
+);
diff --git a/doc/usage/cmd/backtrace.rst b/doc/usage/cmd/backtrace.rst
new file mode 100644
index 00000000000..37acb0b3067
--- /dev/null
+++ b/doc/usage/cmd/backtrace.rst
@@ -0,0 +1,51 @@ 
+.. SPDX-License-Identifier: GPL-2.0+
+
+.. index::
+   single: backtrace (command)
+
+backtrace command
+=================
+
+Synopsis
+--------
+
+::
+
+    backtrace
+
+Description
+-----------
+
+The *backtrace* command prints a backtrace of the current call stack. This can
+be useful for debugging to see how a particular code path was reached.
+
+The output shows each stack frame with the function name, source file, and line
+number (when debug information is available). This includes static functions.
+
+Example
+-------
+
+::
+
+    => backtrace
+    backtrace: 14 addresses
+      backtrace_show() at /home/user/u-boot/lib/backtrace.c:17
+      do_backtrace() at /home/user/u-boot/cmd/backtrace.c:18
+      cmd_process() at /home/user/u-boot/common/command.c:637
+      run_list_real() at /home/user/u-boot/common/cli_hush.c:1868
+      parse_stream_outer() at /home/user/u-boot/common/cli_hush.c:3207
+      parse_string_outer() at /home/user/u-boot/common/cli_hush.c:3257
+      run_command_list() at /home/user/u-boot/common/cli.c:168
+      sandbox_main_loop_init() at /home/user/u-boot/arch/sandbox/cpu/start.c:153
+      board_init_r() at /home/user/u-boot/common/board_r.c:774
+      ...
+
+Configuration
+-------------
+
+The backtrace command is enabled by CONFIG_CMD_BACKTRACE which depends on
+CONFIG_BACKTRACE. Currently this is only available on sandbox.
+
+The sandbox implementation uses libbacktrace (bundled with GCC) to provide
+detailed symbol information including function names, source files, and line
+numbers.
diff --git a/doc/usage/index.rst b/doc/usage/index.rst
index e8dbabfa9d2..8913c0a4f9b 100644
--- a/doc/usage/index.rst
+++ b/doc/usage/index.rst
@@ -31,6 +31,7 @@  Shell commands
    cmd/addrmap
    cmd/armffa
    cmd/askenv
+   cmd/backtrace
    cmd/base
    cmd/bdinfo
    cmd/bind
diff --git a/test/cmd/Makefile b/test/cmd/Makefile
index 4d8f93e2551..c43aefb4eb3 100644
--- a/test/cmd/Makefile
+++ b/test/cmd/Makefile
@@ -14,6 +14,7 @@  obj-y += exit.o
 obj-$(CONFIG_X86) += cpuid.o msr.o
 obj-$(CONFIG_CMD_ADDR_FIND) += addr_find.o
 obj-$(CONFIG_CMD_ADDRMAP) += addrmap.o
+obj-$(CONFIG_CMD_BACKTRACE) += backtrace.o
 obj-$(CONFIG_CMD_BDI) += bdinfo.o
 obj-$(CONFIG_CMD_BOOTSTAGE) += bootstage.o
 obj-$(CONFIG_CMD_CHID) += chid.o
diff --git a/test/cmd/backtrace.c b/test/cmd/backtrace.c
new file mode 100644
index 00000000000..2d999e20f31
--- /dev/null
+++ b/test/cmd/backtrace.c
@@ -0,0 +1,22 @@ 
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Test for backtrace command
+ *
+ * Copyright 2025 Canonical Ltd
+ * Written by Simon Glass <simon.glass@canonical.com>
+ */
+
+#include <dm.h>
+#include <dm/test.h>
+#include <test/test.h>
+#include <test/ut.h>
+
+/* Test 'backtrace' command */
+static int cmd_test_backtrace(struct unit_test_state *uts)
+{
+	/* for now, just run the command */
+	ut_assertok(run_command("backtrace", 0));
+
+	return 0;
+}
+DM_TEST(cmd_test_backtrace, UTF_SCAN_FDT);