<> <> <> <> <> DIRECTORY AMModel USING [ Section ], AMTypes USING [ TV ], Rope USING [ ROPE ], WorldVM USING [ Address, World ]; AMEvents: DEFINITIONS = BEGIN OPEN AMModel, AMTypes, Rope, WorldVM; EventProc: TYPE = PROC [data: REF ANY, event: Event] RETURNS [outcome: Outcome]; <<"data" is as passed to "GetEvents". An EventProc is called whenever something interesting happens in the client world. Returning from the event allows the client process to proceed, as specified by outcome.type:>> < raise ABORTED in victim process>> < depending on the event.type:>> < execute saved byte and continue (result=NIL)>> < return from the call (result=NIL)>> < RESUME[result]>> < redo the call that caused specified local frame, with given arguments.>> < return control from specified local frame, with given result.>> Event: TYPE = REF EventRec; Eventuality: TYPE = { break, call, signal, unknown }; EventRec: TYPE = RECORD[ world: World _ NIL, -- world requesting the debugger session: INT _ 0, -- monotonic, incremented at StopEvents or when world boots process: TV _ NIL, -- process requesting the debugger frame: TV _ NIL, -- local frame requesting the debugger worry: BOOL _ FALSE, -- TRUE => don't try to call client procedures detail: SELECT type: Eventuality FROM break => [id: BreakID, clientData: REF ANY], call => [msg: ROPE], signal => [signal, args: TV ], unknown => [why: ROPE], -- client bug; psbi and frame are valid. ENDCASE]; Outcome: TYPE = RECORD[ SELECT type: * FROM proceed => [result: TV], quit => NULL, retry => [frame, result: TV], returnFrom => [frame, result: TV], ENDCASE] _ [proceed[NIL]]; GetEvents: PROC [world: World, data: REF ANY, proc: EventProc]; StopEvents: PROC [world: World]; Debugging: --INFORMATIONAL-- SIGNAL; Debugged: --INFORMATIONAL-- SIGNAL; <<"Debugging" is raised in a process when it is about to be suspended for an event -->> <<"Debugged" is raised in a process when the EventProc returns -->> <> <> BootedNotifier: TYPE = PROC [world: World, session: INT, clientData: REF]; <> RegisterBootedNotifier: PROC [proc: BootedNotifier, world: World _ NIL, clientData: REF _ NIL]; <> UnRegisterBootedNotifier: PROC [proc: BootedNotifier, world: World _ NIL, clientData: REF _ NIL]; <> <> WorldSwapLocalSignals: PROC [BOOL]; <> <> CallDebugger: PROC [msg: ROPE]; <> <> <> ProvokeProcessEvent: PROC [p: TV, frame: TV, msg: ROPE] RETURNS [outcome: Outcome]; <<... causes a "call" event with the given message to appear as if from the given frame in the given process. This is used by AMProcess to force the debugger's attention to a given frame.>> <> <> BreakID: TYPE = REF BreakRec; BreakRec: TYPE; DuplicateBreakpoint: ERROR; BreakAt: PROC [world: World, section: Section, clientData: REF ANY] RETURNS [id: BreakID]; <> BreakAfter: PROC [world: World, section: Section, clientData: REF ANY] RETURNS [id: BreakID]; <> FrameBreak: PROC [gf: TV, pc: CARDINAL, clientData: REF ANY] RETURNS [id: BreakID]; <> SetBreak: PROC [world: World, addr: Address, pc: CARDINAL, clientData: REF ANY] RETURNS [id: BreakID]; <> ClearBreak: PROC [id: BreakID]; NextBreak: PROC [world: World, prev: BreakID] RETURNS [id: BreakID, clientData: REF ANY]; <> <> Apply: PROC [control, args: TV] RETURNS [result: TV]; <<"control" may have class "procedure", "signal" or "error", corresponding to procedure calls or raising a signal or error. Error's are treated the same as signals. This may raise BadControlLink, BadArgType, BadResStack or EndSession.>> BadControlLink: ERROR; -- "control" had wrong type class BadArgType: ERROR; -- type of "arg" # range of type of "control" BadResStack: ERROR; -- result stack size was incorrect. EndSession: ERROR; -- debuggee was booted (or StopEvents was called) instead of returning. <> <<>> Kill: SAFE PROC [world: World]; <> Screen: SAFE PROC [world: World]; END.