Next: Low-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
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:
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.)
- initially entered (Call),
- successfully returned from (Exit),
- failed back into (Redo), and
- completely failed out of (Fail).
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 is
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
- 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
- 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
Other standard predicates that are useful in debugging are:
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 /, where is a predicate name and 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. :/. (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:
(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.
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.
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.
Turns off debugging mode. This causes trace and spy points to be ignored.
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/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
returns XSB back to the debugger prompt, but with new settings.
- 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.
- debug_ctl(prompt, on)
Make tracing/spying interactive.
- 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''
- debug_ctl(profile, off)
Turns profiling off.
- 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).
- debug_ctl(redirect, tty)
Attaches the previously redirected debugging, error, program output,
and warning streams back to the user terminal.
- 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'].
- 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.
- 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.
- 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.
- debug_ctl(hidden, -List)
This returns the list of predicates that the user said should not be
Next: Low-Level Tracing