How to debug in [Clozure] Common Lisp?

前端 未结 3 1938
悲&欢浪女
悲&欢浪女 2021-01-03 01:32

I\'m using CCL on Mac (1.8.1 -- the latest available at this writing), and wondering if there\'s any sort of debugging tutorial available.

The thing I\'m particularl

相关标签:
3条回答
  • 2021-01-03 02:16

    The simple answer you are looking for is given by juanitofatas. Unfortunately CCL does not support step and hence is weak in debugging. Until now the best implementation to debug is CLISP.

    0 讨论(0)
  • 2021-01-03 02:18

    I am sure a CCL user might point you to the Debugging section in the CCL manual, but, in fact, the ANSI Common Lisp standard includes excellent debugging facilities, including break and step you asked about (except for step's granularity is not based on a line of code but rather a form).

    In fact, the whole Condition System is worth examining.

    There are a few tutorials too.

    The most important thing to remember that the debugging tools give you the normal Lisp REPL (Read-Eval-Print Loop) where you can do just about anything you can do with the initial REPL: define functions and variables, examine the existing variable (including those defined in the functions in which the debugger was entered) et al. Additionally, you might be able to issue additional commands, like step and next (often abbreviated :s and :n) in the stepper or continue (often abbreviated :c) in a continuable error.

    One difference you need to watch for is that in gdb you examine a variable x using print x (abbreviated p x) while in Lisp you just type x and it is evaluated.

    Here are some simple examples:

    Step

    Here ? gives help 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 stepper 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 the prompt is Break <level>.

    Assert

    > (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 prompt as break.

    0 讨论(0)
  • 2021-01-03 02:34

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

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

    0 讨论(0)
提交回复
热议问题