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]; 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; 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]; 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]; 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. AMEvents.mesa - interactions with client Copyright c 1985 by Xerox Corporation. All rights reserved. Andrew Birrell September 20, 1983 3:25 pm Paul Rovner July 20, 1983 12:42 am Russ Atkinson (RRA) February 11, 1985 11:35:14 pm PST "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: quit => raise ABORTED in victim process proceed => depending on the event.type: breakpoints => execute saved byte and continue (result=NIL) explicit call => return from the call (result=NIL) signals => RESUME[result] retry => redo the call that caused specified local frame, with given arguments. returnFrom => return control from specified local frame, with given result. "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 -- NOTE: These are raised as "informational" signals: clients may catch them, but must not jump out of their catch-phrase. The signaller will resume them. registered "BootedNotifiers" are called at end of a client session. This occurs when StopEvents is called for that world, or when AMEventsImpl notices that the debuggee has been booted. All events for which "session" is <= the given "session" should return (their result will be ignored). At end of session, all outstanding calls of "Apply" for that debuggee are terminated by raising the "EndSession" signal. worldName = NIL causes proc to be called for all booted events clientData = NIL implies wildcard match on clientData ditto for world Iff the last call of this procedure has argument "TRUE", signals in the local world will be sent to the world-swap debugger instead of being reported locally. Cause a local "call" event. If someone is handling local events, this will debug without a world-swap, otherwise it will world-swap. Note that DebuggerSwap.CallDebugger will always cause a world-swap. ... 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. Breakpoints Multiple breaks at one place are illegal. Sets breakpoint at beginning of the section (statement or procedure). Sets breakpoint at end of the section (procedure only). OctalBreak(1): Sets breakpoint at specified byte relative to "gf"s codebase -- OctalBreak(2): Sets breakpoint at specified byte. "addr" is typically a codebase. Enumerator for breakpoints. Starts and ends with NIL. Returns the currently set breakpoints in most-recent-first order. If "world" is NIL, returns breakpoint in any world. Procedure invocation "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. Other stuff Currently, calls TemporaryBooting.BootButton[] in client world. ʘcodešœ(™(Kšœ Ïmœ1™™>—K˜š ¡œžœ'žœžœžœ˜ašœ5™5Kšœ™—K˜—šŸœžœžœ˜#KšœS™SKšœJ™JK˜—šŸ œžœžœ˜KšœY™YKšœU™UKšœ™K˜—š Ÿœžœžœ žœžœžœ˜SK™ºK˜—šœ ™ K˜Kšœ)™)K˜Kšœ žœžœ ˜K˜Kšœ žœ˜K˜Kšœžœ˜K˜š Ÿœžœ.žœžœžœ˜ZKšœE™EK˜—š Ÿ œžœ.žœžœžœ˜]Kšœ7™7K˜—šŸ œžœžœžœžœžœžœ˜SKšœN™NK˜—š Ÿœžœ#žœžœžœžœ˜fKšœR™RK˜—KšŸ œžœ˜K˜š Ÿ œžœžœžœžœ˜YKšœ2žœTžœ"™®—K˜—Kšœ™˜š Ÿœžœžœžœ žœ˜5Kšœê™êK˜—Kšœžœ !˜8Kšœ žœ -˜@Kšœ žœ #˜7Kšœ žœ G˜ZK˜—™ K™šŸœžœžœ˜Kšœ?™?—K˜KšŸœžœžœ˜!K˜—Kšžœ˜K˜—…— \x