diff options
-rw-r--r-- | source3/configure.in | 4 | ||||
-rw-r--r-- | source3/lib/util.c | 40 |
2 files changed, 44 insertions, 0 deletions
diff --git a/source3/configure.in b/source3/configure.in index 38f908007c..7cc42fe5bd 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -921,6 +921,10 @@ AC_CHECK_FUNCS(setlocale nl_langinfo) # setbuffer, shmget, shm_open are needed for smbtorture AC_CHECK_FUNCS(setbuffer shmget shm_open backtrace_symbols) +# IRIX stack backtrace +AC_CHECK_HEADERS(libexc.h) +AC_CHECK_LIB(exc, trace_back_stack) + # syscall() is needed for smbwrapper. AC_CHECK_FUNCS(syscall) diff --git a/source3/lib/util.c b/source3/lib/util.c index 3da4e536e0..e9ab72b2bf 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -1344,6 +1344,10 @@ gid_t nametogid(const char *name) Something really nasty happened - panic ! ********************************************************************/ +#ifdef HAVE_LIBEXC_H +#include <libexc.h> +#endif + void smb_panic(const char *why) { char *cmd; @@ -1398,6 +1402,42 @@ void smb_panic(const char *why) SAFE_FREE(backtrace_strings); } +#elif HAVE_LIBEXC + +#define NAMESIZE 32 /* Arbitrary */ + + /* The IRIX libexc library provides an API for unwinding the stack. See + * libexc(3) for details. Apparantly trace_back_stack leaks memory, but + * since we are about to abort anyway, it hardly matters. + * + * Note that if we paniced due to a SIGSEGV or SIGBUS (or similar) this + * will fail with a nasty message upon failing to open the /proc entry. + */ + { + __uint64_t addrs[BACKTRACE_STACK_SIZE]; + char * names[BACKTRACE_STACK_SIZE]; + char namebuf[BACKTRACE_STACK_SIZE * NAMESIZE]; + + int i; + int levels; + + ZERO_ARRAY(addrs); + ZERO_ARRAY(names); + ZERO_ARRAY(namebuf); + + for (i = 0; i < BACKTRACE_STACK_SIZE; i++) { + names[i] = namebuf + (i * NAMESIZE); + } + + levels = trace_back_stack(0, addrs, names, + BACKTRACE_STACK_SIZE, NAMESIZE); + + DEBUG(0, ("BACKTRACE: %d stack frames:\n", levels)); + for (i = 0; i < levels; i++) { + DEBUGADD(0, (" #%d 0x%llx %s\n", i, addrs[i], names[i])); + } + } +#undef NAMESIZE #endif dbgflush(); |