Fix for backtrace deadlock and GLIBC
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Mon, 16 Jun 2014 11:55:25 +0000 (12:55 +0100)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Mon, 16 Jun 2014 11:59:30 +0000 (12:59 +0100)
src/lib/debug.c

index 3c4ff8b..1da7cd0 100644 (file)
@@ -454,8 +454,12 @@ void fr_fault(int sig)
        /*
         *      Produce a simple backtrace - They've very basic but at least give us an
         *      idea of the area of the code we hit the issue in.
+        *
+        *      See below in fr_fault_setup() and
+        *      https://sourceware.org/bugzilla/show_bug.cgi?id=16159
+        *      for why we only print backtraces in debug builds if we're using GLIBC.
         */
-#ifdef HAVE_EXECINFO
+#if defined(HAVE_EXECINFO) && (!defined(NDEBUG) || !defined(__GNUC__))
        {
                size_t frame_count, i;
                void *stack[MAX_BT_FRAMES];
@@ -730,6 +734,23 @@ int fr_fault_setup(char const *cmd, char const *program)
                mallopt(M_PERTURB, 0x42);
                mallopt(M_CHECK_ACTION, 3);
 #endif
+
+#if defined(HAVE_EXECINFO) && defined(__GNUC__) && defined(NDEBUG)
+              /*
+               *  We need to pre-load lgcc_s, else we can get into a deadlock
+               *  in fr_fault, as backtrace() attempts to dlopen it.
+               *
+               *  Apparently there's a performance impact of loading lgcc_s,
+               *  so only do it if this is a debug build.
+               *
+               *  See: https://sourceware.org/bugzilla/show_bug.cgi?id=16159
+               */
+               {
+                       void *stack[10];
+
+                       backtrace(stack, 10);
+               }
+#endif
        }
        setup = true;