From 97a9ea6fd9e5df4a1c6eea734da2fc77ce399ebc Mon Sep 17 00:00:00 2001 From: Trond Norbye Date: Sat, 5 Dec 2009 14:11:26 +0100 Subject: [PATCH] Created a pandora-check for printing callstacks --- clients/ms_sigsegv.c | 97 +++-------------------------------- configure.ac | 2 +- m4/pandora_print_callstack.m4 | 61 ++++++++++++++++++++++ 3 files changed, 69 insertions(+), 91 deletions(-) create mode 100644 m4/pandora_print_callstack.m4 diff --git a/clients/ms_sigsegv.c b/clients/ms_sigsegv.c index 2cdd3017..33029b42 100644 --- a/clients/ms_sigsegv.c +++ b/clients/ms_sigsegv.c @@ -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" @@ -15,31 +18,11 @@ #include #include #include -#include -#include -#include #include #include "ms_memslap.h" #include "ms_setting.h" -#if defined(__cplusplus) && defined(HAVE_ABI_CXA_DEMANGLE) -# include -#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) diff --git a/configure.ac b/configure.ac index aa051dd2..7912531e 100644 --- a/configure.ac +++ b/configure.ac @@ -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 index 00000000..e28b5933 --- /dev/null +++ b/m4/pandora_print_callstack.m4 @@ -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 +#define PANDORA_PRINTSTACK_STD_PREFIX std:: +#else +#include +#define PANDORA_PRINTSTACK_STD_PREFIX +#endif + +#if defined(HAVE_UCONTEXT_H) && defined(HAVE_PRINTSTACK) +#include +#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 + +#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 + +#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 + ]) + +]) -- 2.30.2