xserver: Branch 'master' - 2 commits
Alan Coopersmith
alanc at kemper.freedesktop.org
Thu Apr 9 17:11:33 PDT 2009
configure.ac | 2
hw/kdrive/src/kdrive.c | 34 +------------
hw/xfree86/common/xf86Events.c | 28 ++---------
hw/xfree86/common/xf86Init.c | 18 +++----
hw/xfree86/common/xf86Priv.h | 2
include/os.h | 2
os/log.c | 7 ++
os/osinit.c | 103 +++++++++++++++++++++++++++++++++++++++++
8 files changed, 134 insertions(+), 62 deletions(-)
New commits:
commit 98f4179156391752e6688339487458ad7828abf4
Author: Alan Coopersmith <alan.coopersmith at sun.com>
Date: Thu Mar 26 23:04:24 2009 -0700
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
<http://bugs.opensolaris.org/bugdatabase/view_bug.do?bug_id=6813925>
Signed-off-by: Alan Coopersmith <alan.coopersmith at sun.com>
diff --git a/configure.ac b/configure.ac
index f4e1dbb..93ef0bd 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 34d8378..b7bd076 100644
--- a/os/osinit.c
+++ b/os/osinit.c
@@ -56,6 +56,9 @@ SOFTWARE.
#include <X11/Xos.h>
#include <signal.h>
#include <errno.h>
+#ifdef HAVE_DLFCN_H
+# include <dlfcn.h>
+#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);
commit a0b6a363dca8ce0dc6f4eb79333e48496153cd67
Author: Alan Coopersmith <alan.coopersmith at sun.com>
Date: Mon Mar 9 13:22:57 2009 -0700
Lift fatal signal handlers from DDX'es up to a common DIX implementation
Signed-off-by: Alan Coopersmith <alan.coopersmith at sun.com>
diff --git a/hw/kdrive/src/kdrive.c b/hw/kdrive/src/kdrive.c
index 76355e8..ccef2a0 100644
--- a/hw/kdrive/src/kdrive.c
+++ b/hw/kdrive/src/kdrive.c
@@ -1279,38 +1279,12 @@ KdDepthToFb (ScreenPtr pScreen, int depth)
#endif
-#ifdef HAVE_BACKTRACE
-/* shamelessly ripped from xf86Events.c */
-void
-KdBacktrace (int signum)
-{
- void *array[32]; /* more than 32 and you have bigger problems */
- size_t size, i;
- char **strings;
-
- signal(signum, SIG_IGN);
-
- size = backtrace (array, 32);
- fprintf (stderr, "\nBacktrace (%d deep):\n", size);
- strings = backtrace_symbols (array, size);
- for (i = 0; i < size; i++)
- fprintf (stderr, "%d: %s\n", i, strings[i]);
- free (strings);
-
- kdCaughtSignal = TRUE;
- if (signum == SIGSEGV)
- FatalError("Segmentation fault caught\n");
- else if (signum > 0)
- FatalError("Signal %d caught\n", signum);
-}
-#else
-void
-KdBacktrace (int signum)
+static int
+KdSignalWrapper (int signum)
{
kdCaughtSignal = TRUE;
- FatalError("Segmentation fault caught\n");
+ return 1; /* use generic OS layer cleanup & abort */
}
-#endif
void
KdInitOutput (ScreenInfo *pScreenInfo,
@@ -1357,7 +1331,7 @@ KdInitOutput (ScreenInfo *pScreenInfo,
for (screen = card->screenList; screen; screen = screen->next)
KdAddScreen (pScreenInfo, screen, argc, argv);
- signal(SIGSEGV, KdBacktrace);
+ OsRegisterSigWrapper(KdSignalWrapper);
}
void
diff --git a/hw/xfree86/common/xf86Events.c b/hw/xfree86/common/xf86Events.c
index 19120ce..aa818c3 100644
--- a/hw/xfree86/common/xf86Events.c
+++ b/hw/xfree86/common/xf86Events.c
@@ -79,11 +79,6 @@
#include "xkbsrv.h"
#include "xkbstr.h"
-#ifdef XF86BIGFONT
-#define _XF86BIGFONT_SERVER_
-#include <X11/extensions/xf86bigfont.h>
-#endif
-
#ifdef DPMSExtension
#define DPMS_SERVER
#include <X11/extensions/dpms.h>
@@ -356,35 +351,24 @@ xf86InterceptSigIll(void (*sigillhandler)(void))
}
/*
- * xf86SigHandler --
+ * xf86SigWrapper --
* Catch unexpected signals and exit or continue cleanly.
*/
-void
-xf86SigHandler(int signo)
+int
+xf86SigWrapper(int signo)
{
if ((signo == SIGILL) && xf86SigIllHandler) {
(*xf86SigIllHandler)();
- /* Re-arm handler just in case we unexpectedly return here */
- (void) signal(signo, xf86SigHandler);
- return;
+ return 0; /* continue */
}
if (xf86SignalIntercept && (*xf86SignalIntercept < 0)) {
*xf86SignalIntercept = signo;
- /* Re-arm handler just in case */
- (void) signal(signo, xf86SigHandler);
- return;
+ return 0; /* continue */
}
- signal(signo,SIG_IGN);
xf86Info.caughtSignal = TRUE;
-#ifdef XF86BIGFONT
- XF86BigfontCleanup();
-#endif
-
- xorg_backtrace();
-
- FatalError("Caught signal %d. Server aborting\n", signo);
+ return 1; /* abort */
}
/*
diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c
index acb775b..cf28ae7 100644
--- a/hw/xfree86/common/xf86Init.c
+++ b/hw/xfree86/common/xf86Init.c
@@ -380,23 +380,25 @@ InstallSignalHandlers(void)
*/
xf86Info.caughtSignal=FALSE;
if (!xf86Info.notrapSignals) {
- signal(SIGSEGV,xf86SigHandler);
- signal(SIGILL,xf86SigHandler);
+ OsRegisterSigWrapper(xf86SigWrapper);
+ } else {
+ signal(SIGSEGV, SIG_DFL);
+ signal(SIGILL, SIG_DFL);
#ifdef SIGEMT
- signal(SIGEMT,xf86SigHandler);
+ signal(SIGEMT, SIG_DFL);
#endif
- signal(SIGFPE,xf86SigHandler);
+ signal(SIGFPE, SIG_DFL);
#ifdef SIGBUS
- signal(SIGBUS,xf86SigHandler);
+ signal(SIGBUS, SIG_DFL);
#endif
#ifdef SIGSYS
- signal(SIGSYS,xf86SigHandler);
+ signal(SIGSYS, SIG_DFL);
#endif
#ifdef SIGXCPU
- signal(SIGXCPU,xf86SigHandler);
+ signal(SIGXCPU, SIG_DFL);
#endif
#ifdef SIGXFSZ
- signal(SIGXFSZ,xf86SigHandler);
+ signal(SIGXFSZ, SIG_DFL);
#endif
}
}
diff --git a/hw/xfree86/common/xf86Priv.h b/hw/xfree86/common/xf86Priv.h
index bc984f2..f4ed8c0 100644
--- a/hw/xfree86/common/xf86Priv.h
+++ b/hw/xfree86/common/xf86Priv.h
@@ -147,7 +147,7 @@ extern _X_EXPORT void DoShowOptions(void);
/* xf86Events.c */
extern _X_EXPORT void xf86Wakeup(pointer blockData, int err, pointer pReadmask);
-extern _X_EXPORT void xf86SigHandler(int signo);
+extern _X_HIDDEN int xf86SigWrapper(int signo);
extern _X_EXPORT void xf86HandlePMEvents(int fd, pointer data);
extern _X_EXPORT int (*xf86PMGetEventFromOs)(int fd,pmEvent *events,int num);
extern _X_EXPORT pmWait (*xf86PMConfirmEventToOs)(int fd,pmEvent event);
diff --git a/include/os.h b/include/os.h
index bda7125..2f6b0c0 100644
--- a/include/os.h
+++ b/include/os.h
@@ -228,8 +228,10 @@ extern _X_EXPORT char *XNFprintf(const char *fmt, ...);
extern _X_EXPORT char *XNFvprintf(const char *fmt, va_list va);
typedef void (*OsSigHandlerPtr)(int /* sig */);
+typedef int (*OsSigWrapperPtr)(int /* sig */);
extern _X_EXPORT OsSigHandlerPtr OsSignal(int /* sig */, OsSigHandlerPtr /* handler */);
+extern _X_EXPORT OsSigWrapperPtr OsRegisterSigWrapper(OsSigWrapperPtr newWrap);
extern _X_EXPORT int auditTrailLevel;
diff --git a/os/log.c b/os/log.c
index b01965a..3961b0b 100644
--- a/os/log.c
+++ b/os/log.c
@@ -98,6 +98,10 @@ OR PERFORMANCE OF THIS SOFTWARE.
#define getpid(x) _getpid(x)
#endif
+#ifdef XF86BIGFONT
+#define _XF86BIGFONT_SERVER_
+#include <X11/extensions/xf86bigfont.h>
+#endif
#ifdef DDXOSVERRORF
void (*OsVendorVErrorFProc)(const char *, va_list args) = NULL;
@@ -401,6 +405,9 @@ void AbortServer(void) __attribute__((noreturn));
void
AbortServer(void)
{
+#ifdef XF86BIGFONT
+ XF86BigfontCleanup();
+#endif
CloseWellKnownConnections();
OsCleanup(TRUE);
CloseDownDevices();
diff --git a/os/osinit.c b/os/osinit.c
index f9ee73e..34d8378 100644
--- a/os/osinit.c
+++ b/os/osinit.c
@@ -54,6 +54,8 @@ SOFTWARE.
#include "os.h"
#include "osdep.h"
#include <X11/Xos.h>
+#include <signal.h>
+#include <errno.h>
#include "dixstruct.h"
@@ -88,6 +90,58 @@ int limitStackSpace = -1;
int limitNoFile = -1;
#endif
+static OsSigWrapperPtr OsSigWrapper = NULL;
+
+OsSigWrapperPtr
+OsRegisterSigWrapper(OsSigWrapperPtr newSigWrapper)
+{
+ OsSigWrapperPtr oldSigWrapper = OsSigWrapper;
+
+ OsSigWrapper = newSigWrapper;
+
+ return oldSigWrapper;
+}
+
+/*
+ * OsSigHandler --
+ * Catch unexpected signals and exit or continue cleanly.
+ */
+static void
+#ifdef SA_SIGINFO
+OsSigHandler(int signo, siginfo_t *sip, void *unused)
+#else
+OsSigHandler(int signo)
+#endif
+{
+ if (OsSigWrapper != NULL) {
+ if (OsSigWrapper(signo) == 0) {
+ /* ddx handled signal and wants us to continue */
+ return;
+ }
+ }
+
+ /* log, cleanup, and abort */
+ xorg_backtrace();
+
+#ifdef SA_SIGINFO
+ if (sip->si_code == SI_USER) {
+ ErrorF("Recieved signal %d sent by process %ld, uid %ld\n",
+ (long) sip->si_pid, (long) sip->si_uid);
+ } else {
+ switch (signo) {
+ case SIGSEGV:
+ case SIGBUS:
+ case SIGILL:
+ case SIGFPE:
+ ErrorF("%s at address %p\n", strsignal(signo), sip->si_addr);
+ }
+ }
+#endif
+
+ FatalError("Caught signal %d (%s). Server aborting\n",
+ signo, strsignal(signo));
+}
+
void
OsInit(void)
{
@@ -97,6 +151,35 @@ OsInit(void)
char fname[PATH_MAX];
if (!been_here) {
+ struct sigaction act, oact;
+ int i;
+ int siglist[] = { SIGSEGV, SIGQUIT, SIGILL, SIGFPE, SIGBUS,
+#ifdef SIGSYS
+ SIGSYS,
+#endif
+#ifdef SIGXCPU
+ SIGXCPU,
+#endif
+#ifdef SIGXFSZ
+ SIGXFSZ,
+#endif
+#ifdef SIGEMT
+ SIGEMT,
+#endif
+ 0 /* must be last */ };
+ sigemptyset(&act.sa_mask);
+ act.sa_handler = OsSigHandler;
+ act.sa_flags = 0;
+#ifdef SA_SIGINFO
+ act.sa_flags |= SA_SIGINFO;
+#endif
+ for (i = 0; siglist[i] != 0; i++) {
+ if (sigaction(siglist[i], &act, &oact)) {
+ ErrorF("failed to install signal handler for signal %d: %s\n",
+ siglist[i], strerror(errno));
+ }
+ }
+
#if !defined(__SCO__) && !defined(__CYGWIN__) && !defined(__UNIXWARE__)
fclose(stdin);
fclose(stdout);
More information about the xorg-commit
mailing list