Debugging predicates

4.3 | Debugging predicates

- Running and stopping the debugger
- Leashing ports
- Spy-points

4.3.1 | Running and stopping the debugger

`trace/0` activates the debugger. The next invocation of a predicate will be traced.
`debug/0` activates the debugger. The next invocation of a predicate on which a spy-point has been set will be traced.
It is important to understand that the information associated to the control flow is only available when the debugger is on. For efficiency reasons, when the debugger is off the information concerning the control flow (i.e. the boxes) is not retained. So, if the debugger is activated in the middle of a computation (by a call to `debug/0` or `trace/0` in the program or after the interrupt key sequence (`Ctl-C`) by choosing `trace` or `debug`), information prior to this point is not available.
`debugging/0`: prints onto the terminal information about the current debugging state (whether the debugger is switched on, what are the leashed ports, spy-points defined,...).
`notrace/0` or `nodebug/0` switches the debugger off.
`wam_debug/0` invokes the sub-debugger devoted to the WAM data structures (section 4.6). It can be also invoked using the `W` debugger command (section 4.5).

4.3.2 | Leashing ports

`leash(Ports)` requests the debugger to prompt the user, as he creeps through the program, for every port defined in the `Ports` list. Each element of `Ports` is an atom in `call`, `exit`, `redo`, `fail`, `exception`. `Ports` can also be an atom defining a shorthand:

- `full`: equivalent to `[call, exit, redo, fail, exception]`
- `half`: equivalent to `[call, redo]`
- `loose`: equivalent to `[call]`
- `none`: equivalent to `[]`
- `tight`: equivalent to `[call, redo, fail, exception]`

When an unleashed port is encountered the debugger continues to show the associated goal but does not stop the execution to prompt the user.

4.3.3 | Spy-points

When dealing with big sources it is not very practical to creep through the entire program. It is preferable to define a set of spy-points on interesting predicates to be prompted when the debugger reaches one of these predicates. Spy-points can be added either using `spy/1` (or `spypoint_condition/3`) or dynamically when prompted by the debugger using the `+` (or `*`) debugger command (section 4.5). The current mode of leashing does not affect spy-points in the sense that user interaction is requested on every port.
`spy(PredSpec)` sets a spy-point on all the predicates given by `PredSpec`. `PredSpec` defines one or several predicates and has one of the following forms:

- `[PredSpec1, PredSpec2,...]`: set a spy-point for each element of the list.
- `Name`: set a spy-point for any predicate whose name is `Name` (whatever the arity).
- `Name/Arity`: set a spy-point for the predicate whose name is `Name` and arity is `Arity`.
- `Name/A1-A2`: set a spy-point for the each predicate whose name is `Name` and arity is between `A1` and `A2`.

It is not possible to set a spy-point on an undefined predicate.
The following predicate is used to remove one or several spy-points:
`nospy(PredSpec)` removes the spy-points from the specified predicates.
`nospyall/0` removes all spy-points:
It is also possible to define conditional spy-points.
`spypoint_condition(Goal, Port, Test)` sets a conditional spy-point on the predicate for `Goal`. When the debugger reaches a conditional spy-point it only shows the associated goal if the following conditions are verified:

- the actual goal unifies with `Goal`.
- the actual port unifies with `Port`.
- the Prolog goal `Test` succeeds.

Copyright (C) 1999-2002 Daniel Diaz
Verbatim copying and distribution of this entire article is permitted in any medium, provided this notice is preserved.
More about the copyright