SpyBreaksImpl.mesa
Copyright Ó 1990, 1991, 1992 by Xerox Corporation. All rights reserved.
Michael Plass, September 22, 1992 1:10 pm PDT
Willie-s, May 19, 1992 2:55 pm PDT
DIRECTORY Breakpoint, BreakWorldArchitecture, Commander, CommanderOps, Convert, FakeCirio, IO, Spy, Rope, TargetArchitecture;
SpyBreaksImpl: CEDAR PROGRAM
IMPORTS Breakpoint, BreakWorldArchitecture, Commander, CommanderOps, Convert, FakeCirio, IO, Spy, Rope
EXPORTS ExportsList
~ BEGIN
ROPE: TYPE ~ Rope.ROPE;
SpyTraceBreakProcedure: PROCEDURE ~ {
Spy.SampleMyStack[];
};
nameSpyTraceBreakProc: ROPE ~ "←SpyTraceBreakProcedure←P60";
breakWorld: BreakWorldArchitecture.BreakWorld ~
BreakWorldArchitecture.CreateBreakWorld[
name: "SPARC",
peekContents: FakeCirio.PeekContents,
pokeContents: FakeCirio.PokeContents,
getProcAddress: FakeCirio.GetProcAddress,
getProcDataSegment: FakeCirio.GetProcDataSegment,
getPatchArea: FakeCirio.GetPatchArea,
monitoredCall: FakeCirio.MonitoredCall,
worldAccessData: NIL];
Fail: PROC [msg: ROPE] ~ {
Spy.SampleMyStack[]; -- for debug when can't set breaks.
CommanderOps.Failed[msg];
};
breaks: LIST OF Breakpoint.Break ¬ NIL;
SpySetTraceBreakCommand: Commander.CommandProc ~ {
ENABLE {
FakeCirio.Cant => Fail[Rope.Concat["FakeCirio.Cant: ", message]];
Breakpoint.CantSet => Fail[Rope.Concat["Breakpoint.CantSet: ", message]];
Breakpoint.Cant => Fail[Rope.Concat["Breakpoint.Cant: ", message]];
BreakWorldArchitecture.Cant => Fail[Rope.Concat["BreakWorldArchitecture.Cant: ", message]];
Convert.Error => Fail["Illegal offset specified"];
};
arg: ROPE ~ CommanderOps.NextArgument[cmd];
IF arg # NIL AND CommanderOps.NextArgument[cmd] = NIL THEN {
toSign: INT ~ Rope.SkipTo[arg, 0, "+-"];
procName: ROPE ~ Rope.Substr[arg, 0, toSign];
offset: INT ~ IF toSign = Rope.Size[arg] THEN 0 ELSE Convert.IntFromRope[Rope.Substr[arg, toSign]];
breakpointBaseAddress: BreakWorldArchitecture.Address ~ IF Rope.Size[procName] # 0 THEN FakeCirio.GetProcAddress[
breakWorld: breakWorld, procName: procName] ELSE BreakWorldArchitecture.nullAddress;
breakpointAddress: BreakWorldArchitecture.Address ~ BreakWorldArchitecture.AddressFromDisplacement[breakpointBaseAddress, offset];
breakProcedureAddress: BreakWorldArchitecture.Address ~ FakeCirio.GetProcAddress[
breakWorld: breakWorld, procName: nameSpyTraceBreakProc];
break: Breakpoint.Break ¬ Breakpoint.SetBreakpoint[
address: breakpointAddress, clientData: NIL,
breakProc: breakProcedureAddress, breakData: 0];
breaks ¬ CONS[break, breaks];
{
address: TargetArchitecture.Address ~ Breakpoint.AddressFromBreak[break].address;
IO.PutF1[cmd.out, "Break set at pc=0%08xH\n", [cardinal[LOOPHOLE[address]]]];
RETURN;
};
};
CommanderOps.Failed[cmd.procData.doc];
};
cantClear: Breakpoint.Break ¬ NIL;
SpyClearTraceBreaksCommand: Commander.CommandProc ~ {
ENABLE {
FakeCirio.Cant => Fail[Rope.Concat["FakeCirio.Cant: ", message]];
Breakpoint.CantClear => Fail[Rope.Concat["Breakpoint.CantClear: ", message]];
Breakpoint.Cant => Fail[Rope.Concat["Breakpoint.Cant: ", message]];
BreakWorldArchitecture.Cant => Fail[Rope.Concat["BreakWorldArchitecture.Cant: ", message]];
};
IF cantClear # NIL THEN {
IF breaks = NIL
THEN breaks ¬ LIST[cantClear]
ELSE FOR tail: LIST OF Breakpoint.Break ¬ breaks, tail.rest DO
IF tail.rest = NIL THEN {tail.rest ¬ LIST[cantClear]; EXIT};
ENDLOOP;
cantClear ¬ NIL;
};
UNTIL breaks = NIL DO
break: Breakpoint.Break ¬ breaks.first;
cantClear ¬ break;
breaks ¬ breaks.rest;
{ address: TargetArchitecture.Address ~ Breakpoint.AddressFromBreak[break].address;
IO.PutF1[cmd.out, "Clearing break at pc=0%08xH ...", [cardinal[LOOPHOLE[address]]]];
};
Breakpoint.ClearBreakpoint[cantClear];
cantClear ¬ NIL;
IO.PutRope[cmd.out, "Ok.\n"];
ENDLOOP;
};
Commander.Register[
key: "SpySetTraceBreak", proc: SpySetTraceBreakCommand,
doc: "<cprocname> - set a spy trace break"];
Commander.Register[
key: "SpyClearBreaks", proc: SpyClearTraceBreaksCommand,
doc: "Clear all spy breaks"];
END.