Quintus Prolog Manual


(PREV) (NEXT)

e-3: The Standard Debugger

The standard debugger is a traditional terminal-based (as opposed to window-based) debugger. {manual(e-1)} describes the basic debugger facilities; this chapter only describes the features of the standard debugger.

e-3-1: Format of Debugging Messages

After you turn on the debugger and type the goal you want to debug, the system begins to show the steps of the procedure's execution. As the system passes through each port of a procedure, it displays a debugging message on your terminal.

A sample debugging message and an explanation of its symbols are shown below.

** (23) 0 Call (dynamic): mymodule:foo(hello,there,_123) ?



**
The first two characters indicate whether this is a spypoint and whether this port is being entered after a 'skip'. The possible combinations are:
    ** -   This is a spypoint.  (foo/3 has been spied.)

    *> -   This is a spypoint; you are returning from a 'skip'.

    > -   This is not a spypoint; you are returning from a 'skip'.

        -   This is not a spypoint.  (For this condition, two blank

            spaces are displayed at the left of the message.)

            
(23)
The number in parentheses is the unique invocation identifier. This identifies a particular call to the procedure. This number can be used to correlate the trace messages for the various ports, since it is unique for every invocation. It will also give an indication of the number of procedure calls made since the start of the execution. The invocation counter is reset to 1 whenever a new goal is typed at the top level, and is also reset when retries (see {manual(e-1-3-4)}) are performed.
0
The next number is the current depth -- that is, the number of direct ancestors this goal has. The ancestors can be printed using the 'g' debugging option. The depth increases as procedures are called and decreases as procedures return. There may be many goals at the same depth, which is why the unique invocation identifier is also provided. If the depth is shown as 0, this spypoint is on a compiled procedure and no depth or ancestor information is available. The depth is reset to 0 when a compiled procedure is executed, and begins growing again from there afterward.
Call
The next word shows the particular port: Head, Call, Exit, Done, Redo, Fail, or Exception.
(dynamic)
The next parenthesized item, if present, indicates when there is something unusual about the predicate. The possibilities are:
built_in
for built-in predicates; or
locked
for locked predicates; or
undefined
for undefined predicates; or
foreign
for foreign predicates (defined in another programming language); or
dynamic
for dynamic predicates; or
multifile
for multifile predicates.
mymodule
If the procedure currently being debugged was loaded into a module other than 'user', the module name will be displayed here, followed by a colon.
foo(hello,there,_123)
The goal is then printed so that its current instantiation state can be seen. (At Redo ports, the instantiation state shown is the same as at the previous Exit.) This is done using print/1 so that all goals displayed by the debugger can be "pretty printed", if the user wishes, using portray/1 clauses. The debugger also maintains a print depth limit and will only show terms nested down to this depth. The system initially uses a limit of 10, but this can be changed using the '<' debugging option.
?
The final '?' is the prompt indicating that you should type in one of the option codes (see next section). If this particular port is unleashed, there will be no prompt and the debugger will continue to the next port.

NOTE: Since the system does not allow the placing of spypoints on built-in predicates, the only way to show the execution of built-in predicates typed at the main Prolog prompt is to select trace mode. For example, if you typed 'write(foo).' at the main Prolog prompt with the debugger in debug mode, the system would simply display the word 'foo' without tracing the execution of the predicate write/1. However, if a built-in predicate such as write/1 were called from within a program, the execution of the predicate would be shown in any case that the execution of the procedure containing it would be shown. There are a few basic built-in predicates for which information is not displayed because it is more convenient not to trace them. These are: true/0, otherwise/0, false/0, fail/0, =/2, '!' (cut), ';' (or), ',' (and), and '->'/2 (local cut).

e-3-1-1: Format of Head Port Messages

The message shown at a Head port is slightly different than the messages at other ports. Rather than optionally showing something unusual about the predicate (dynamic in the above example), the Head port shows you which clause of the predicate is being, and which, if any, will be tried next. For example, a Head port might be printed as follows:

   (23) 0 Head [2->4]: mymodule:foo(hello,there,_123) ?



Here the [2->4] means that clause 2 for predicate mymodule:foo/3 is about to be tried. If this clause's head should fail to unify, or if a goal in the body of the clause fails, clause 4 will be tried next. Clause 3 will be skipped, due to indexing (see {manual(b-5-2)}). If clause 2 were the last clause to be tried, it would be shown as [2]. And in the case where clause 2 is being tried, and all the following clauses are indexable, but none can match the goal, the debugger will show [2->fail], suggesting that a choice point is being left, even though no more solutions will be possible (see {manual(b-5-2)} for an explanation of indexable clauses, and how indexing works).

e-3-1-2: Format of Exception Port Messages

The Exception port shows the exception term describing the exception that has been raised. This is printed on a separate line before the line printed for the port itself. For example:

! type_error(_2069 is a,2,'arithmetic expression',a)

   (2) 1 Exception (built_in): _2050 is a ?



For exception term formats or more information about the exception handling system of Quintus Prolog, see {manual(g-19)}.

e-3-2: Options Available during Debugging

e-3-2-0: Introduction

This section describes the options that you can select in response to the '? ' prompt, which is displayed after the debugger prints out a goal. The options are one-letter mnemonics, some of which optionally can be followed by a decimal integer. Any layout characters are ignored up to the next newline.

The most important option to remember is 'h' (for help). When you type 'h', the following list of available options is displayed:

Debugging options:



<cr>   creep      p      print         r [i]  retry i      @    command

 c     creep      w      write         f [i]  fail i       b    break

 l     leap       d      display                           a    abort

 s [i] skip i                                              h    help

 z     zip        g [n]  n ancestors   +      spy pred     ?    help

 n     nonstop    < [n]  set depth     -      nospy pred   =    debugging

 q     quasi-skip .      find defn     e      raise_exception



 

These options provide a number of different functions which fall into the following classes:

Basic control
- The basic ways of continuing with the execution
Printing
- Showing the goal, or its ancestors, in various ways
Advanced control
- Affecting control flow
Environment
- Changing spypoints, executing commands, breaking and aborting, access to source code
Help
- Showing the debugger state and listing options

Each of the options is described below.

e-3-2-1: Basic Control Options

These commands are described in depth in {manual(e-1-3)} and {manual(e-1-3-2)}.

<CR>
(the Return key)

This is the same as the 'c' (creep) option but is reduced to a single keystroke for convenience.
c
creep

This causes the debugger to single-step to the next port and display its goal.
l
leap

This causes the debugger to resume running your program, stopping only when the next spypoint is reached, or when the program terminates.
s
skip

At a Call, Redo, or Head port, this skips over the entire execution of the procedure. At any other port, this is equivalent to the 'c' (creep) option.
s [i]
skip over ancestor invocation

If you specify an invocation identifier (see {manual(e-3-1)}) of an ancestor invocation after the skip command, it will skip over that invocation. This means that that ancestor goal will be completed without stopping.
z
zip

This causes the debugger to run until the next spypoint is reached, just like leaping, except that no debugging information is kept, so execution is much faster. See {manual(e-1-3-3)} for more information on the trade-offs between speed and information when using this option.
q
quasi-skip

This causes the debugger to run until the next spypoint is reached, or until this invocation is completed. This option combines the behavior of leaping and skipping. It also ensures that the debugger will stop at the Exit, Done, or Fail port of the current invocation, as soon as it is reached.

e-3-2-2: Printing Options

p
print

This option prints the current goal using print/1 and the current debugger print depth limit. The depth limit prevents very large structures from being shown in their entirety; it can be changed with the '<' (set depth) option (see below).
w
write

This option writes the current goal on the terminal using write/1. This may be useful if your "pretty print" routine (portray/1) is not doing what you want. The 'write' option has no depth limit.
d
display

This option displays the current goal on the terminal using display/1. This shows the goal in prefix notation. The 'display' option has no depth limit.
g
ancestors

This option prints the list of ancestors of the current goal (that is, all goals that are between the current goal and the top-level goal in the calling sequence). Each ancestor goal is printed using print/1 with the current debugger depth limit. Goals shown in the ancestor list are always accessible to invocations for the 'r' (retry) option.
g [n]
ancestors

This is a version of the 'g' option which prints only n ancestors. That is, the last n ancestors will be printed counting back from the current goal.
< [n]
set depth

This option sets the debugger print depth limit to n. This limit determines the depth to which goals are printed when they are shown by the debugger. The depth limit is also used when showing the ancestor list. If n is 0, or is omitted, the debugger will then use no limit when printing goals. The default limit is 10.

e-3-2-3: Advanced Control Options

These options are described in greater depth in {manual(e-1-3-4)}.

r
retry

This option restarts the current invocation. This may be useful when, for example, you find yourself leaving with some incorrect result. 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 execution has returned to the state it was in at the time of the original call. The message
                [Debugger:  retry goal]



         

is displayed to indicate where this occurred, in case you wish to follow these numbers later.

r [i]
retry previous invocation

If you supply an integer after the retry command, then this is taken as specifying an invocation number and the system tries to get you to the Call port, not of the current box, but of the invocation box you have specified. This must be an ancestor invocation.
f
fail

This is similar to Retry except that it transfers control to the Fail port of the current box. This places your execution in a situation in which it is about to backtrack out of the current invocation, having failed the goal.
f [i]
fail previous invocation

This is similar to 'r [i]' except that it transfers control to the Fail port of the invocation specified (which must be an ancestor).

e-3-2-4: Environment Options

n
nonstop

This option turns off the debugger for the rest of the execution of the top-level goal. When the execution of this goal is completed, the debugger returns to its current mode (trace, debug, or zip). This option does not turn the debugger off; to turn the debugger off, you must type:
                | ?- call nodebug



        
+
spy this

This option places a spypoint on the procedure currently being shown.
-
nospy this

This option removes any spypoint on the procedure currently being shown.
@
command

This option prompts for a single Prolog goal, which is executed as a command without any variable results being shown. The command is run as a new execution, with the current execution suspended, but without any debugging. This is particularly useful for quickly changing debugging parameters without entering a break level.
b
break

This option calls the built-in predicate break/0, thus suspending the execution so far and putting you at the top level of the interpreter. (See the description of break/0 in {manual(g-11-1)}.) The new execution is separate from the suspended one, and invocation numbers will start again from 1. The debugger is turned off when the break level is entered, although the spypoints and leashing of the suspended level are retained. When you end the break (by typing the end-of-file character), execution will resume and you will be prompted once again at the port which you left. Changes to leashing or to spypoints will remain in effect after the break has finished.
a
abort

This option aborts (abandons) the current execution. All the execution states built so far are destroyed, and execution restarts at the top level of the interpreter.
.
find-definition

This works only under the editor interface. The source code corresponding to the current procedure call is found and displayed in the text window.
,
find-more-definition

This works only under the Emacs interfaces, and can be used after doing a find-definition, in the case where there is more than one possible definition. This is useful in several cases:
  1. where a predicate is multifile -- you can find all the files which have clauses for that predicate;
  2. where you specify a name but no arity -- you can find all the definitions of predicates with that name and with different arities;
  3. where you have the same name/arity defining predicates in different modules.

e-3-2-5: Help Options

h
help

This option displays the table of options given above.
?
help

This is equivalent to the 'h' option.
=
debugging

This option shows the current state of the debugger, the spypoints that have been set, the leashed ports, and the behavior on undefined procedures.


Copyright (C) 1997 AI International Ltd
contact: product support sales information