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

时间:2013-08-07 01:43:54

标签: debugging common-lisp

我在Mac上使用CCL(1.8.1 - 本文中的最新版本),并想知道是否有任何类型的调试教程可用。

我特别感兴趣的是在我的代码中的某处设置一个断点,然后戳戳&刺激各种值,然后单步执行下一行代码,检查更多值等等。

修改 我已经阅读了CCL手册(18.3及其左右)的调试部分,但对它没有多大意义。我来自C / Java /等。后台和基于IDE的源代码级调试器,只需稍微暴露一下gdb。

所以我想我正在寻找的是一个介绍/教程,它将引导我完成一些简单的步骤。

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

谢谢!

3 个答案:

答案 0 :(得分:8)

我确信CCL用户可能会指向Debugging section in the CCL manual,但事实上,ANSI Common Lisp标准包含出色的调试工具,包括您询问的breakstepstep的粒度不是基于一行代码而是基于一种形式)。

事实上,整个Condition System值得研究。

还有一个few tutorials

最重要的是要记住,调试工具为您提供了正常的Lisp REPL(读取 - 评估 - 打印循环),您可以使用初始REPL执行任何操作:定义函数和变量,检查现有的变量(包括在输入调试器的函数中定义的变量)等。 此外,您可以在步进器中发出其他命令,例如stepnext(通常缩写为:s:n)或{ {1}}(通常缩写continue)为可持续错误。

您需要注意的一个区别是,在:c中,您使用gdb(缩写为x)检查变量print x,而在Lisp中只需键入{{1}并且它被评估。

以下是一些简单的例子:

步骤

这里p x提供有关可用命令的帮助;如果你的lisp barfs,请尝试x?

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>

此处提示为level

断言

> (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

Break <level>使用与> (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 相同的提示。

答案 1 :(得分:4)

您正在寻找的简单答案由juanitofatas提供。不幸的是,CCL不支持步骤,因此在调试方面很弱。到目前为止,调试的最佳实现是CLISP。

答案 2 :(得分:1)

在ccl中,您可以使用cl-stepper:step代替cl:step

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