* (c) Copyright 2009, Schooner Information Technology, Inc.
* http://www.schoonerinfotech.com/
*
+ * Rewrite of stack dump:
+ * Copyright (C) 2009 Sun Microsystems
+ * Author Trond Norbye
*/
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
-#include <ucontext.h>
-#include <dlfcn.h>
-#include <execinfo.h>
#include <pthread.h>
#include "ms_memslap.h"
#include "ms_setting.h"
-#if defined(__cplusplus) && defined(HAVE_ABI_CXA_DEMANGLE)
-# include <cxxabi.h>
-#endif
-
-#undef REG_RIP
-
-#if defined(REG_RIP)
-# define SIGSEGV_STACK_IA64
-# define REGFORMAT "%016lx"
-#elif defined(REG_EIP)
-# define SIGSEGV_STACK_X86
-# define REGFORMAT "%08x"
-#else
-# define SIGSEGV_STACK_GENERIC
-# define REGFORMAT "%x"
-#endif
-
/* prototypes */
int ms_setup_sigsegv(void);
int ms_setup_sigpipe(void);
/* signal seg reaches, this function will run */
static void ms_signal_segv(int signum, siginfo_t *info, void *ptr)
{
- int i;
-
UNUSED_ARGUMENT(signum);
UNUSED_ARGUMENT(info);
UNUSED_ARGUMENT(ptr);
pthread_mutex_lock(&ms_global.quit_mutex);
- fprintf(stderr, "Segmentation fault occurred.\n");
-
-#if defined(SIGSEGV_STACK_X86) || defined(SIGSEGV_STACK_IA64)
- int f= 0;
- Dl_info dlinfo;
- void **bp= 0;
- void *ip= 0;
-#else
- void *bt[20];
- char **strings;
- int sz;
-#endif
-
-#if defined(SIGSEGV_STACK_X86) || defined(SIGSEGV_STACK_IA64)
-# if defined(SIGSEGV_STACK_IA64)
- ip= (void *)ucontext->uc_mcontext.gregs[REG_RIP];
- bp= (void **)ucontext->uc_mcontext.gregs[REG_RBP];
-# elif defined(SIGSEGV_STACK_X86)
- ip= (void *)ucontext->uc_mcontext.gregs[REG_EIP];
- bp= (void **)ucontext->uc_mcontext.gregs[REG_EBP];
-# endif
-
- fprintf(stderr, "Stack trace:\n");
- while (bp && ip)
- {
- if (! dladdr(ip, &dlinfo))
- break;
-
- const char *symname= dlinfo.dli_sname;
-# if defined(HAVE_ABI_CXA_DEMANGLE) && defined(__cplusplus)
- int status;
- char *tmp= __cxa_demangle(symname, NULL, 0, &status);
-
- if ((status == 0) && tmp)
- symname= tmp;
-# endif
-
- fprintf(stderr, "% 2d: %p <%s+%u> (%s)\n",
- ++f,
- ip,
- symname,
- (unsigned)(ip - dlinfo.dli_saddr),
- dlinfo.dli_fname);
-
-# if defined(HAVE_ABI_CXA_DEMANGLE) && defined(__cplusplus)
- if (tmp)
- free(tmp);
-# endif
-
- if (dlinfo.dli_sname && ! strcmp(dlinfo.dli_sname, "main"))
- break;
-
- ip= bp[1];
- bp= (void **)bp[0];
- }
-#else
- fprintf(stderr, "Stack trace:\n");
- sz= backtrace(bt, 20);
- strings= backtrace_symbols(bt, sz);
-
- for (i= 0; i < sz; ++i)
- {
- fprintf(stderr, "%s\n", strings[i]);
- }
-#endif
+ fprintf(stderr, "Segmentation fault occurred.\nStack trace:\n");
+ pandora_print_callstack(stderr);
fprintf(stderr, "End of stack trace\n");
pthread_mutex_unlock(&ms_global.quit_mutex);
- exit(1);
-} /* ms_signal_segv */
-
+ abort();
+}
/* signal pipe reaches, this function will run */
static void ms_signal_pipe(int signum, siginfo_t *info, void *ptr)
--- /dev/null
+dnl Copyright (C) 2009 Sun Microsystems
+dnl This file is free software; Sun Microsystems
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl Try to define a macro to dump the current callstack.
+AC_DEFUN([PANDORA_PRINT_CALLSTACK],[
+ AC_CHECK_HEADERS([ucontext.h])
+ AS_IF([test "x$ac_cv_header_ucontext_h" = "xyes"],
+ [ AC_CHECK_FUNCS([printstack]) ])
+
+
+ AS_IF([ test "x$ac_cv_func_printstack" != "xyes"],
+ [ AC_CHECK_HEADERS([dlfcn.h])
+ AC_CHECK_HEADERS([execinfo.h])
+ AC_CHECK_FUNCS([backtrace])
+ AC_CHECK_FUNCS([backtrace_symbols_fd]) ])
+
+ AH_BOTTOM([
+#ifdef __cplusplus
+#include <cstdio>
+#define PANDORA_PRINTSTACK_STD_PREFIX std::
+#else
+#include <stdio.h>
+#define PANDORA_PRINTSTACK_STD_PREFIX
+#endif
+
+#if defined(HAVE_UCONTEXT_H) && defined(HAVE_PRINTSTACK)
+#include <ucontext.h>
+#define pandora_print_callstack(a) \
+printstack(PANDORA_PRINTSTACK_STD_PREFIX fileno(a))
+#elif defined(HAVE_EXECINFO_H) && defined(HAVE_BACKTRACE) && defined(HAVE_BACKTRACE_SYMBOLS_FD)
+
+#include <execinfo.h>
+
+#define pandora_print_callstack(a) \
+{ \
+ void *stack[100]; \
+ int depth = backtrace(stack, 100); \
+ backtrace_symbols_fd(stack, depth, PANDORA_PRINTSTACK_STD_PREFIX fileno(a)); \
+}
+#elif defined(HAVE_EXECINFO_H) && defined(HAVE_BACKTRACE) && defined(HAVE_BACKTRACE_SYMBOLS) && !defined(HAVE_BACKTRACE_SYMBOLS_FD)
+
+#include <execinfo.h>
+
+#define pandora_print_callstack(a) \
+{ \
+ void *stack[100]; \
+ int depth= backtrace(stack, 100); \
+ char **symbol= backtrace_symbols(stack, depth); \
+ for (int x= 0; x < size; ++x) \
+ PANDORA_PRINTSTACK_STD_PREFIX fprintf(a, "%s\n", symbol[x]); \
+}
+#else
+#define pandora_print_callstack(a) \
+ PANDORA_PRINTSTACK_STD_PREFIX fprintf(a, \
+ "Stackdump not supported for this platform\n");
+#endif
+ ])
+
+])