From 98f4179156391752e6688339487458ad7828abf4 Mon Sep 17 00:00:00 2001 From: Alan Coopersmith Date: Thu, 26 Mar 2009 23:04:24 -0700 Subject: [PATCH] Use RTLD_DI_SETSIGNAL to catch runtime dynamic loader errors and clean up Based on fix for Sun bug 6813925: Xorg needs to catch ld.so.1 failure so it can close down devices cleanly Signed-off-by: Alan Coopersmith --- configure.ac | 2 +- os/osinit.c | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index f4e1dbb04..93ef0bd23 100644 --- a/configure.ac +++ b/configure.ac @@ -105,7 +105,7 @@ AM_CONDITIONAL(XSERVER_DTRACE, [test "x$WDTRACE" != "xno"]) AC_HEADER_DIRENT AC_HEADER_STDC -AC_CHECK_HEADERS([fcntl.h stdlib.h string.h unistd.h]) +AC_CHECK_HEADERS([fcntl.h stdlib.h string.h unistd.h dlfcn.h]) dnl Checks for typedefs, structures, and compiler characteristics. AC_C_CONST diff --git a/os/osinit.c b/os/osinit.c index 34d8378a6..b7bd0763b 100644 --- a/os/osinit.c +++ b/os/osinit.c @@ -56,6 +56,9 @@ SOFTWARE. #include #include #include +#ifdef HAVE_DLFCN_H +# include +#endif #include "dixstruct.h" @@ -113,6 +116,14 @@ OsSigHandler(int signo, siginfo_t *sip, void *unused) OsSigHandler(int signo) #endif { +#ifdef RTLD_DI_SETSIGNAL + const char *dlerr = dlerror(); + + if (dlerr) { + LogMessage(X_ERROR, "Dynamic loader error: %s\n", dlerr); + } +#endif /* RTLD_DI_SETSIGNAL */ + if (OsSigWrapper != NULL) { if (OsSigWrapper(signo) == 0) { /* ddx handled signal and wants us to continue */ @@ -180,6 +191,15 @@ OsInit(void) } } +#ifdef RTLD_DI_SETSIGNAL + /* Tell runtime linker to send a signal we can catch instead of SIGKILL + * for failures to load libraries/modules at runtime so we can clean up + * after ourselves. + */ + int failure_signal = SIGQUIT; + dlinfo(RTLD_SELF, RTLD_DI_SETSIGNAL, &failure_signal); +#endif + #if !defined(__SCO__) && !defined(__CYGWIN__) && !defined(__UNIXWARE__) fclose(stdin); fclose(stdout);