UnixTrapToMesaErrorImpl.mesa
Copyright Ó 1989, 1991 by Xerox Corporation. All rights reserved.
Carl Hauser, April 24, 1989 3:42:59 pm PDT
Chauser, September 25, 1990 11:42 am PDT
Michael Plass, August 12, 1991 5:42 pm PDT
DIRECTORY
PreDebug,
Process,
RuntimeError,
UnixTypes,
VM;
UnixTrapToMesaErrorImpl: CEDAR MONITOR
IMPORTS PreDebug, Process, VM
~ BEGIN
RegisterHandler: PROC [handler: WORD] ~ TRUSTED MACHINE CODE {
"XR←RegisterHandler"
};
CallDebugger: PROC [] ~ TRUSTED MACHINE CODE {
"XR�llDebugger"
};
ProcDescPtr: TYPE ~ POINTER TO RECORD [
func: WORD, context: WORD
];
TrapArgs: TYPE ~ MACHINE DEPENDENT RECORD [
sig: INT,
code: INT,
scp: POINTER,
addr: POINTER
];
WhichTrapUnixFatal: WORD ~ 3;
WhichTrapUnix: WORD ~ 2;
WhichTrapFatalStackOverflow: WORD ~ 1023;
Copied from /usr/include/vm/faultcode.h
NoMap: WORD ~ 3;
Prot: WORD ~ 4;
UndecodableTrap: ERROR ~ CODE;
XRThread: TYPE ~ POINTER;
UnixHandler: PROC [handlee: XRThread, which: WORD, arg: POINTER] ~ TRUSTED {
must correspond in type to XR←HandlerProc in Threads.h
SELECT which FROM
WhichTrapUnix, WhichTrapUnixFatal => DecodeTrap[LOOPHOLE[arg]];
WhichTrapFatalStackOverflow => TRUSTED {
Process.Detach[ FORK NotifyStackOverflow[Process.GetCurrent[]] ];
RipVanWinkle[];
};
ENDCASE => ERROR;
};
ThreadStackOverflowed: ERROR[ process: PROCESS ] ~ CODE;
NotifyStackOverflow: PROC [process: PROCESS] RETURNS [] ~ {
The error is raised in a separate thread because by definition there is no space on the overflowed stack. The main reason for raising an error at all is to allow the automatic resource-release for debugging that an uncaught error provokes. There isn't any point in catching this error explicitly.
ERROR ThreadStackOverflowed[process];
};
RipVanWinkle: PROC [] RETURNS [] ~ {
sleep forever; this thread is not recoverable; maybe someday it will be possible to UNWIND it, but since there's very little stack space available here it is, to say the least, delicate.
DO CallDebugger[]; ENDLOOP;
};
DecodeTrap: PROC [trapInfo: POINTER TO TrapArgs] ~ TRUSTED {
sig: UnixTypes.Signal ¬ LOOPHOLE[trapInfo.sig];
SELECT sig FROM
SIGSEGV => SELECT trapInfo.code FROM
NoMap => ERROR VM.AddressFault[trapInfo.addr];
Prot => ERROR VM.WriteProtectFault[trapInfo.addr];
ENDCASE => ERROR UndecodableTrap;
ENDCASE => ERROR UndecodableTrap;
};
TRUSTED { RegisterHandler[LOOPHOLE[UnixHandler, ProcDescPtr].func] };
PreDebug.RegisterErrorExplainer[ThreadStackOverflowed, NIL, "Thread stack overflow occurred in some thread."];
END.