Common Lisp the Language, 2nd Edition

Next: Predefined Condition Types Up: Program Interface to Previous: Restart Functions

## 29.4.11. Debugging Utilities

Common Lisp does not specify exactly what a debugger is or does, but it does provide certain means for indicating intent to transfer control to a supervisory or debugging facility.

[Function]
`break &optional format-string &rest format-arguments`

[This supersedes the description of `break` given in section 24.1.-GLS]

The function `break` prints the message described by the format-string and format-arguments and then goes directly into the debugger without allowing any possibility of interception by programmed error-handling facilities.

If no format-string is supplied, a suitable default will be generated.

If continued, `break` returns `nil`.

Note that `break` is presumed to be used as a way of inserting temporary debugging ``breakpoints'' in a program, not as a way of signaling errors; it is expected that continuing from a `break` will not trigger any unusual recovery action. For this reason, `break` does not take the additional format control string that `cerror` takes as its first argument. This and the lack of any possibility of interception by programmed error handling are the only program-visible differences between `break` and `cerror`. The user interface aspects of these functions are permitted to vary more widely; for example, it is permissible for a read-eval-print loop to be entered by `break` rather than by the conventional debugger.

`break` could be defined by

    (defun break (&optional (format-string "Break")
                  &rest format-arguments)
      (with-simple-restart (continue "Return from BREAK.")
        (invoke-debugger
          (make-condition 'simple-condition
                          :format-string format-string
                          :format-arguments format-arguments)))
      nil)

[Function]
`invoke-debugger condition`

Attempts interactive handling of its argument, which must be a condition.

If the variable `*debugger-hook*` is not `nil`, it will be called as a function on two arguments: the condition being handled and the value of `*debugger-hook*`. If a hook function returns normally, the standard debugger will be tried.

The standard debugger will never directly return. Return can occur only by a special transfer of control, such as the use of a restart.

Remark: The exact way in which the debugger interacts with users is expected to vary considerably from system to system. For example, some systems may use a keyboard interface, while others may use a mouse interface. Of those systems using keyboard commands, some may use single-character commands and others may use parsed line-at-a-time commands. The exact set of commands will vary as well. The important properties of a debugger are that it makes information about the error accessible and that it makes the set of apparent restarts easily accessible.

It is desirable to have a mode where the debugger allows other features, such as the ability to inspect data, stacks, etc. However, it may sometimes be appropriate to have this kind of information hidden from users. Experience on the Lisp Machines has shown that some users who are not programmers develop a terrible phobia of debuggers. The reason for this usually may be traced to the fact that the debugger is very foreign to them and provides an overwhelming amount of information of interest only to programmers. With the advent of restarts, there is a clear mechanism for the construction of ``friendly'' debuggers. Programmers can be taught how to get to the information they need for debugging, but it should be possible to construct user interfaces to the debugger that are natural, convenient, intelligible, and friendly even to non-programmers.

[Variable]
`*debugger-hook*`

This variable should hold either `nil` or a function of two arguments, a condition and the value of `*debugger-hook*`. This function may either handle the condition (transfer control) or return normally (allowing the standard debugger to run).

Note that, to minimize recursive errors while debugging, `*debugger-hook*` is bound to `nil` when calling this function. When evaluating code typed in by the user interactively, the hook function may want to bind `*debugger-hook*` to the function that was its second argument so that recursive errors can be handled using the same interactive facility.

Next: Predefined Condition Types Up: Program Interface to Previous: Restart Functions