diff options
author | Alan Coopersmith <alan.coopersmith@sun.com> | 2009-03-09 13:22:57 -0700 |
---|---|---|
committer | Alan Coopersmith <alan.coopersmith@sun.com> | 2009-04-09 17:10:12 -0700 |
commit | a0b6a363dca8ce0dc6f4eb79333e48496153cd67 (patch) | |
tree | e67b9bb7ba752daf740905818cb26e6b110ac31a /os/osinit.c | |
parent | fcc19e673e3ef33d64916dd933853f8aa667c4d7 (diff) |
Lift fatal signal handlers from DDX'es up to a common DIX implementation
Signed-off-by: Alan Coopersmith <alan.coopersmith@sun.com>
Diffstat (limited to 'os/osinit.c')
-rw-r--r-- | os/osinit.c | 83 |
1 files changed, 83 insertions, 0 deletions
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 <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); |