Created a pandora-check for printing callstacks
authorTrond Norbye <trond.norbye@sun.com>
Sat, 5 Dec 2009 13:11:26 +0000 (14:11 +0100)
committerTrond Norbye <trond.norbye@sun.com>
Sat, 5 Dec 2009 13:11:26 +0000 (14:11 +0100)
clients/ms_sigsegv.c
configure.ac
m4/pandora_print_callstack.m4 [new file with mode: 0644]

index 2cdd3017d8ec49c272ca019e59437943cbe1adce..33029b42cc35d74b29406ff547c2f65c3926df82 100644 (file)
@@ -7,6 +7,9 @@
  * (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);
@@ -49,83 +32,17 @@ int ms_setup_sigint(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)
index aa051dd247c7667ed3cd88c5709ce1eca3ad33f7..7912531eb4f0e8d8dbb7dc4dd5dd79c6b1bdfd35 100644 (file)
@@ -24,7 +24,6 @@ PANDORA_HAVE_LIBEVENT
 PANDORA_REQUIRE_PTHREAD
 PANDORA_CXX_DEMANGLE
 
-
 dnl Specialty checks
 DETECT_BYTEORDER
 ENABLE_UTILLIB
@@ -35,6 +34,7 @@ PROTOCOL_BINARY_TEST
 WITH_MEMCACHED
 ENABLE_DEPRECATED
 PANDORA_HAVE_LIBINNODB
+PANDORA_PRINT_CALLSTACK
 
 AC_CONFIG_FILES([
   Makefile
diff --git a/m4/pandora_print_callstack.m4 b/m4/pandora_print_callstack.m4
new file mode 100644 (file)
index 0000000..e28b593
--- /dev/null
@@ -0,0 +1,61 @@
+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
+  ])
+
+])