next up previous contents index
Next: Low-Level Tracing Up: Debugging Previous: Debugging   Contents   Index


High-Level Tracing

XSB  supports a version of the Byrd four-port debugger for debugging Prolog code. In this release (Version 2.2), it does not work very well when debugging code involving tabled predicates. If one only creeps (see below), the tracing can provide some useful information. We do intend that future versions will have more complete debugging help for tabled evaluation.

To turn on tracing, use trace/0. To turn tracing off, use notrace/0. When tracing is on, the system will print a message each time a predicate is:

  1. initially entered (Call),
  2. successfully returned from (Exit),
  3. failed back into (Redo), and
  4. completely failed out of (Fail).
At each port, a message is printed and the tracer stops and prompts for input. (See the predicates show/1 and leash/1 described below to modify what is traced and when the user is prompted.)

In addition to single-step tracing, the user can set spy points to influence how the tracing/debugging works. A spy point is set using spy/1. Spy points can be used to cause the system to enter the tracer when a particular predicate is entered. Also the tracer allows ``leaping'' from spy point to spy point during the debugging process.

The debugger also has profiling capabilities, which can measure the cpu time spent in each call. The cpu time is measured only down to 0.0001-th of a second.

When the tracer prompts for input, the user may enter a return, or a single character followed by a return, with the following meanings:

c, <CR>: Creep
Causes the system to single-step to the next port (i.e. either the entry to a traced predicate called by the executed clause, or the success or failure exit from that clause).
a: Abort
Causes execution to abort and control to return to the top level interpreter.
b: Break
Calls the evaluable predicate break, thus invoking recursively a new incarnation of the system interpreter. The command prompt at break level $n$ is
$n$: ?-
The user may return to the previous break level by entering the system end-of-file character (e.g. ctrl-D), or typing in the atom end_of_file; or to the top level interpreter by typing in abort.
f: Fail
Causes execution to fail, thus transferring control to the Fail port of the current execution.
h: Help
Displays the table of debugging options.
l: Leap
Causes the system to resume running the program, only stopping when a spy-point is reached or the program terminates. This allows the user to follow the execution at a higher level than exhaustive tracing.
n: Nodebug
Turns off debug mode.
r: Retry (fail)
Transfers to the Call port of the current goal. Note, however, that side effects, such as database modifications etc., are not undone.
s: Skip
Causes tracing to be turned off for the entire execution of the procedure. Thus, nothing is seen until control comes back to that procedure, either at the Success or the Failure port.
q: Quasi-skip
This is like Skip except that it does not mask out spy points.
S: Verbose skip
Similar to Skip mode, but trace continues to be printed. The user is prompted again when the current call terminates with success or failure. This can be used to obtain a full trace to the point where an error occurred or for code profiling. (See more about profiling below.)
e: Exit
Causes immediate exit from XSB back to the operating system.

Other standard predicates that are useful in debugging are:

spy(Preds)

where Preds is a spy specification or a list of such specifications, and must be instantiated. This predicate sets spy points (conditional or unconditional) on predicates. A spy specification can be of several forms. Most simply, it is a term of the form $P$/$N$, where $P$ is a predicate name and $N$ its arity. Optionally, only a predicate name can be provided, in which case it refers to all predicates of any arity currently defined in usermod. It may optionally may be prefixed by a module name, e.g. $ModName$:$P$/$N$. (Again, if the arity is omitted, the specification refers to all predicates of any arity with the given name currently defined in the given module.) A spy specification may also indicate a conditional spy point. A conditional spy specification is a Prolog rule, the head indicating the predicate to spy, and the body indicating conditions under which to spy. For example, to spy the predicate p/2 when the first argument is not a variable, one would write: $spy (p(X,\_):-nonvar(X)).$ (Notice that the parentheses around the rule are necessary). The body may be empty, i.e., the rule may just be a fact. The head of a rule may also be prefixed (using $:$) with a module name. One should not put both conditional and unconditional spy points on the same predicate.

nospy(Preds)

where Preds is a spy specification, or a list of such specifications, and must be instantiated at the time of call. What constitutes a spy specification is described above under spy. nospy removes spy points on the specified predicates. If a specification is given in the form of a fact, all conditional spy points whose heads match that fact are removed.

debug

Turns on debugging mode. This causes subsequent execution of predicates with trace or spy points to be traced, and is a no-op if there are no such predicates. The predicates trace/1 and spy/1 cause debugging mode to be turned on automatically.

nodebug

Turns off debugging mode. This causes trace and spy points to be ignored.

debugging

Displays information about whether debug mode is on or not, and lists predicates that have trace points or spy points set on them.

debug_ctl(option,value)

debug_ctl/2 performs debugger control functions as described below. These commands can be entered before starting a trace or inside the trace. The latter can be done by responding with `` b'' at the prompt, which recursively invokes an XSB sub-session. At this point, you can enter the debugger control commands and type end_of_file. This returns XSB back to the debugger prompt, but with new settings.
  1. debug_ctl(prompt, off) Set non-interactive mode globally. This means that trace will be printed from start to end, and the user will never be prompted during the trace.
  2. debug_ctl(prompt, on) Make tracing/spying interactive.
  3. debug_ctl(profile, on) Turns profiling on. This means that each time a call execution reaches the Fail or Exit port, CPU time spent in that call will be printed. The actual call can be identified by locating a Call prompt that has the same number as the ``cpu time'' message.
  4. debug_ctl(profile, off) Turns profiling off.
  5. debug_ctl(redirect, +File) Redirects debugging output to a file. This also includes program output, errors and warnings. Note that usually you cannot see the contents of +File until it is closed, i.e., until another redirect operation is performed (usually debug_ctl(redirect, tty), see next).
  6. debug_ctl(redirect, tty) Attaches the previously redirected debugging, error, program output, and warning streams back to the user terminal.
  7. debug_ctl(show, +PortList) Allows the user to specify at which ports should trace messages be printed. PortList must be a list of port names, i.e., a sublist of ['Call', 'Exit', 'Redo', 'Fail'].
  8. debug_ctl(leash, +PortList) Allows the user to specify at which ports the tracer should stop and prompt the user for direction. PortList must be a list of port names, i.e., a sublist of ['Call', 'Exit', 'Redo', 'Fail']. Only ports that are show-n can be leash-ed.
  9. debug_ctl(hide, +PredArityPairList) The list must be of the form [P1/A1, P2/A2, ...], i.e., each either must specify a predicate-arity pair. Each predicate on the list will become non-traceable. That is, during the trace, each such predicate will be treated as an black-box procedure, and trace will not go into it.
  10. debug_ctl(unhide, ?PredArityPairList) If the list is a predicate-arity list, every predicate on that list will become traceable again. Items in the list can contain variables. For instance, debug_ctl(unhide, [_/2]) will make all 2-ary that were previously made untraceable traceable again. As a special case, if PredArityPairList is a variable, all predicates previously placed on the ``untraceable''-list will be taken off.
  11. debug_ctl(hidden, -List) This returns the list of predicates that the user said should not be traced.


next up previous contents index
Next: Low-Level Tracing Up: Debugging Previous: Debugging   Contents   Index
Baoqiu Cui
2000-04-23