Browse Source

Backport bits from SSL tree.

Brian Aker 12 years ago
parent
commit
98b027e44f
4 changed files with 105 additions and 108 deletions
  1. 9 2
      configure.ac
  2. 33 28
      gearmand/gearmand.cc
  3. 59 76
      libgearman/backtrace.cc
  4. 4 2
      libgearman/include.am

+ 9 - 2
configure.ac

@@ -104,6 +104,7 @@ AC_CHECK_HEADERS([cxxabi.h],
                  AC_DEFINE([HAVE_CXXABI_H], [1], [Have cxxabi.h]),
                  AC_DEFINE([HAVE_CXXABI_H], [0], [Have cxxabi.h]))
 AC_CHECK_HEADERS_ONCE([arpa/inet.h])
+AC_CHECK_HEADERS_ONCE([dlfcn.h])
 AC_CHECK_HEADERS_ONCE([errno.h])
 AC_CHECK_HEADERS_ONCE([execinfo.h])
 AC_CHECK_HEADERS_ONCE([fcntl.h])
@@ -196,12 +197,12 @@ AC_CHECK_FUNCS([strstr])
 
 LT_LIB_M
 
+# Check for the ability to call dlopen (used in libhostile)
 # Check for the ability to call dlopen (used in libhostile)
 AS_IF([test "x$enable_shared" = xyes],
       [AC_CHECK_LIB([dl],[dlopen],
                     [AC_SUBST([DL_LIB],[-ldl])
-                    AC_DEFINE([HAVE_LIBDL],[1],[Have dlopen])])],
-                    [AC_DEFINE([HAVE_LIBDL],[0],[Have dlopen])])
+                    AC_DEFINE([HAVE_LIBDL],[1],[Have dlopen])])])
 
 # Check for -lrt
 AC_CHECK_LIB([rt],[clock_gettime],
@@ -234,6 +235,12 @@ AX_HARDEN_COMPILER_FLAGS
 
 AM_CONDITIONAL([TARGET_MINGW],[test "x${MINGW}" = "xtrue"])
 
+# backtrace(), others require shared builds
+AS_IF([test "x$enable_shared" = "xyes"],
+      [AC_DEFINE([HAVE_SHARED_ENABLED],[1],[Enable code which requires shared library support. Like backtrace().])
+      AX_CXX_GCC_ABI_DEMANGLE])
+AM_CONDITIONAL([SHARED_ENABLED],[test "x$enable_shared" = "xyes"])
+
 AC_CONFIG_FILES([Makefile
                  docs/conf.py
                  libgearman-1.0/version.h

+ 33 - 28
gearmand/gearmand.cc

@@ -474,12 +474,12 @@ extern "C" void _reset_log_handler(int) // signal_arg
 }
 
 static bool segfaulted= false;
-extern "C" void _crash_handler(int)
+extern "C" void _crash_handler(int signal_)
 {
   if (segfaulted)
   {
-    error::message("Fatal crash while backtracing");
-    _exit(1); /* Quit without running destructors */
+    error::message("Fatal crash while backtracing", strsignal(signal_));
+    _exit(EXIT_FAILURE); /* Quit without running destructors */
   }
 
   segfaulted= true;
@@ -527,36 +527,41 @@ static bool _set_signals(void)
     return true;
   }
 
-  sa.sa_handler= _crash_handler;
-  if (sigaction(SIGSEGV, &sa, NULL) == -1)
-  {
-    error::perror("Could not set SIGSEGV handler.");
-    return true;
-  }
+  bool in_gdb_libtest= bool(getenv("LIBTEST_IN_GDB"));
 
-  if (sigaction(SIGABRT, &sa, NULL) == -1)
+  if (in_gdb_libtest == false)
   {
-    error::perror("Could not set SIGABRT handler.");
-    return true;
-  }
-  
+    sa.sa_handler= _crash_handler;
+    if (sigaction(SIGSEGV, &sa, NULL) == -1)
+    {
+      error::perror("Could not set SIGSEGV handler.");
+      return true;
+    }
+
+    if (sigaction(SIGABRT, &sa, NULL) == -1)
+    {
+      error::perror("Could not set SIGABRT handler.");
+      return true;
+    }
+
 #ifdef SIGBUS
-  if (sigaction(SIGBUS, &sa, NULL) == -1)
-  {
-    error::perror("Could not set SIGBUS handler.");
-    return true;
-  }
+    if (sigaction(SIGBUS, &sa, NULL) == -1)
+    {
+      error::perror("Could not set SIGBUS handler.");
+      return true;
+    }
 #endif
-  if (sigaction(SIGILL, &sa, NULL) == -1)
-  {
-    error::perror("Could not set SIGBUS handler.");
-    return true;
-  }
+    if (sigaction(SIGILL, &sa, NULL) == -1)
+    {
+      error::perror("Could not set SIGBUS handler.");
+      return true;
+    }
 
-  if (sigaction(SIGFPE, &sa, NULL) == -1)
-  {
-    error::perror("Could not set SIGBUS handler.");
-    return true;
+    if (sigaction(SIGFPE, &sa, NULL) == -1)
+    {
+      error::perror("Could not set SIGBUS handler.");
+      return true;
+    }
   }
 
   return false;

+ 59 - 76
libgearman/backtrace.cc

@@ -1,6 +1,6 @@
 /*  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
  * 
- *  libgearman client library.
+ *  Libgearman client library.
  *
  *  Copyright (C) 2012 Data Differential, http://datadifferential.com/
  *  All rights reserved.
@@ -43,106 +43,89 @@
 #include <cstdlib>
 #include <cstring>
 
+#if defined(HAVE_SHARED_ENABLED) && HAVE_SHARED_ENABLED
+
 #ifdef HAVE_EXECINFO_H
 #include <execinfo.h>
 #endif
 
-#ifdef HAVE_CXXABI_H
-#include <cxxabi.h>
-#endif
-
 #ifdef HAVE_GCC_ABI_DEMANGLE
+# include <cxxabi.h>
 # define USE_DEMANGLE 1
 #else
 # define USE_DEMANGLE 0
 #endif
 
+#ifdef HAVE_DLFCN_H
+# include <dlfcn.h>
+#endif   
+
+const int MAX_DEPTH= 50;
+
 void custom_backtrace(void)
 {
 #ifdef HAVE_EXECINFO_H
-  void *array[50];
-
-  int size= backtrace(array, 50);
-  char **strings= backtrace_symbols(array, size);
-
-  if (strings == NULL)
-  {
-    return;
-  }
-
-  fprintf(stderr, "Number of stack frames obtained: %lu\n", (unsigned long)size);
+  void *backtrace_buffer[MAX_DEPTH +1];
 
-  char *named_function= (char *)::realloc(NULL, 1024);
-  
-  if (named_function == NULL)
+  int stack_frames= backtrace(backtrace_buffer, MAX_DEPTH);
+  if (stack_frames)
   {
-    ::free(strings);
-    return;
-  }
-
-  for (int x= 1; x < size; x++) 
-  {
-    if (USE_DEMANGLE)
+    char **symbollist= backtrace_symbols(backtrace_buffer, stack_frames);
+    if (symbollist)
     {
-      size_t sz= 200;
-      char *named_function_ptr= (char *)::realloc(named_function, sz);
-      if (named_function_ptr == NULL)
+      for (int x= 0; x < stack_frames; x++) 
       {
-        continue;
-      }
-      named_function= named_function_ptr;
-
-      char *begin_name= 0;
-      char *begin_offset= 0;
-      char *end_offset= 0;
+        bool was_demangled= false;
 
-      for (char *j= strings[x]; *j; ++j)
-      {
-        if (*j == '(')
-        {
-          begin_name= j;
-        }
-        else if (*j == '+')
+        if (USE_DEMANGLE)
         {
-          begin_offset= j;
-        }
-        else if (*j == ')' and begin_offset) 
-        {
-          end_offset= j;
-          break;
+#ifdef HAVE_DLFCN_H
+          Dl_info dlinfo;
+          if (dladdr(backtrace_buffer[x], &dlinfo))
+          {
+            char demangled_buffer[1024];
+            const char *called_in= "<unresolved>";
+            if (dlinfo.dli_sname)
+            {
+              size_t demangled_size= sizeof(demangled_buffer);
+              int status;
+              char* demangled;
+              if ((demangled= abi::__cxa_demangle(dlinfo.dli_sname, demangled_buffer, &demangled_size, &status)))
+              {
+                called_in= demangled;
+                fprintf(stderr, "---> demangled: %s -> %s\n", demangled_buffer, demangled);
+              }
+              else
+              {
+                called_in= dlinfo.dli_sname;
+              }
+
+              was_demangled= true;
+              fprintf(stderr, "#%d  %p in %s at %s\n",
+                      x, backtrace_buffer[x],
+                      called_in,
+                      dlinfo.dli_fname);
+            }
+          }
+#endif
         }
-      }
-
-      if (begin_name and begin_offset and end_offset and begin_name < begin_offset)
-      {
-        *begin_name++= '\0';
-        *begin_offset++= '\0';
-        *end_offset= '\0';
 
-        int status;
-        char *ret= abi::__cxa_demangle(begin_name, named_function, &sz, &status);
-        if (ret) // realloc()'ed string
+        if (was_demangled == false)
         {
-          named_function= ret;
-          fprintf(stderr, "  %s : %s()+%s\n", strings[x], begin_name, begin_offset);
+          fprintf(stderr, "?%d  %p in %s\n", x, backtrace_buffer[x], symbollist[x]);
         }
-        else
-        {
-          fprintf(stderr, "  %s : %s()+%s\n", strings[x], begin_name, begin_offset);
-        }
-      }
-      else
-      {
-        fprintf(stderr, " %s\n", strings[x]);
       }
-    }
-    else
-    {
-      fprintf(stderr, " unmangled: %s\n", strings[x]);
+
+      ::free(symbollist);
     }
   }
-
-  ::free(named_function);
-  ::free(strings);
 #endif // HAVE_EXECINFO_H
 }
+
+#else // HAVE_SHARED_ENABLED
+
+void custom_backtrace(void)
+{
+  fprintf(stderr, "Backtrace null function called\n");
+}
+#endif // AX_ENABLE_BACKTRACE

+ 4 - 2
libgearman/include.am

@@ -113,10 +113,12 @@ libgearman_libgearman_la_CXXFLAGS= -DBUILDING_LIBGEARMAN
 
 libgearman_libgearman_la_LDFLAGS= -version-info $(GEARMAN_LIBRARY_VERSION)
 
-libgearman_libgearman_la_LIBADD= @LIBUUID_LIB@
+libgearman_libgearman_la_LIBADD=
+libgearman_libgearman_la_LIBADD+= @LIBUUID_LIB@
+libgearman_libgearman_la_LIBADD+= @DL_LIB@
 
 if TARGET_LINUX
-libgearman_libgearman_la_LIBADD+= -lm
+libgearman_libgearman_la_LIBADD+= @LIBM@
 endif