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
#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

View File

@ -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 */
}
/*

View File

@ -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
}
}

View File

@ -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);

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);
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;

View File

@ -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();

View File

@ -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);