I am sure that the CCL user can tell you the Debugging section in the CCL manual , but in fact ANSI Common Lisp includes some excellent debugging tools, including the break and step that you asked for (except step , the granularity is not based on a line of code, but rather on the form).
In fact, it is worth considering the entire system of conditions .
There are several tutorials .
The most important thing to remember is that the debugging tools give you a normal REPL (Read-Eval-Print Loop), where you can do something you can do with the original REPL: define functions and variables, examine the existing variable (including those defined in functions into which the debugger was entered), etc. In addition, you can issue additional commands, such as step and next (often abbreviated :s and :n ) in a step or continue (often abbreviated :c ) in a continuous error.
The only difference you need to observe is that in gdb you check the variable x with print x (abbreviated as px ), and in Lisp you just type x and evaluate it.
Here are some simple examples:
Step
Here ? provides information on available commands; try help or :h if your Lisp barfs.
> (defun factorial (n) (if (zerop n) 1 (* n (factorial (1- n))))) FACTORIAL > (step (factorial 3)) step 1 --> (FACTORIAL 3) Step 1 > ? Commands may be abbreviated as shown in the second column. COMMAND ABBR DESCRIPTION Help :h, ? print this command list Error :e print the last error message Inspect :i inspect the last error Abort :a abort to the next recent input loop Unwind :uw abort to the next recent input loop Reset :re toggle *PACKAGE* and *READTABLE* between the local bindings and the sane values Quit :q quit to the top-level input loop Where :w inspect this frame Up :u go up one frame, inspect it Top :t go to top frame, inspect it Down :d go down one frame, inspect it Bottom :b go to bottom (most recent) frame, inspect it Mode mode :m set stack mode for Backtrace: 1=all the stack elements 2=all the frames 3=only lexical frames 4=only EVAL and APPLY frames (default) 5=only APPLY frames Frame-limit n :fl set the frame-limit for Backtrace. This many frames will be printed in a backtrace at most. Backtrace [mode [limit]] :bt inspect the stack Break+ :br+ set breakpoint in EVAL frame Break- :br- disable breakpoint in EVAL frame Redo :rd re-evaluate form in EVAL frame Return value :rt leave EVAL frame, prescribing the return values Step :s step into form: evaluate this form in single step mode Next :n step over 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 -- Step-until :su, Next-until :nu, Over-until :ou, Continue-until :cu -- same as above, specify a condition when to stop Step 1 > :s step 2 --> 3 Step 2 > :n step 2 ==> value: 3 step 2 --> (IF (ZEROP N) 1 (* N (FACTORIAL
Note that the prompt inside the step is step <level> , where level is the nesting level.
Break
> (defun assert-0 (x) (unless (eql x 0) (break "Bad x: ~S" x)) 0) ASSERT-0 > (assert-0 0) 0 > (assert-0 'assert-0) ** - Continuable Error Bad x: ASSERT-0 If you continue (by typing 'continue'): Return from BREAK loop The following restarts are also available: ABORT :R1 Abort main loop Break 1 > x ASSERT-0 Break 1 > :c 0
Here's the Break <level> prompt.
Approve
> (defun my+1 (x) (assert (numberp x) (x) "must be a number: ~S" x) (1+ x)) MY+1 > (my+1 5) 6 > (my+1 'my+1) ** - Continuable Error must be a number: MY+1 If you continue (by typing 'continue'): Input a new value for X. The following restarts are also available: ABORT :R1 Abort main loop Break 1 > :c New X> 'foo ** - Continuable Error must be a number: FOO If you continue (by typing 'continue'): Input a new value for X. The following restarts are also available: ABORT :R1 Abort main loop Break 1 > :c New X> 6 7
assert uses the same hint as break .