25.1. Top Level Loop
Prev | Chapter 25. Environment | Next

## 25.1. Top Level Loop [sec_25-1-1]

The debugger may be invoked through the functions `INVOKE-DEBUGGER`, `BREAK`, `SIGNAL`, `ERROR`, `CERROR`, `WARN`. The stepper is invoked through the macro `STEP`. Debugger and stepper execute subordinate read-eval-print loop (called break loops) which are similar to the main read-eval-print loop except for the prompt and the set of available commands. Commands must be typed literally, in any case, without surrounding quotes or whitespace. Each command has a keyword abbreviation, indicated in the second column.

Table 25.1. Commands common to the main loop, the debugger and the stepper

command | abbreviation | operation
--- | --- | ---
help | :h | prints a list of available commands

Table 25.2. Commands common to the debugger and the stepper

command | abbreviation | operation
--- | --- | ---
Abort | :a | abort to the next most recent read-eval-print loop
Unwind | :uw | abort to the next most recent read-eval-print loop
Quit | :q | quit to the top read-eval-print loop

The stack is organized into frames and other stack elements. Usually every invocation of an interpreted function and every evaluation of an interpreted form corresponds to one stack frame. Special forms such as `LET`, `LET*`, `UNWIND-PROTECT` and `CATCH` produce special kinds of stack frames.

In a break loop there is a current stack frame, which is initially the most recent stack frame but can be moved using the debugger commands Up and Down.

Evaluation of forms in a break loop occurs in the lexical environment of the current stack frame and at the same time in the dynamic environment of the debugger's caller. This means that to inspect or modify a lexical variable all you have to do is to move the current stack frame to be just below the frame that corresponds to the form or the function call that binds that variable.

There is a current stack mode which defines in how much detail the stack is shown by the stack-related debugger commands:

1. All the stack elements are considered. This mode works fine for debugging compiled functions.
2. All the frames are considered.
3. Only lexical frames (frames that correspond to special forms that modify the lexical environment) are considered.
4. Only `EVAL` and `APPLY` frames are considered. Every evaluation of a form in the interpreter corresponds to an `EVAL` frame. This is the default.
5. Only `APPLY` frames are considered. Every invocation of an interpreted function corresponds to one `APPLY` frame.

Table 25.3. Commands common to the debugger and the stepper

command | abbreviation | operation
--- | --- | ---
Error | :e | print the last error object.
Inspect | :i | `INSPECT` the last error object.
Where | :w | shows the current stack frame.
Up | :u | goes up one frame, i.e., to the caller if in mode-5
Down | :d | does down one frame, i.e., to the callee if in mode-5
Top | :t | goes to top frame, i.e., to the top-level form if in mode-4
Bottom | :b | goes to bottom (most recent) frame, i.e., most probably to the form or function that caused the debugger to be entered.
Mode `mode` | :m `mode` | sets the current stack mode
Frame-limit `l` | :fl | set the frame-limit: this many frames will be printed by Backtrace at most.
Backtrace [`mode` [`l`]] | :bt [`mode` [`l`]] | lists the stack in the given `mode`, bottom frame first, top frame last; at most `l` frames are printed.

If the current stack frame is an `EVAL` or `APPLY` frame, the following commands are available as well:

Table 25.4. Commands specific to `EVAL`/`APPLY`

command | abbreviation | operation
--- | --- | ---
Break+ | :br+ | sets a breakpoint in the current frame. When the corresponding form or function will be left, the debugger will be entered again, with the variable `EXT:*TRACE-VALUES*` containing a list of its values.
Break- | :br- | removes a breakpoint from the current frame.
Redo | :rd | re-evaluates the corresponding form or function call. This command can be used to restart parts of a computation without aborting it entirely.
Return `value` | :rt `value` | leaves the current frame, returning the given value.

Table 25.5. Commands specific to the debugger

command | abbreviation | operation
--- | --- | ---
Continue | :c | continues evaluation of the program.

Table 25.6. Commands specific to the stepper

command | abbreviation | operation
--- | --- | ---
Step | :s | step into a form: evaluate this form in single step mode
Next | :n | step over a form: evaluate this form at once
Over | :o | step over this level: evaluate at once up to the next return
Continue | :c | switch off single step mode, continue evaluation

The stepper is usually used like this: If some form returns a strange value or results in an error, call `(`STEP` `form`)` and navigate using the commands Step and Next until you reach the form you regard as responsible. If you are too fast (execute Next once and get the error), there is no way back; you have to restart the entire stepper session. If you are too slow (stepped into a function or a form which certainly is OK), a couple of Next commands or one Over command will help.

### 25.1.1. User-defined Commands

You can set `CUSTOM:*USER-COMMANDS*` to a list of `FUNCTION`s, each returning a `LIST` of bindings, i.e., either a

`STRING`
  the help string printed by help in addition to the standard CLISP help
`CONS` `(`STRING` . `FUNCTION`)`
  the actual binding: when the user types the string, the function is called on the remainder of the string, i.e., the part of the string after the command.

E.g.,

    (setq CUSTOM:*USER-COMMANDS*
          (list (lambda () (list (format nil "~2%User-defined commands:")))
                (lambda ()
                  (flet ((panic (argline)
                           (format t "don't panic~@[ because of ~A~], ~D~%"
                                   (and (plusp (length argline)) argline)
                                   (random 42))))
                    (list (format nil "~%panic   :p    hit the panic button!")
                          (cons "panic" #'panic)
                          (cons ":p" #'panic))))
                (lambda ()
                  (let ((curses #("ouch" "yuk" "bletch")))
                    (flet ((swear (argline)
                             (format t "~A: ~A!~%" argline
                                     (aref curses (random (length curses))))))
                      (list (format nil "~%swear   :e    curse")
                            (cons "swear" #'swear)
                            (cons ":e" #'swear)))))))

| These notes document CLISP version 2.45 | Last modified: 2008-05-14

Enter your search termsSubmit search form
Webclisp.cons.orgclisp.podval.orgwww.lisp.org

Prev | Up | Next
Chapter 25. Environment | Home | 25.2. Debugging Utilities