从调试器中进入 sbcl

Stepping in sbcl from within the debugger

我正在尝试弄清楚如何在使用 break 之类的东西调用调试器后单步执行 sbcl 和 Slime 中的代码。我不想从头开始。例如,如果我有以下代码:

(defun fib (n)
  (when (eql n 2)
    (break))
  (if (<= 0 n 1)
      n
      (+ (fib (- n 1))
         (fib (- n 2)))))

遇到断点后,我希望能够开始单步执行代码。我找到的唯一方法是遍历 Slime 中的框架,使用 "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 手动步进

can be invoked via the step macro, or from within the debugger.

我是 运行 sbcl 1.2.5 和 Slime 2.12,我的优化质量都是 1,除了安全和调试都是 3。

我在调试设置为 3 的情况下编译了 swank。因此,当我在 break 之后单步执行时,它会进入 swank,给出所描述的奇怪行为。

自从我开始学习 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 但据我所知,这没有用。)

更新:

"After the break point is hit, I want to be able to start stepping through the code. The only way I have found to do this, is to go over the frame in Slime, use the "Return From Frame" (R) feature, and type in (step (fib 2))."

您实际上可以直接按 s 继续!无需 Return From Frame,只需在中断发生后按 s 即可。请注意,要使其正常工作,您的初始化文件中必须包含 (proclaim (optimize (debug 3)))(例如 .sbclrc)