Debugger.mesa
Copyright Ó 1990, 1991 by Xerox Corporation. All rights reserved.
Debugger: Carl Hauser, April 24, 1989 5:45:59 pm PDT
PreDebug: Christian Jacobi, July 20, 1990 1:04:52 pm PDT
Christian Jacobi, July 25, 1990 7:56 pm PDT
DIRECTORY
Atom,
DebuggerFixup,
PreDebug,
PreDebugPrivate,
Rope,
RuntimeError,
VM;
Debugger: CEDAR MONITOR
IMPORTS Atom, Rope, RuntimeError, VM
EXPORTS PreDebug, DebuggerFixup, PreDebugPrivate =
BEGIN OPEN PreDebug;
RaiseSignal: PROC [which: SIGANY, rtns: POINTER, args: POINTER] = TRUSTED MACHINE CODE {
"XR←RaiseSignal"
};
Raise: PUBLIC PROC [signalOrError: SIGANY, args: POINTER] = {
RaiseSignal[signalOrError, NIL, args];
};
registration: LIST OF RegRec ¬ NIL;
RegRec: TYPE = RECORD [signal: SIGANY, explain: Explainer, data: REF];
RegisterSignalExplainer: PUBLIC PROC [signal: SIGANY, explain: Explainer ¬ NIL, data: REF ¬ NIL] = {
registration ¬ CONS[[signal, explain, data], registration]
};
RegisterErrorExplainer: PUBLIC PROC [error: ERRANY, explain: Explainer ¬ NIL, data: REF ¬ NIL] = {
RegisterSignalExplainer[LOOPHOLE[error], explain, data];
};
Ropeize: PROC [x: REF] RETURNS [Rope.ROPE] = {
WITH x SELECT FROM
r: Rope.ROPE => RETURN [r];
rt: REF TEXT => RETURN [Rope.FromRefText[rt]];
ENDCASE => RETURN [NIL];
};
Explain: PUBLIC PROC [signalOrError: SIGANY, args: POINTER] RETURNS [Rope.ROPE] = {
registerData: Rope.ROPE ¬ NIL;
FOR l: LIST OF RegRec ¬ registration, l.rest WHILE l#NIL DO
IF l.first.signal=signalOrError THEN {
IF l.first.explain#NIL THEN RETURN[l.first.explain[signalOrError, args, l.first.data]];
registerData ¬ Ropeize[l.first.data];
EXIT
};
ENDLOOP;
SELECT TRUE FROM
registerData#NIL => RETURN [registerData];
ENDCASE => RETURN ["unknown error"];
};
Protect: PUBLIC PROC [inner: PROC, rejectP: PROC [Rope.ROPE] RETURNS [BOOL]] RETURNS [ok: BOOL ¬ TRUE] = {
inner[! RuntimeError.UNCAUGHT => TRUSTED {
explanation: Rope.ROPE;
explanation ¬ Explain[signal, LOOPHOLE[parameters]];
IF rejectP[explanation] THEN REJECT ELSE {ok ¬ FALSE; CONTINUE}
}];
};
lastMessage: Rope.ROPE ¬ NIL;
IJustToldTheUser: PUBLIC PROC [msg: Rope.ROPE] = {
lastMessage ¬ msg
};
LastMessage: PUBLIC PROC [] RETURNS [Rope.ROPE] = {
RETURN [lastMessage]
};
SystemPutRope: PUBLIC ENTRY PROC [r: Rope.ROPE] = {
ENABLE UNWIND => NULL;
PutChar: PROC [c: CHAR] RETURNS [] ~ TRUSTED MACHINE CODE {
"XR�ugPutChar"
};
FOR i: INT IN [0..Rope.Length[r]) DO
PutChar[Rope.Fetch[r, i]]
ENDLOOP;
};
MyUncaughtHandler: RuntimeError.UCSProc = {
explanation: Rope.ROPE;
explanation ¬ Explain[signal, LOOPHOLE[msg]];
IF Rope.Length[explanation]>50 AND Rope.Equal[explanation, LastMessage[]] THEN {
explanation ¬ Rope.Replace[base: explanation, start: 40, with: " ... "];
};
SystemPutRope[Rope.Cat["\n*** Uncaught error: ", explanation, "\n"]];
--IF oldUncaughtHandler#NIL
--THEN oldUncaughtHandler[msg, signal, frame]
--ELSE {
IF signal # LOOPHOLE[RuntimeError.Aborted] THEN {
Debug[];
If control returns here, raise ABORTED then exit
ERROR ABORTED;
};
ExitThread[];
--};
};
Debug: PUBLIC PROC [] = {
TryCallDebugger: PROC ~ TRUSTED MACHINE CODE {
"XR�llDebugger"
};
DoProcs[start];
TryCallDebugger[];
DoProcs[stop];
};
ExitThread: PUBLIC PROC ~ {
Exit: PROC ~ TRUSTED MACHINE CODE {
"XR𡤎xit"
};
Exit[]
};
RegisterInterest: PUBLIC ENTRY PROC [startDebugging, stopDebugging: DebuggerFixup.InterestProc, data: REF] ~ {
interests ¬ CONS[ [startDebugging, stopDebugging, data], interests];
};
DoProcs: PROC [action: {start, stop}] ~ {
FOR l: LIST OF Interest ¬ interests, l.rest WHILE l # NIL DO
IF action=start THEN l.first.start[l.first.data] ELSE l.first.stop[l.first.data]
ENDLOOP;
};
interests: LIST OF Interest ¬ NIL;
Interest: TYPE = RECORD [start, stop: DebuggerFixup.InterestProc, data: REF];
oldUncaughtHandler: RuntimeError.UCSProc ¬ NIL;
Init: PROC [] = {
RegisterErrorExplainer[RuntimeError.Aborted, NIL, "Aborted"];
RegisterErrorExplainer[RuntimeError.AbstractionFault, NIL, "ArithmeticFault"];
RegisterErrorExplainer[RuntimeError.ArithmeticFault, NIL, "ArithmeticFault"];
RegisterErrorExplainer[RuntimeError.AssignRefCompositeFault, NIL, "AssignRefCompositeFault"];
RegisterErrorExplainer[RuntimeError.BoundsFault, NIL, "BoundsFault"];
RegisterErrorExplainer[RuntimeError.DivideCheck, NIL, "DivideCheck"];
RegisterErrorExplainer[RuntimeError.LinkageFault, NIL, "LinkageFault"];
RegisterErrorExplainer[RuntimeError.NarrowFault, NIL, "NarrowFault"];
RegisterErrorExplainer[RuntimeError.NarrowRefFault, NIL, "NarrowRefFault"];
RegisterErrorExplainer[RuntimeError.NestedProcFault, NIL, "NestedProcFault"];
RegisterErrorExplainer[RuntimeError.NilFault, NIL, "NilFault"];
RegisterErrorExplainer[RuntimeError.ResumeFault, NIL, "ResumeFault"];
RegisterErrorExplainer[RuntimeError.StackFault, NIL, "StackFault"];
RegisterErrorExplainer[RuntimeError.StartFault, NIL, "StartFault"];
RegisterErrorExplainer[RuntimeError.Uncaught, NIL, "Uncaught"];
RegisterErrorExplainer[RuntimeError.UnnamedError, NIL, "UnnamedError"];
RegisterErrorExplainer[RuntimeError.UnnamedSignal, NIL, "UnnamedSignal"];
RegisterErrorExplainer[RuntimeError.Unwind, NIL, "Unwind"];
RegisterErrorExplainer[RuntimeError.UnwindFault, NIL, "UnwindFault"];
RegisterErrorExplainer[RuntimeError.ZeroDivisor, NIL, "ZeroDivisor"];
RegisterSignalExplainer[RuntimeError.UnboundProcedureFault, NIL, "UnboundProcedureFault"];
RegisterSignalExplainer[RuntimeError.SendMsg, NIL, "SendMsg"];
RegisterErrorExplainer[Atom.NILNotAnAtom, NIL, "NILNotAnAtom"];
RegisterErrorExplainer[Rope.NoRope, NIL, "NoRope"];
RegisterErrorExplainer[Rope.VerifyFailed, NIL, "Rope.VerifyFailed"];
RegisterErrorExplainer[VM.AddressFault, NIL, "VM.AddressFault"];
RegisterErrorExplainer[VM.WriteProtectFault, NIL, "VM.WriteProtectFault"];
IF oldUncaughtHandler=NIL THEN
oldUncaughtHandler ¬ RuntimeError.RegisterUncaughtSignalHandler[MyUncaughtHandler];
};
Init[];
END.