Lift fatal signal handlers from DDX'es up to a common DIX implementation

Signed-off-by: Alan Coopersmith <alan.coopersmith@sun.com>
This commit is contained in:
Alan Coopersmith 2009-03-09 13:22:57 -07:00
parent fcc19e673e
commit a0b6a363dc
7 changed files with 113 additions and 61 deletions

View File

@ -1279,38 +1279,12 @@ KdDepthToFb (ScreenPtr pScreen, int depth)
#endif #endif
#ifdef HAVE_BACKTRACE static int
/* shamelessly ripped from xf86Events.c */ KdSignalWrapper (int signum)
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)
{ {
kdCaughtSignal = TRUE; kdCaughtSignal = TRUE;
FatalError("Segmentation fault caught\n"); return 1; /* use generic OS layer cleanup & abort */
} }
#endif
void void
KdInitOutput (ScreenInfo *pScreenInfo, KdInitOutput (ScreenInfo *pScreenInfo,
@ -1357,7 +1331,7 @@ KdInitOutput (ScreenInfo *pScreenInfo,
for (screen = card->screenList; screen; screen = screen->next) for (screen = card->screenList; screen; screen = screen->next)
KdAddScreen (pScreenInfo, screen, argc, argv); KdAddScreen (pScreenInfo, screen, argc, argv);
signal(SIGSEGV, KdBacktrace); OsRegisterSigWrapper(KdSignalWrapper);
} }
void void

View File

@ -79,11 +79,6 @@
#include "xkbsrv.h" #include "xkbsrv.h"
#include "xkbstr.h" #include "xkbstr.h"
#ifdef XF86BIGFONT
#define _XF86BIGFONT_SERVER_
#include <X11/extensions/xf86bigfont.h>
#endif
#ifdef DPMSExtension #ifdef DPMSExtension
#define DPMS_SERVER #define DPMS_SERVER
#include <X11/extensions/dpms.h> #include <X11/extensions/dpms.h>
@ -356,35 +351,24 @@ xf86InterceptSigIll(void (*sigillhandler)(void))
} }
/* /*
* xf86SigHandler -- * xf86SigWrapper --
* Catch unexpected signals and exit or continue cleanly. * Catch unexpected signals and exit or continue cleanly.
*/ */
void int
xf86SigHandler(int signo) xf86SigWrapper(int signo)
{ {
if ((signo == SIGILL) && xf86SigIllHandler) { if ((signo == SIGILL) && xf86SigIllHandler) {
(*xf86SigIllHandler)(); (*xf86SigIllHandler)();
/* Re-arm handler just in case we unexpectedly return here */ return 0; /* continue */
(void) signal(signo, xf86SigHandler);
return;
} }
if (xf86SignalIntercept && (*xf86SignalIntercept < 0)) { if (xf86SignalIntercept && (*xf86SignalIntercept < 0)) {
*xf86SignalIntercept = signo; *xf86SignalIntercept = signo;
/* Re-arm handler just in case */ return 0; /* continue */
(void) signal(signo, xf86SigHandler);
return;
} }
signal(signo,SIG_IGN);
xf86Info.caughtSignal = TRUE; xf86Info.caughtSignal = TRUE;
#ifdef XF86BIGFONT return 1; /* abort */
XF86BigfontCleanup();
#endif
xorg_backtrace();
FatalError("Caught signal %d. Server aborting\n", signo);
} }
/* /*

View File

@ -380,23 +380,25 @@ InstallSignalHandlers(void)
*/ */
xf86Info.caughtSignal=FALSE; xf86Info.caughtSignal=FALSE;
if (!xf86Info.notrapSignals) { if (!xf86Info.notrapSignals) {
signal(SIGSEGV,xf86SigHandler); OsRegisterSigWrapper(xf86SigWrapper);
signal(SIGILL,xf86SigHandler); } else {
signal(SIGSEGV, SIG_DFL);
signal(SIGILL, SIG_DFL);
#ifdef SIGEMT #ifdef SIGEMT
signal(SIGEMT,xf86SigHandler); signal(SIGEMT, SIG_DFL);
#endif #endif
signal(SIGFPE,xf86SigHandler); signal(SIGFPE, SIG_DFL);
#ifdef SIGBUS #ifdef SIGBUS
signal(SIGBUS,xf86SigHandler); signal(SIGBUS, SIG_DFL);
#endif #endif
#ifdef SIGSYS #ifdef SIGSYS
signal(SIGSYS,xf86SigHandler); signal(SIGSYS, SIG_DFL);
#endif #endif
#ifdef SIGXCPU #ifdef SIGXCPU
signal(SIGXCPU,xf86SigHandler); signal(SIGXCPU, SIG_DFL);
#endif #endif
#ifdef SIGXFSZ #ifdef SIGXFSZ
signal(SIGXFSZ,xf86SigHandler); signal(SIGXFSZ, SIG_DFL);
#endif #endif
} }
} }

View File

@ -147,7 +147,7 @@ extern _X_EXPORT void DoShowOptions(void);
/* xf86Events.c */ /* xf86Events.c */
extern _X_EXPORT void xf86Wakeup(pointer blockData, int err, pointer pReadmask); 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 void xf86HandlePMEvents(int fd, pointer data);
extern _X_EXPORT int (*xf86PMGetEventFromOs)(int fd,pmEvent *events,int num); extern _X_EXPORT int (*xf86PMGetEventFromOs)(int fd,pmEvent *events,int num);
extern _X_EXPORT pmWait (*xf86PMConfirmEventToOs)(int fd,pmEvent event); extern _X_EXPORT pmWait (*xf86PMConfirmEventToOs)(int fd,pmEvent event);

View File

@ -228,8 +228,10 @@ extern _X_EXPORT char *XNFprintf(const char *fmt, ...);
extern _X_EXPORT char *XNFvprintf(const char *fmt, va_list va); extern _X_EXPORT char *XNFvprintf(const char *fmt, va_list va);
typedef void (*OsSigHandlerPtr)(int /* sig */); typedef void (*OsSigHandlerPtr)(int /* sig */);
typedef int (*OsSigWrapperPtr)(int /* sig */);
extern _X_EXPORT OsSigHandlerPtr OsSignal(int /* sig */, OsSigHandlerPtr /* handler */); extern _X_EXPORT OsSigHandlerPtr OsSignal(int /* sig */, OsSigHandlerPtr /* handler */);
extern _X_EXPORT OsSigWrapperPtr OsRegisterSigWrapper(OsSigWrapperPtr newWrap);
extern _X_EXPORT int auditTrailLevel; extern _X_EXPORT int auditTrailLevel;

View File

@ -98,6 +98,10 @@ OR PERFORMANCE OF THIS SOFTWARE.
#define getpid(x) _getpid(x) #define getpid(x) _getpid(x)
#endif #endif
#ifdef XF86BIGFONT
#define _XF86BIGFONT_SERVER_
#include <X11/extensions/xf86bigfont.h>
#endif
#ifdef DDXOSVERRORF #ifdef DDXOSVERRORF
void (*OsVendorVErrorFProc)(const char *, va_list args) = NULL; void (*OsVendorVErrorFProc)(const char *, va_list args) = NULL;
@ -401,6 +405,9 @@ void AbortServer(void) __attribute__((noreturn));
void void
AbortServer(void) AbortServer(void)
{ {
#ifdef XF86BIGFONT
XF86BigfontCleanup();
#endif
CloseWellKnownConnections(); CloseWellKnownConnections();
OsCleanup(TRUE); OsCleanup(TRUE);
CloseDownDevices(); CloseDownDevices();

View File

@ -54,6 +54,8 @@ SOFTWARE.
#include "os.h" #include "os.h"
#include "osdep.h" #include "osdep.h"
#include <X11/Xos.h> #include <X11/Xos.h>
#include <signal.h>
#include <errno.h>
#include "dixstruct.h" #include "dixstruct.h"
@ -88,6 +90,58 @@ int limitStackSpace = -1;
int limitNoFile = -1; int limitNoFile = -1;
#endif #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 void
OsInit(void) OsInit(void)
{ {
@ -97,6 +151,35 @@ OsInit(void)
char fname[PATH_MAX]; char fname[PATH_MAX];
if (!been_here) { 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__) #if !defined(__SCO__) && !defined(__CYGWIN__) && !defined(__UNIXWARE__)
fclose(stdin); fclose(stdin);
fclose(stdout); fclose(stdout);