summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
Diffstat (limited to 'source3')
-rw-r--r--source3/configure.in2
-rw-r--r--source3/lib/util.c40
2 files changed, 42 insertions, 0 deletions
diff --git a/source3/configure.in b/source3/configure.in
index 7546ba6773..27d39d13ca 100644
--- a/source3/configure.in
+++ b/source3/configure.in
@@ -919,6 +919,8 @@ AC_CHECK_FUNCS(syslog vsyslog timegm)
AC_CHECK_FUNCS(setlocale nl_langinfo)
# setbuffer, shmget, shm_open are needed for smbtorture
AC_CHECK_FUNCS(setbuffer shmget shm_open backtrace_symbols)
+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();