5.5 Commands Available during Debugging
This section describes the particular commands that are available when
the system prompts you after printing out a debugging message. All the
commands are one or two letter mnemonics, among which some can be
optionally followed by an argument. They are read from the
standard input stream with any blanks being completely ignored up
to the end of the line (<RET>).
While you are typing commands at a given port, the debugger maintains a
notion of current frame of the ancestor stack. The “current
goal”, referred to by many commands, is the goal of the current frame.
The current frame is initially at the bottom of the ancestor stack, but
can be moved by certain commands. If the current frame is above the
bottom of the stack, the port indicator, displayed in front of the
current goal, is replaced by the word Ancestor.
The only command that you really have to remember is ‘h’ (followed
by <RET>). This provides help in the form of the following list of
available commands.
RET creep c creep
l leap z zip
s skip s <i> skip i
o out o <n> out n
q q-skip q <i> q-skip i
r retry r <i> retry i
f fail f <i> fail i
j<p> jump to port j<p><i>jump to port i
d display w write
p print p <n> print partial
g ancestors g <n> ancestors n
t backtrace t <n> backtrace n
[ frame up ] frame down
[ <i> frame i ] <i> frame i
v variables v <i> variables i
& blocked goals & <n> nth blocked goal
n nodebug = debugging
+ spy this * spy conditionally
- nospy this \ <i> remove brkpoint
D <i> disable brkpoint E <i> enable brkpoint
a abort b break
@ command u unify
e raise exception . find this
< reset printdepth < <n> set printdepth
^ reset subterm ^ <n> set subterm
? help h help
- c
- <RET>
- creep causes the debugger to single-step to the very next
port and print a message. Then if the port is leashed
(see Basic Debug), the user is prompted for further interaction.
Otherwise, it continues creeping. If leashing is off,
creep is the same as leap (see below) except that a complete
trace is printed on the standard error stream.
- l
- leap causes the debugger to resume running your program,
only stopping when a spypoint is reached (or when the
program terminates). Leaping can thus be used to follow the
execution at a higher level than exhaustive tracing. All you need to do
is to set spypoints on an evenly spread set of pertinent
predicates, and then follow the control flow through these by
leaping from one to the other. Debugging information is collected
while leaping, so when a spypoint is reached, it is possible
to inspect the ancestor goals, or creep into them upon
entry to Redo ports.
- z
- zip is like leap, except no debugging information is being
collected while zipping, resulting in significant savings in
memory and execution time.
- s
- skip is only valid for Call and Redo ports. It skips over
the entire execution of the predicate. That is, you will not see
anything until control comes back to this predicate (at either the
Exit port or the Fail port). Skip is particularly useful
while creeping since it guarantees that control will be returned
after the (possibly complex) execution within the box. If you skip,
no message at all will appear until control returns. This includes
calls to predicates with spypoints set; they will be masked
out during the skip. No debugging information is being collected while
skipping.
If you supply an integer argument, this should denote an
invocation number of an ancestral goal. The system tries to
get you to the Exit or Fail port of the invocation box you
have specified.
- o
- out is a shorthand for skipping to the Exit or Fail port of
the immediate ancestor goal. If you supply an integer
argument n, it denotes skipping to the Exit or Fail
port of the nth ancestor goal.
- q
- quasi-skip is like a combination of zip and skip:
execution stops when either control comes back to this predicate,
or a spypoint is reached. No debugging information is being
collected while quasi-skipping.
An integer argument can be supplied as for skip.
- r
- retry can be used at any port (although at the Call
port it has no effect). It transfers control back to the Call
port of the box. This allows you to restart an invocation when,
for example, you find yourself leaving with some weird result. The
state of execution is exactly the same as when you originally called,
(unless you use side-effects in your program; i.e. asserts
etc. will not be undone). When a retry is performed the invocation
counter is reset so that counting will continue from the current
invocation number regardless of what happened before the retry. This is
in accord with the fact that you have, in executional terms, returned to
the state before anything else was called.
If you supply an integer argument, this should denote an
invocation number of an ancestral goal. The system tries to
get you to the Call port of the box you have specified. It does
this by continuously failing until it reaches the right place.
Unfortunately this process cannot be guaranteed: it may be the case that
the invocation you are looking for has been cut out of the search
space by cuts (!
) in your program. In this case the
system fails to the latest surviving Call port before the correct
one.
- f
- fail can be used at any of the four ports (although at the
Fail port it has no effect). It transfers control to the Fail
port of the box, forcing the invocation to fail prematurely.
If you supply an integer after the command, this is taken as
specifying an invocation number and the system tries to get you to the
Fail port of the invocation box you have specified. It does
this by continuously failing until it reaches the right place.
Unfortunately this process cannot be guaranteed: it may be the case that
the invocation you are looking for has been cut out of the search
space by cuts (!
) in your program. In this case the
system fails to the latest surviving Fail port before the correct
one.
- j<p>
- jump to port transfers control back to the prescribed
port <p>. Here, <p> is one of: ‘c’, ‘e’,
‘r’, ‘f’, standing for Call, Exit, Redo and Fail
ports. Takes an optional integer argument, an invocation
number.
Jumping to a Call port is the same as retrying it, i.e.
‘jc’ is the same as the ‘r’ debugger command; and similarly
‘jf’ is the same as ‘f’.
The ‘je’ jump to Exit port command transfers control
back to the Exit port of the box. It can be used at a Redo or an
Exit port (although at the latter it has no effect). This allows
you to restart a computation following an Exit port, which you
first leapt over, but because of its unexpected failure you
arrived at the Redo port. If you supply an integer
argument, this should denote an exact invocation
number of an exited invocation present in the backtrace, and then
the system will get you to the specified Exit port. The debugger
requires here an exact invocation number so that it does not jump too
far back in the execution (if an Exit port is not present in the
backtrace, it may be be a better choice to jump to the preceding
Call port, rather than to continue looking for another Exit
port).
The ‘jr’ jump to Redo port command transfers control
back to the Redo port of the box. It can be used at an Exit or a
Redo port (although at the latter it has no effect). This allows
you to force the goal in question to try to deliver another
solution. If you supply an integer argument, this should
denote an exact invocation number of an exited invocation present
in the backtrace, and then the system will get you to the
specified Redo port.
- d
- display goal displays the current goal using
display/1
. See Write (below).
- p
- print goal displays the current goal using
print/1
.
An argument will override the default printdepth, treating 0 as
infinity.
- w
- write goal displays the current goal using
writeq/1
.
- g
- print ancestor goals provides you with a list of ancestors
to the current goal, i.e. all goals that are
hierarchically above the current goal in the calling sequence.
You can always be sure of jumping to the Call or Fail port of any
goal in the ancestor list (by using retry etc). If you
supply an integer n, only that number of ancestors will
be printed. That is to say, the last n ancestors will be
printed counting back from the current goal. Each entry is
displayed just as they would be in a trace message, except the current frame
is indicated by a @ in front of the invocation number.
- t
- print backtrace is the same as the above, but also shows any
goals that have exited nondeterminately and their
ancestors. This information shows where there are outstanding
choices that the program could backtrack to. If you supply
an integer n, only that number of goals will be
printed.
Ancestors to the current goal are annotated with the
‘Call:’ port, as they have not yet exited, whereas
goals that have exited are annotated with the ‘Exit:’
port. You can always be sure of jumping to the Exit or Redo
port of any goal shown to be exited in the backtrace
listing.
The backtrace is a tree rather than a stack: to find the
parent of a given goal with depth indicator d, look
for the closest goal above it with depth indicator d-1.
- [
- frame up: moves the frame up one step. If you supply an argument,
it should denote an invocation number of an existing goal.
- ]
- frame down: moves the frame down one step. If you supply an
argument, it should denote an invocation number of an existing goal.
- v
- print variable bindings endeavors to print the variable bindings
of the clause containing the current goal. This is available for both
compiled and interpreted code, if the source code was originally loaded
with the
source_info
Prolog flag switched on. The coverage is
usually better for compiled code. If you supply an argument, it should
denote an invocation number of an existing goal.
Just like the top-level, the debugger displays variable bindings as well
as any goals that are blocked on a variable found among those bindings,
and prompts for the same one-letter commands as the top-level does;
see Queries. To return to the debugger, simply type RET.
- &
- print blocked goals prints a list of the goals that are
currently blocked in the current debugging session together with
the variable that each such goal is blocked on
(see ref-sem-sec). The goals are enumerated from 1 and up. If
you supply an integer n, only that goal will be
printed. Each entry is preceded by the goal number followed by
the variable name.
- n
- nodebug switches the debugger off. Note that this is the correct way
to switch debugging off at a trace point. You cannot use the @ or
b commands because they always return to the debugger.
- =
- debugging outputs information concerning the status of the
debugging package. See the built-in predicate
debugging/0
.
- +
- spy this sets a plain spypoint on the current goal.
- *
- spy this conditionally sets a conditional spypoint on the
current goal. Prompts for the Conditions, and calls the
spy(Func, Conditions)
goal, where Func is the predicate spec of the current
invocation. For spy/2
, see Breakpoint Predicates.
- -
- nospy this removes all spypoints applicable to the current
goal. Equivalent to
nospy
Func, where Func is
the predicate spec of the current invocation.
- \
- remove this removes the spypoint that caused the debugger to
interact at the current port. With an argument n, it
removes the breakpoint with identifier n. Equivalent to
remove_breakpoints(
BID)
, where BID is the current
breakpoint identifier, or the supplied argument
(see Breakpoint Predicates).
- D
- disable this disables the spypoint that caused the debugger
to interact at the current port. With an argument n,
it disables the breakpoint with identifier n. Equivalent to
disable_breakpoints(
BID)
, where BID is the current
breakpoint identifier, or the supplied argument
(see Breakpoint Predicates).
- E
- enable this enables all specific spypoints for the
predicate at the current port. With an argument
n, it enables the breakpoint with identifier
n. Equivalent to
enable_breakpoints(
BID)
, where
BID is the breakpoint identifiers for the current
predicate, or the supplied argument (see Breakpoint Predicates).
- .
- find this outputs information about where the predicate
being called is defined.
- a
- abort causes an abort of the current execution. All the execution
states built so far are destroyed and you are put right back at the
top-level. (This is the same as the built-in predicate
abort/0
.)
- b
- break calls the built-in predicate
break/0
, thus
putting you at a recursive top-level with the execution so far sitting
underneath you. When you end the break (^D) you will be
reprompted at the port at which you broke. The new execution is
completely separate from the suspended one; the invocation numbers will
start again from 1 during the break. The debugger is temporarily
switched off as you call the break and will be re-switched on when you
finish the break and go back to the old execution. However, any changes
to the leashing or to spypoints will remain in effect.
- @
- command gives you the ability to call arbitrary Prolog
goals. It is effectively a one-off break (see above). The
initial message ‘| :- ’ will be output on the standard error
stream, and a command is then read from the standard input stream
and executed as if you were at top-level. If the term read is of
form Pattern
^
Body, Pattern is
unified with the current goal and Body is executed.
Please note:
- If Body is compound, it should be parenthesized.
- If the current goal has a module qualifier, Pattern should not
include the module qualifier.
- u
- unify is available at the Call port and gives you the option
of providing a solution to the goal from the standard input
stream rather than executing the goal. This is convenient
e.g. for providing a “stub” for a predicate that has not yet
been written. A prompt will be output on the standard error
stream, and the solution is then read from the standard input
stream and unified with the goal. If the term
read in is of the form Head
:-
Body, Head
will be unified with the current goal, and Body will
be executed in its place.
- e
- raise exception is available at all ports. A prompt will be
output on the standard error stream, and an exception term
is then read from the standard input stream and raised in the
program being debugged.
- <
- This command, without arguments, resets the printdepth to 10.
With an argument of n, the printdepth is set to n,
treating 0 as infinity. This command works by changing the value of the
debugger_print_options
Prolog flag.
- ^
- While at a particular port, a current subterm of the current goal
is maintained. It is the current subterm that is displayed, printed, or
written when prompting for a debugger command. Used in combination with
the printdepth, this provides a means for navigating in the current goal
for focusing on the part of interest. The current subterm is set to the
current goal when arriving at a new port. This command, without
arguments, resets the current subterm to the current goal. With an
argument of n (> 0), the current subterm is replaced by its
n:th subterm. With an argument of 0, the current subterm is
replaced by its parent term. With multiple arguments separated by
whitespace, the arguments are applied from left to right.
- ?
- h
- help displays the table of commands given above.
The user can define new debugger commands or modify the behavior of the
above ones using the user:debugger_command_hook/2
hook predicate,
see Breakpoint Predicates.
Send feedback on this subject.