### 5.3 Debugging predicates

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

#### 5.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 with 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 5.6). It can be also invoked using the W debugger command (section 5.5).

#### 5.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.

#### 5.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 5.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-2021 Daniel Diaz Verbatim copying and distribution of this entire article is permitted in any medium, provided this notice is preserved. More about the copyright