aboutsummaryrefslogtreecommitdiff
path: root/lib/libspl/assert.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libspl/assert.c')
-rw-r--r--lib/libspl/assert.c33
1 files changed, 32 insertions, 1 deletions
diff --git a/lib/libspl/assert.c b/lib/libspl/assert.c
index 4acf687f4b23..e6e3008f0aa6 100644
--- a/lib/libspl/assert.c
+++ b/lib/libspl/assert.c
@@ -49,7 +49,38 @@
pthread_getname_np(pthread_self(), buf, len);
#endif
-#if defined(HAVE_BACKTRACE)
+#if defined(HAVE_LIBUNWIND)
+#define UNW_LOCAL_ONLY
+#include <libunwind.h>
+
+static inline void
+libspl_dump_backtrace(void)
+{
+ unw_context_t uc;
+ unw_cursor_t cp;
+ unw_word_t ip, off;
+ char funcname[128];
+#ifdef HAVE_LIBUNWIND_ELF
+ char objname[128];
+ unw_word_t objoff;
+#endif
+
+ fprintf(stderr, "Call trace:\n");
+ unw_getcontext(&uc);
+ unw_init_local(&cp, &uc);
+ while (unw_step(&cp) > 0) {
+ unw_get_reg(&cp, UNW_REG_IP, &ip);
+ unw_get_proc_name(&cp, funcname, sizeof (funcname), &off);
+#ifdef HAVE_LIBUNWIND_ELF
+ unw_get_elf_filename(&cp, objname, sizeof (objname), &objoff);
+ fprintf(stderr, " [0x%08lx] %s+0x%2lx (in %s +0x%2lx)\n",
+ ip, funcname, off, objname, objoff);
+#else
+ fprintf(stderr, " [0x%08lx] %s+0x%2lx\n", ip, funcname, off);
+#endif
+ }
+}
+#elif defined(HAVE_BACKTRACE)
#include <execinfo.h>
static inline void