How to debug in [Clozure] Common Lisp?

I am using CCL on a Mac (1.8.1 is the latest available in this article) and wondering if there is any tutorial for debugging.

What interests me especially is to set a breakpoint somewhere in my code, then push and push various values, then go to the next line of code, check more values, etc.

EDIT: I read the debugging section of the CCL manual (18.3 and so on), but can't figure it out. I am coming from C / Java / etc. IDE-based background and source-level debuggers with little impact on gdb.

So, I think what I'm looking for is an introduction / tutorial that allows me to go through a few simple steps.

(I'm new to Lisp (and CCL, of course), so if I ask a completely wrong question or something is completely wrong, feel free to let me know.)

Thanks!

+4
source share
3 answers

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 #))) Step 2 > :s step 3 --> (ZEROP N) Step 3 > :n step 3 ==> value: NIL step 3 --> (* N (FACTORIAL (1- N))) Step 3 > :s step 4 --> N Step 4 > :n step 4 ==> value: 3 step 4 --> (FACTORIAL (1- N)) Step 4 > :s step 5 --> (1- N) Step 5 > :n step 5 ==> value: 2 step 5 --> (IF (ZEROP N) 1 (* N (FACTORIAL #))) Step 5 > :c step 5 ==> value: 2 step 4 ==> value: 2 step 3 ==> value: 6 step 2 ==> value: 6 step 1 ==> value: 6 6 

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 .

+6
source

The simple answer you are looking for is given by juanitofatas. Unfortunately, CCL does not support a step and is therefore weak in debugging. So far, the best debugging option is CLISP.

+4
source

in ccl, you can use cl-stepper:step instead of cl:step .

(ql:quickload "com.informatimago.common-lisp.lisp.stepper")

0
source

Source: https://habr.com/ru/post/1495649/


All Articles