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 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); -- 2.43.0