summaryrefslogtreecommitdiff
path: root/os/osinit.c
diff options
context:
space:
mode:
authorAdam Jackson <ajax@redhat.com>2009-08-20 15:28:57 -0400
committerAdam Jackson <ajax@redhat.com>2009-08-20 15:43:55 -0400
commit0b131a5cd91cea54240777c66a9cd385029e8cb2 (patch)
tree5dab0b7c4f38f521244ece0a846b1ea7787d0602 /os/osinit.c
parent792dee3854cbede64e17fdc4736831edad295706 (diff)
linux: Yet more malloc() avoidance for backtrace()
Turns out, there's an initializer at the top of backtrace() that (on some arches) calls dlopen(). dlopen(), unsurprisingly, calls malloc(). So, call backtrace() early in signal handler setup so we can later safely call it from the signal handler itself.
Diffstat (limited to 'os/osinit.c')
-rw-r--r--os/osinit.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/os/osinit.c b/os/osinit.c
index 17a2bedc7..e8fcd4540 100644
--- a/os/osinit.c
+++ b/os/osinit.c
@@ -59,6 +59,10 @@ SOFTWARE.
#ifdef HAVE_DLFCN_H
# include <dlfcn.h>
#endif
+#ifdef HAVE_BACKTRACE
+#include <execinfo.h>
+#endif
+
#include "dixstruct.h"
@@ -192,6 +196,16 @@ OsInit(void)
siglist[i], strerror(errno));
}
}
+#ifdef HAVE_BACKTRACE
+ /*
+ * initialize the backtracer, since the ctor calls dlopen(), which
+ * calls malloc(), which isn't signal-safe.
+ */
+ do {
+ void *array;
+ backtrace(&array, 1);
+ } while (0);
+#endif
#ifdef RTLD_DI_SETSIGNAL
/* Tell runtime linker to send a signal we can catch instead of SIGKILL