235 lines · 8.2 KB · Text
RawDownload
= debug: process debugging     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);    Debug  is  the  module  interface to the debugging facilitiesprovided by prog(3).  It allows facilities for inspection  ofa  program's  data structures, as it is running, and to startand stop a running program under program control.  Init  mustbe  called  before  any  other function to initialise debug'sglobal state. Startprog starts up a program under control of the debug mod‐ule.   Dis  is  the  full  pathname of the Dis module to load(which must be compatible with command(2); dir is the currentdirectory  in which to put the new process; ctxt and argv arethe arguments given to the new process.  Startprog returns  atuple  (prog, err)  where prog can be used to interrogate andcontrol the running process, as detailed below, unless  thereis an error, in which case prog will be nil, and err containsa description of the error.  Prog is  similar  to  startprog,except that it attaches to an already running process identi‐fied by pid.    Controlling a processA Prog  adt  provides  routines  for  controlling  a  runningprocess.   It implements the following routines.  Unless oth‐erwise stated, they return nil on success  and  a  diagnosticstring on error. prog.cont()          Run the program until a break point is reached. prog.delbpt(dis, pc)          Delbpt  deletes  the  breakpoint  in the Dis module          with filename dis at Dis instruction pc. prog.event()          Event waits for a state transition in  the  running          prog  and  returns  the new state, as returned by a          read of the dbgctl file (see prog(3)). prog.grab()          Grab stops the prog and puts it into a state  where          single stepping is possible. prog.kill()          Kill kills prog. prog.setbpt(dis, pc)          Setbpt  sets  a  breakpoint  in the Dis module with          filename dis at Dis instruction pc. prog.stack()          Stack returns a tuple (exps, err) where exps is  an          array  of  Exp adts, each representing one frame of          the current execution stack of prog.  If  an  error          occurs,  exps  will  be nil, and err will contain a          description of the error. prog.start()          Start runs prog  until  it  hits  a  breakpoint  or          exits. prog.status()          Status  returns a tuple (pgrp, user, state, module)          where pgrp is the process group id of prog, user is          the  owner  of  the  process,  state is the current          state of the process,  and  module  is  the  module          implementation name of the currently executing mod‐          ule. prog.step(how)          Step steps prog forward in a  manner  specified  by          how, which is one of the following constants:           StepExp                 Step one expression evaluation.           StepStmt                 Step one source statement.           StepOver                 Step over one called function.           StepOut                 Step   until   the   current   function  has                 returned. prog.stop()          Stop prog from running. prog.unstop()          Release a program from its  stopped  state;  break‐          points will no longer be triggered.    Inspecting dataThe  Exp  adt  provides  facilities  for  inspecting the datastructures of a running Dis  process.   A  hierarchical  datastructure  can  be  expanded  into  an array of its componentExps, as long as the appropriate symbol information has  beenlocated correctly using stdsym or addsym, and findsym. A  Pos  represents a position in a Limbo source code file; itholds the source file name, the line number  (origin  1)  andthe character within the line (origin 0).  The Src adt repre‐sents a range in a Limbo  source  code  file;  Src.start  andSrc.stop  represent  the  beginning and the end of the range,respectively. A Sym represents a .sbl symbol file, and is created by  call‐ing  sym(p)  where  p is the pathname of the symbol file; symreturns a tuple (sym, err), where if sym is nil, err containsan  error  message.   A  Sym  can  map between a Dis PC and asource file address, and vice versa.  For a  given  Sym  sym,sym.srctopc(src) returns the PC associated with src (or -1 onerror); sym.pctosrc converts the other way (and  returns  nilon error). Each  element  e  in  the  top  level  stack,  as returned byProg.stack, has an associated Module e.m which  needs  to  beassociated  with  a  Sym  so that debug can glean from it thetype information it needs.  Given a module m, m.stdsym() willtry and find a symbol file in a standard place, but this willfail if the symbol file or the Dis file is in a  non-standardplace.   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  symbolfiles associated with m respectively. Each  top  level  stack  element expands into three elements,``args'', ``locals'', and ``module'', representing the  argu‐ments  to  the  function, the function's local variables, andthe module-global variables of the function's module  respec‐tively.  Before a top level stack element can be expanded, itis necessary to call findsym on it to locate  the  function'sdata. exp.name  The name of the symbol. exp.expand()          Expand  a  hierarchical  structure into an array of          its component elements. A list element expands into          two  elements named ``hd'' and ``tl''; a tuple into          elements named ``t0'', ``t1'',...,  an  array  into          elements named ``0'', ``1'',..., etc. exp.val() Val  returns  a tuple (s, flag) where s is a string          representation of the value of exp, and if flag  is          zero, exp cannot be expanded. exp.src() Src returns the file range associated with exp. exp.findsym()          If  exp is a top level stack frame (i.e. one of the          members of the array returned by  Prog.stack)  then          findsym  will  attempt to locate its type and name.          If it succeeds, it returns the null string,  other‐          wise it returns an error indicating the problem. exp.srcstr()          Srcstr  returns  a string representing the position          in the source file of exp. == files/prog/pid/* == source/appl/lib/debug.b == see ALSOwm-deb(1), prog(3) == bugsThere is  no  way  of  looking  at  the  types  of  the  dataextracted.