home *** CD-ROM | disk | FTP | other *** search
-
- /* C O P Y R I G H T N O T I C E : */
- /* Copyright 1986 Eric Jul and Norm Hutchinson. May not be used for any */
- /* purpose without written permission from the authors. */
-
- /* Emerald handler to catch bad ULTRIX signals. */
- /* If the signal is in user code then fail the current process else */
- /* crash the kernel. */
-
- /* EXPORTS: EmBadSignal */
-
- /* Author: Eric Jul, November 1986 */
-
- #include <signal.h>
- #include <stdio.h>
- #include "Kernel/h/kEvents.h"
- #include "Kernel/h/kmdTypes.h"
- #include "Kernel/h/emTypes.h"
- #include "Kernel/h/utils.h"
- #include "Kernel/h/system.h"
-
- extern int perror();
- extern int etext;
- extern char * sbrk();
-
- extern int BadSigJumpPoint; /* in kernel stub */
- extern unsigned int BadSigPC; /* in kernel stub */
- extern SSPtr currentSSP, preemptRunning();
- extern void dofail();
- extern void shutdownOID();
-
- /**********************************************************************/
- /* EmBadSignal */
- /**********************************************************************/
- /* ought to be void*/
- EmBadSignal(fSig, fCode, fContext)
- int fSig;
- int fCode;
- struct sigcontext *fContext;
- /* For param description, see sigvec(2), ULTRIX manual */
- {
- unsigned int limit = (unsigned int) sbrk(0);
- struct sigvec vec; /* used in sigvec() calls */
-
- KMDTrace("Failure", 3, "BadSignal(%d), Code = %d, IP = 0x%04x\n", fSig,
- fCode, fContext->sc_pc);
-
- BadSigPC = (unsigned int) fContext->sc_pc;
- if (
- NonNULL(currentSSP)
- && (((unsigned int) fContext->sc_pc) > (unsigned int) (&etext))
- && (((unsigned int) fContext->sc_pc) < limit)) {
- /* it was in the user area, fail it */
- /* We force the failure by setting the pc to an address in the
- kernel stub which forces a kernel call */
- KMDTrace("Failure", 3, "Failing process\n");
- fContext->sc_pc = (int) &BadSigJumpPoint;
- return;
- } else {
- /* It was an error in either the Emerald compiler or the
- * Emerald kernel, so die.
- * To die, remove the signal handler and redo the offending
- * instruction as to cause UNIX to core dump with the
- * system in the appropriate place and with the appropriate
- * stack.
- */
- ErrMsg( "Cannot handle BadSignal(%d), Code = %d, IP = 0x%04x\n", fSig,
- fCode, fContext->sc_pc);
-
- /* Emergency shutdown on bad signal -- kernel broken */
- HoldSigs(); /* Watch out for this */
- #ifdef BSD
- (void) fflush(stdout);
- (void) fflush(stderr);
- #endif
- printf("**** Signal no. %d arrived -- starting crash termination.\n", fSig);
-
- SendShutDownMsg(GetLNN());
-
- shutdownOID();
-
- vec.sv_handler = SIG_DFL;
- vec.sv_mask = 0; /* All signals enabled */
- vec.sv_onstack = 0; /* Use main stack */
- #ifdef xkernel
- #else
- if (sigvec(fSig, &vec, 0) < 0) {
- perror("BadSignal:sigvec");
- }
- (void) sigsetmask(0);
- #endif
- /* Now return and UNIX will do a core dump */
- return;
- }
- }
- /************************************************************************/
- /* Kernel call */
- void BadSignalOccurred()
- /* called from the kernel stub when a process has received a bad signal */
- /* the call looks like it was performed by the offending instruction, i.e.,
- the IP points to the next instruction */
- {
- KMDTrace("Failure", 3, "Recovering from a bad signal\n");
- if (IsNIL(currentSSP->regs.g) || (IsNIL(currentSSP->regs.b))) {
- /* This was the problem */
- KMDTrace("Failure", 3, "NIL invoked: propagating failure\n");
- dofail(preemptRunning(), TRUE);
- return;
- }
-
- KMDTrace("Failure", 3, "Bad reference in %s\n", PPSSPlace(currentSSP));
- dofail(preemptRunning(), FALSE);
- }
-