Debugging 如何在[Clozure]Common Lisp中调试?

Debugging 如何在[Clozure]Common Lisp中调试?,debugging,common-lisp,Debugging,Common Lisp,我正在Mac上使用CCL(1.8.1——本文提供的最新版本),不知道是否有任何调试教程可用 我特别感兴趣的是在代码中的某个地方设置断点,然后戳和戳各种值,然后跨过下一行代码,检查更多值,等等 编辑: 我已经阅读了CCL手册的调试部分(18.3及相关内容),但没有完全理解它。我来自C/Java/etc.背景和基于IDE的源代码级调试器,对gdb有一点了解 所以我想我要找的是一个介绍/教程,它能引导我完成一些简单的步骤 (我是Lisp(当然还有CCL)的新手,因此,如果我问的问题完全错误,或者做事方

我正在Mac上使用CCL(1.8.1——本文提供的最新版本),不知道是否有任何调试教程可用

我特别感兴趣的是在代码中的某个地方设置断点,然后戳和戳各种值,然后跨过下一行代码,检查更多值,等等

编辑: 我已经阅读了CCL手册的调试部分(18.3及相关内容),但没有完全理解它。我来自C/Java/etc.背景和基于IDE的源代码级调试器,对gdb有一点了解

所以我想我要找的是一个介绍/教程,它能引导我完成一些简单的步骤

(我是Lisp(当然还有CCL)的新手,因此,如果我问的问题完全错误,或者做事方式完全错误,请随时告诉我。)


谢谢

我相信CCL用户可能会向您指出,但事实上,ANSI Common Lisp标准包含了优秀的调试工具,包括和您询问的(除了
步骤之外,
的粒度不是基于代码行,而是基于表单)

事实上,整个问题值得研究

还有一个问题

需要记住的最重要的一点是,调试工具为您提供了正常的Lisp REPL(Read Eval Print Loop),在这里您可以对初始REPL执行任何操作:定义函数和变量,检查现有变量(包括在调试器输入的函数中定义的变量)等等,您可能能够在步进器中发出附加命令,如
步骤
下一步
(通常缩写为
:s
:n
)或在连续错误中发出
继续
(通常缩写为
:c

您需要注意的一个区别是,在
gdb
中,您使用
print x
(缩写为
px
)检查变量
x
,而在Lisp中,您只需键入
x
,即可对其进行计算

以下是一些简单的例子:

步 此处
提供了有关可用命令的帮助;如果您的lisp出现问题,请尝试
help
:h

> (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
请注意,步进机内的提示为
step
,其中
level
为嵌套级别

打破 这里的提示是
Break

断言
assert
使用与
break
相同的提示您正在寻找的简单答案由juanitofatas给出。不幸的是,CCL不支持step,因此调试能力较弱。到目前为止,调试的最佳实现是CLISP。

在ccl中,您可以使用
cl步进器:步骤
而不是
cl:步骤


(ql:quickload“com.informatimago.common lisp.lisp.stepper”)

CCL手册和Hyperspec都是很好的参考资料,但我想多学一点手持式,这就是为什么我要求提供教程的原因。谢谢+一个非常详细的答案。但是,当我在CCL(1.8和1.9)中键入
(步骤(阶乘3))
时,我得到的响应是
6
(对3的回答!)——无需单步执行。@Olie:最好在专用CCL邮件列表中询问此CCL特定问题。我的猜测是,要么CCL只支持单步执行已解释的函数,要么编译了
阶乘
,要么这是CCL中的错误。CCL不支持单步执行。因此,应删除上述答案,因为它具有误导性。CCLCCL不支持步骤。我投反对票是出于怨恨,不是基于证据。下面得到6张赞成票的答案是完全错误的。
> (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
> (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