include "debug.m"; debug := load Debug Debug->PATH; Pos: adt { file: string; line: int; pos: int; }; Src: adt { start: Pos; # range within source files stop: Pos; }; Sym: adt { srctopc: fn(s: self ref Sym, src: ref Src): int; pctosrc: fn(s: self ref Sym, pc: int): ref Src; }; Module: adt { addsym: fn(m: self ref Module, sym: ref Sym); stdsym: fn(m: self ref Module); dis: fn(m: self ref Module): string; sbl: fn(m: self ref Module): string; }; Prog: adt { cont: fn(p: self ref Prog): string; delbpt: fn(p: self ref Prog, dis: string, pc: int): string; event: fn(p: self ref Prog): string; grab: fn(p: self ref Prog): string; kill: fn(p: self ref Prog): string; setbpt: fn(p: self ref Prog, dis: string, pc: int): string; stack: fn(p: self ref Prog): (array of ref Exp, string); start: fn(p: self ref Prog): string; status: fn(p: self ref Prog): (int, string, string, string); step: fn(p: self ref Prog, how: int): string; stop: fn(p: self ref Prog): string; unstop: fn(p: self ref Prog): string; }; Exp: adt { name: string; m: ref Module; expand: fn(e: self ref Exp): array of ref Exp; val: fn(e: self ref Exp): (string, int); src: fn(e: self ref Exp): ref Src; findsym:fn(e: self ref Exp): string; srcstr: fn(e: self ref Exp): string; }; init: fn(): int; startprog: fn(dis, dir: string, ctxt: ref Draw->Context, argv: list of string): (ref Prog, string); prog: fn(pid: int): (ref Prog, string); sym: fn(sbl: string): (ref Sym, string);
Startprog starts up a program under control of the debug module. Dis is the full pathname of the Dis module to load (which must be compatible with command(2); dir is the current directory in which to put the new process; ctxt and argv are the arguments given to the new process. Startprog returns a tuple (prog, err) where prog can be used to interrogate and control the running process, as detailed below, unless there is an error, in which case prog will be nil, and err contains a description of the error. Prog is similar to startprog, except that it attaches to an already running process identified by pid.
A Pos represents a position in a Limbo source code file; it holds the source file name, the line number (origin 1) and the character within the line (origin 0). The Src adt represents a range in a Limbo source code file; Src.start and Src.stop represent the beginning and the end of the range, respectively.
A Sym represents a .sbl symbol file, and is created by calling sym(p) where p is the pathname of the symbol file; sym returns a tuple (sym, err), where if sym is nil, err contains an error message. A Sym can map between a Dis PC and a source file address, and vice versa. For a given Sym sym, sym.srctopc(src) returns the PC associated with src (or -1 on error); sym.pctosrc converts the other way (and returns nil on error).
Each element e in the top level stack, as returned by Prog.stack, has an associated Module e.m which needs to be associated with a Sym so that debug can glean from it the type information it needs. Given a module m, m.stdsym() will try and find a symbol file in a standard place, but this will fail if the symbol file or the Dis file is in a non-standard place. M.addsym(s) sets the symbol file for m to the Sym s. M.dis() and m.sbl() return the paths of the Dis and symbol files associated with m respectively.
Each top level stack element expands into three elements, ``args'', ``locals'', and ``module'', representing the arguments to the function, the function's local variables, and the module-global variables of the function's module respectively. Before a top level stack element can be expanded, it is necessary to call findsym on it to locate the function's data.
DEBUG(2 ) | Rev: Tue Mar 31 02:42:39 GMT 2015 |