<<>> <> <> <> <> <> <<>> <<>> 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_CallDebugger" }; 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; <> NoMap: WORD ~ 3; Prot: WORD ~ 4; UndecodableTrap: ERROR ~ CODE; XRThread: TYPE ~ POINTER; UnixHandler: PROC [handlee: XRThread, which: WORD, arg: POINTER] ~ TRUSTED { <> 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 [] ~ { <> ERROR ThreadStackOverflowed[process]; }; RipVanWinkle: PROC [] RETURNS [] ~ { <> 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.