Debugging 如何在Common LISP上使用Emacs内置调试器查看局部变量?

Debugging 如何在Common LISP上使用Emacs内置调试器查看局部变量?,debugging,common-lisp,sbcl,slime,backtrace,Debugging,Common Lisp,Sbcl,Slime,Backtrace,我正在用sbcl和slime在iMac上编写公共LISP代码。 我可以通过在代码行之间插入(中断)或调用(step)函数来调用Emacs内置调试器。下面是调试过程的一个步骤 Restarts: 0: [STEP-CONTINUE] Resume normal execution 1: [STEP-OUT] Resume stepping after returning from this function 2: [STEP-NEXT] Step over call 3: [STEP-IN

我正在用sbcl和slime在iMac上编写公共LISP代码。 我可以通过在代码行之间插入(中断)或调用(step)函数来调用Emacs内置调试器。下面是调试过程的一个步骤

Restarts:
 0: [STEP-CONTINUE] Resume normal execution
 1: [STEP-OUT] Resume stepping after returning from this function
 2: [STEP-NEXT] Step over call
 3: [STEP-INTO] Step into call
 4: [RETRY] Retry SLIME REPL evaluation request.
 5: [*ABORT] Return to SLIME's top level.
 --more--

Backtrace:
  0: ((LABELS RECURSE :IN PARTIAL-EVAL) X)
      Locals:
        BINDINGS = ((A . 3) (X . 0) (Y . 2))
        EXP = X
        #:G0 = X
  1: (SB-KERNEL:%MAP-TO-LIST-ARITY-1 #<CLOSURE (LABELS RECURSE :IN PARTIAL-EVAL) {1002A9614B}> (A X (- C C) (- 9 9) (+ Z (/ A 3 #) (- Y # Z))))
  2: ((LABELS RECURSE :IN PARTIAL-EVAL) (- A X (- C C) (- 9 9) (+ Z (/ A 3 #) (- Y # Z))))
      Locals:
        ARGS#1 = (A X (- C C) (- 9 9) (+ Z (/ A 3 (/ B)) (- Y (* A 1) Z)))
        BINDINGS = ((A . 3) (X . 0) (Y . 2))
        EXP = (- A X (- C C) (- 9 9) (+ Z (/ A 3 (/ B)) (- Y (* A 1) Z)))
        #:G0 = (- A X (- C C) (- 9 9) (+ Z (/ A 3 (/ B)) (- Y (* A 1) Z)))
        #:G5 = (A X (- C C) (- 9 9) (+ Z (/ A 3 (/ B)) (- Y (* A 1) Z)))
        OP = -
  3: (SB-KERNEL:%MAP-TO-LIST-ARITY-1 #<CLOSURE (LABELS RECURSE :IN PARTIAL-EVAL) {1002A9614B}> (1 (- A X (- C C) (- 9 9) (+ Z # #))))
  4: ((LABELS RECURSE :IN PARTIAL-EVAL) (/ 1 (- A X (- C C) (- 9 9) (+ Z # #))))
      Locals:
        ARGS#1 = (1 (- A X (- C C) (- 9 9) (+ Z (/ A 3 #) (- Y # Z))))
        BINDINGS = ((A . 3) (X . 0) (Y . 2))
        EXP = (/ 1 (- A X (- C C) (- 9 9) (+ Z (/ A 3 #) (- Y # Z))))
        #:G0 = (/ 1 (- A X (- C C) (- 9 9) (+ Z (/ A 3 #) (- Y # Z))))
        #:G5 = (1 (- A X (- C C) (- 9 9) (+ Z (/ A 3 #) (- Y # Z))))
        OP = /
  5: (PARTIAL-EVAL (/ 1 (- A X (- C C) (- 9 9) (+ Z # #))) ((A . 3) (X . 0) (Y . 2)))
  6: ((LAMBDA (&REST SB-DI::ARGS) :IN SB-DI::HANDLE-SINGLE-STEP-AROUND-TRAP) (/ 1 (- A X (- C C) (- 9 9) (+ Z # #))) ((A . 3) (X . 0) (Y . 2)))
  7: ((LAMBDA ()))
  8: (SB-INT:SIMPLE-EVAL-IN-LEXENV (LET ((SB-IMPL::*STEP-OUT* :MAYBE)) (UNWIND-PROTECT (SB-IMPL::WITH-STEPPING-ENABLED #))) #S(SB-KERNEL:LEXENV :FUNS NIL :VARS NIL :BLOCKS NIL :TAGS NIL :TYPE-RESTRICTIONS ..
  9: (SB-INT:SIMPLE-EVAL-IN-LEXENV (STEP (PARTIAL-EVAL (QUOTE #) (QUOTE #))) #<NULL-LEXENV>)
 10: (EVAL (STEP (PARTIAL-EVAL (QUOTE #) (QUOTE #))))
 --more--
重新启动:
0:[步骤-继续]恢复正常执行
1:[步出]从此功能返回后恢复步进
2:[下一步]分步呼叫
3:[进入]进入呼叫
4:[重试]重试SLIM REPL评估请求。
5:[*中止]返回SLIME的顶层。
--更多--
回溯:
0:((标签递归:部分求值)X)
当地人:
绑定=((A.3)(X.0)(Y.2))
EXP=X
#:G0=X
1:(SB内核:%MAP-TO-LIST-ARITY-1#(ax(-cc)(-9)(+Z(/a3#)(-Y#Z)))
2:((标签递归:部分求值)(-ax(-cc)(-99)(+Z(/a3-)(-Y-)))
当地人:
ARGS#1=(ax(-cc)(-9)(+Z(/a3(/B))(-Y(*a1)Z)))
绑定=((A.3)(X.0)(Y.2))
EXP=(-ax(-cc)(-99)(+Z(/a3(/B))(-Y(*a1)Z)))
#:G0=(-ax(-cc)(-99)(+Z(/a3(/B))(-Y(*a1)Z)))
#:G5=(ax(-cc)(-99)(+Z(/a3(/B))(-Y(*a1)Z)))
OP=-
3:(SB内核:%MAP-TO-LIST-ARITY-1#(1(-ax(-cc)(-9)(+Z#))
4:((标签递归:部分求值)(/1(-ax(-cc)(-9)(+Z###))
当地人:
ARGS#1=(1(-ax(-cc)(-99)(+Z(/a3#)(-Y#Z)))
绑定=((A.3)(X.0)(Y.2))
EXP=(/1(-ax(-cc)(-99)(+Z(/a3-)(-Y-))
#:G0=(/1(-ax(-cc)(-99)(+Z(/a3-)(-Y-))
#:G5=(1(-ax(-cc)(-99)(+Z(/a3-)(-Y-))
OP=/
5:(部分评估(/1(-ax(-cc)(-99)(+Z###))((A.3)(X.0)(Y.2)))
6:((LAMBDA(&REST SB-DI::ARGS):在SB-DI::HANDLE-SINGLE-STEP-AROUND-TRAP中)(/1(-ax(-cc)(-9)(+Z##))((A.3)(X.0)(Y.2)))
7:((LAMBDA()))
8:(SB-INT:SIMPLE-EVAL-IN-lexev(LET((SB-IMPL:*STEP-OUT*:MAYBE))(UNWIND-PROTECT(SB-IMPL::WITH-STEP-ENABLED#)))#S(SB-KERNEL:lexev:FUNS-NIL:VARS-NIL:BLOCKS-NIL:TAGS-NIL:TYPE-RESTRICTIONS。。
9:(SB-INT:SIMPLE-EVAL-IN-lexev(步骤(部分评估)(引号#)(引号#)))
10:(评估(步骤(部分评估)
--更多--

当我展开每个堆栈时,我可以跟踪和查看一些局部变量,但不是所有的局部变量。我如何将这些缺少的局部变量添加到监视列表中?当我使用其他IDE时,监视变量非常容易,但使用Emacs时,我找不到如何执行此操作。

编译器可能会优化某些内容,从而隐藏中间变量晚一点,你可以试试

(declaim (optimize (speed 0) (space 0) (debug 3)))
(并重新编译代码)


您还谈到了“watch”调试器函数:它在SBCL中不可用,但在其他实现(如LispWorks)中可用。

编译器可能会优化某些内容,从而隐藏中间变量。您可以尝试

(declaim (optimize (speed 0) (space 0) (debug 3)))
(并重新编译代码)


您还谈到了一个“监视”调试器函数:它在SBCL中不可用,但在其他实现(如LispWorks)中可用.

正如我在评论中所说,一种可能性是调试器中没有出现的变量尚未绑定。例如,在像
LET
这样的内部构造中,当引入几个词法变量并将其绑定到某个值时,如果调试器中只显示了其中的几个,这可能意味着错误发生在n未显示第一个变量初始化形式的计算


当然,这也取决于运行时系统(编译器或解释器),因此,遵循Evhince的建议并适当设置优化选项是一个好主意。

正如我在一篇评论中所说的,可能是调试器中未出现的变量尚未绑定。例如,在内部构造(如
LET
)中,当引入多个词法变量并将其绑定到som时如果调试器中只显示了其中的几个变量,这可能意味着在计算未显示的第一个变量的初始化形式时出错


当然,这也取决于运行时系统(编译器或解释器),因此,遵循Evhince的建议并适当设置优化选项是一个好主意。

它不是Emacs的内置调试器。它是GNU Emacs中的SLIME调试器。如果你能找到一个可复制的代码示例,并且在回溯中看不到哪些变量,这将非常有用。我不知道SBCL是否也是如此,但当我调试CCL程序时,通常调试器中未出现的变量尚未绑定,因此这是错误发生的另一个提示(就在绑定第一个缺少的变量之前)。这段代码在本周二之前应该是私有的,很抱歉现在无法上载,但我将在下周上载,以显示调试器中现在显示的变量是哪个代码。@Renzo,因为绑定的所有变量都将显示在调试器中,所以slime调试器不提供“监视”功能。我明白了吗?@imgnpoints,我想是的。对于t例如,他在let中定义了变量,如果只显示了其中的一部分,这意味着错误出现在以下变量的初始化中。这不是Emacs的内置调试器。这是GNU Emacs中的SLIME调试器。如果您能找到一个可复制的代码示例,并且在后面看不到哪些变量,这将非常有用我不知道SBCL是否也是这样,但是当我调试CCL程序时,通常没有出现在调试器中的变量还没有绑定,所以这是发生错误的另一个提示(就在绑定第一个缺少的变量之前)。此代码在本周二之前都是私有的,很抱歉现在无法上载,但是