From cff1e7c7bdf97cb764c49c04954c6dec07cf7869 Mon Sep 17 00:00:00 2001 From: Rob Norris Date: Tue, 15 Oct 2024 22:18:19 +1100 Subject: [PATCH] libspl/backtrace: dump registers in libunwind backtraces More useful stuff, especially when trying to follow a disassembly. Sponsored-by: https://despairlabs.com/sponsor/ Signed-off-by: Rob Norris --- lib/libspl/backtrace.c | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/lib/libspl/backtrace.c b/lib/libspl/backtrace.c index d26d742106e2..686964f1b9a2 100644 --- a/lib/libspl/backtrace.c +++ b/lib/libspl/backtrace.c @@ -65,32 +65,51 @@ libspl_backtrace(int fd) ssize_t ret __attribute__((unused)); unw_context_t uc; unw_cursor_t cp; - unw_word_t loc; + unw_word_t v; char buf[128]; - size_t n; + size_t n, c; - ret = write(fd, "Call trace:\n", 12); unw_getcontext(&uc); + + unw_init_local(&cp, &uc); + ret = write(fd, "Registers:\n", 11); + c = 0; + for (int regnum = 0; regnum <= UNW_TDEP_LAST_REG; regnum++) { + const char *name = unw_regname(regnum); + for (n = 0; name[n] != '\0'; n++) {} + ret = write(fd, " ", 2 + ((n == 2) ? 1 : 0)); + ret = write(fd, name, n); + unw_get_reg(&cp, regnum, &v); + ret = write(fd, ": 0x", 4); + n = libspl_u64_to_hex_str(v, 18, buf, sizeof (buf)); + ret = write(fd, buf, n); + if (!(++c % 3)) + ret = write(fd, "\n", 1); + } + if (c % 3) + ret = write(fd, "\n", 1); + unw_init_local(&cp, &uc); + ret = write(fd, "Call trace:\n", 12); while (unw_step(&cp) > 0) { - unw_get_reg(&cp, UNW_REG_IP, &loc); + unw_get_reg(&cp, UNW_REG_IP, &v); ret = write(fd, " [0x", 5); - n = libspl_u64_to_hex_str(loc, 10, buf, sizeof (buf)); + n = libspl_u64_to_hex_str(v, 18, buf, sizeof (buf)); ret = write(fd, buf, n); ret = write(fd, "] ", 2); - unw_get_proc_name(&cp, buf, sizeof (buf), &loc); + unw_get_proc_name(&cp, buf, sizeof (buf), &v); for (n = 0; n < sizeof (buf) && buf[n] != '\0'; n++) {} ret = write(fd, buf, n); ret = write(fd, "+0x", 3); - n = libspl_u64_to_hex_str(loc, 2, buf, sizeof (buf)); + n = libspl_u64_to_hex_str(v, 2, buf, sizeof (buf)); ret = write(fd, buf, n); #ifdef HAVE_LIBUNWIND_ELF ret = write(fd, " (in ", 5); - unw_get_elf_filename(&cp, buf, sizeof (buf), &loc); + unw_get_elf_filename(&cp, buf, sizeof (buf), &v); for (n = 0; n < sizeof (buf) && buf[n] != '\0'; n++) {} ret = write(fd, buf, n); ret = write(fd, " +0x", 4); - n = libspl_u64_to_hex_str(loc, 2, buf, sizeof (buf)); + n = libspl_u64_to_hex_str(v, 2, buf, sizeof (buf)); ret = write(fd, buf, n); ret = write(fd, ")", 1); #endif