From a0b6a363dca8ce0dc6f4eb79333e48496153cd67 Mon Sep 17 00:00:00 2001 From: Alan Coopersmith Date: Mon, 9 Mar 2009 13:22:57 -0700 Subject: Lift fatal signal handlers from DDX'es up to a common DIX implementation Signed-off-by: Alan Coopersmith --- os/log.c | 7 ++++++ os/osinit.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+) (limited to 'os') diff --git a/os/log.c b/os/log.c index b01965a17..3961b0b9f 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 +#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 f9ee73ec1..34d8378a6 100644 --- a/os/osinit.c +++ b/os/osinit.c @@ -54,6 +54,8 @@ SOFTWARE. #include "os.h" #include "osdep.h" #include +#include +#include #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); -- cgit v1.2.3