diff options
Diffstat (limited to 'lib/libspl/assert.c')
-rw-r--r-- | lib/libspl/assert.c | 33 |
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 |