在调试器中从sbcl步进

7
我试图弄清如何在 sbcl 和 Slime 中通过 break 调用调试器后逐步执行代码。我不想从开头开始一步一步地走。例如,如果我有以下代码:
(defun fib (n)
  (when (eql n 2)
    (break))
  (if (<= 0 n 1)
      n
      (+ (fib (- n 1))
         (fib (- n 2)))))

断点被触发后,我希望能够逐步执行代码。我找到的唯一方法是在 Slime 中跳过 frame,使用“Return From Frame” (R) 功能,并输入 (step (fib 2))。

当我尝试使用“Step” (s) 功能时,不是实际逐步执行,而是显示:

Evaluating call:
  (CONTINUE)
With arguments:
   [Condition of type STEP-FORM-CONDITION]

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: [ABORT] Return to sldb level 1.
 5: [CONTINUE] Return from BREAK.
 --more--

Backtrace:
  0: (SWANK:SLDB-STEP 0)
  1: (SB-INT:SIMPLE-EVAL-IN-LEXENV (SWANK:SLDB-STEP 0) #<NULL-LEXENV>)
  2: (EVAL (SWANK:SLDB-STEP 0))
  3: (SWANK:EVAL-FOR-EMACS (SWANK:SLDB-STEP 0) "COMMON-LISP-USER" 122)
  4: ((FLET #:FORM-FUN-7055 :IN SWANK::SLDB-LOOP))
  5: (SWANK::SLDB-LOOP 1)
  6: ((LAMBDA NIL :IN SWANK::DEBUG-IN-EMACS))
  7: ((FLET SWANK/BACKEND:CALL-WITH-DEBUGGING-ENVIRONMENT :IN "/home/michael/slime/swank/sbcl.lisp") #<FUNCTION (LAMBDA NIL :IN SWANK::DEBUG-IN-EMACS) {1003DB44CB}>)

我希望您能够做到这一点,从sbcl手册 stepping 可以通过step宏或在调试器中实现。我正在运行sbcl 1.2.5与Slime 2.12,我的优化质量都是1,除了安全和调试,它们都是3。

1
这个问题似乎与上下文无关,听起来像是一个错误或支持请求。你尝试在Freenode的IRC #lisp频道或SLIME的邮件列表中询问了吗?这似乎与SBCL没有直接关系,因为你似乎没有尝试在没有SLIME的情况下进行调试。 - acelent
2个回答

2

自从开始学习Common Lisp以来,我一直在努力尝试使步骤调试起作用。在阅读了这篇优美的教程Debugging with SLIME后,我想再给步骤调试器一次机会......

以下是我重新编译swank的步骤(在尝试之前请先阅读完):

在终端中启动一个新的SBCL会话:

rlwrap sbcl
ran the following
(declaim (optimize (debug 0)))
(asdf:load-system :swank :force t)
; then i noticed in the messages that it doesn't compile all the files
; compiling file "/home/smokeink/quicklisp/dists/quicklisp/software/slime-2.14/swank-loader.lisp"
; /home/smokeink/.cache/common-lisp/sbcl-1.3.0-linux-x64/home/smokeink/quicklisp/dists/quicklisp/software/slime-2.14/swank-loader-TMP.fasl written
; then i tried:
(compile-file "~/.emacs.d/elpa/slime-20150623.821/swank.lisp")
; compiling...
; ~/.emacs.d/elpa/slime-20150623.821/swank.fasl written

那个方法不起作用,所以我采取了另一种方法,我在swank.lisp中添加了以下内容:
; ...
(in-package :swank)
; added the following line
(declaim (optimize (debug 0)))
; ...

重新启动了slime,它重新编译了几个文件,然后按预期工作了。
(请注意,在执行上述操作之前,我还更改了)
(declaim (optimize (debug 2)
                   (sb-c::insert-step-conditions 0)
                   (sb-c::insert-debug-catch 0)))
to
(declaim (optimize (debug 0)
                   (sb-c::insert-step-conditions 0)
                   (sb-c::insert-debug-catch 0)))

在 swank/sbcl.lisp 中做的更改对单步调试问题没有影响。我还尝试在 .sbclrc 中设置 (declaim (optimize (debug 0))),然后重新启动 Slime,但据我所记得,那并没有起作用。

更新:

"打上断点后,我想能够逐步执行代码。我找到的唯一方法是在 Slime 中走过这个帧,使用“Return From Frame”(R)功能,并键入(step (fib 2))。"

你实际上可以直接按 s 键!不需要 Return From Frame,打断点后直接按 s 即可。请注意,为了使此方法有效,你必须在初始化文件(例如 .sbclrc)中加入 (proclaim (optimize (debug 3)))


2

我已将swank编译且调试级别设置为3。因此,当我在断点后进行步进时,它会继续步进到swank中,导致出现所描述的奇怪行为。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接