[slime-devel] Debugging SBCL...

Nikodemus Siivola nikodemus at random-state.net
Thu Mar 25 22:10:44 UTC 2010


On 25 March 2010 23:18, Andrei Stebakov <lispercat at gmail.com> wrote:
> I am trying to debug a web app (based on hunchentoot and weblocks).
> Let's say I have a function
>
> (defun test-func(a)
>   (let ((b 1)
>         (c 2))
>     (break)))
>
> I call this (test-func 0) from (defun weblocks-dispatcher (request) ....)
> When I hit break, am I supposed to see a, b and c as local variables in the
> frame?
> All I can see is the request parameter of weblocks-dispatcher and not even
> the frame for test-func, what I am missing?

It all comes down to: "Use a higher debug level."

Either use DEBUG 2 -- or 3, if you really want the maximum info, but 3
has both notable runtime and compile-time costs in SBCL.

In addition to having a low debug-level, you're not seeing the frame
in your example because BREAK has been tail-called. Changing the code
to

 (defun test-func(a)
   (let ((b 1)
         (c 2))
     (break)
     t))

gets rid of the tail call, so you see the frame:

  0: (BREAK "break")
  1: (TEST-FUNC #<unavailable argument>)
      Locals:
        SB-DEBUG::ARG-0 = :<NOT-AVAILABLE>
  2: (SB-INT:SIMPLE-EVAL-IN-LEXENV (TEST-FUNC 1) #<NULL-LEXENV>)

Also, since the values are never used the variables are optimized
away. Changing the code to

(defun test-func (a)
  (let ((b (+ a 1))
        (c (+ a 2)))
    (break)
    (+ a b c)))

gets you

  1: (TEST-FUNC 1)
      Locals:
        SB-DEBUG::ARG-0 = 1
  2: (SB-INT:SIMPLE-EVAL-IN-LEXENV (TEST-FUNC 1) #<NULL-LEXENV>)

-- you're still missing the name of the argument, and B and C have
been optimized away as they are used only once. The code has been
compiled as if you had written (+ a (+ a 1) (+ a 2)) instead of (+ a b
c).

Debug 2 is enough to sort that out:

(defun test-func (a)
  (declare (optimize (debug 2)))
  (let ((b (+ a 1))
        (c (+ a 2)))
    (break)
    (+ a b c)))

  0: (BREAK "break")
  1: (TEST-FUNC 1)
      Locals:
        A = 1
        B = 2
        C = 3
  2: (SB-INT:SIMPLE-EVAL-IN-LEXENV (TEST-FUNC 1) #<NULL-LEXENV>)

...but you see, already the higher debug level is starting to cost in
the form of elided optimizations -- but for many applications DEBUG 2
is a nice halfway house.

Cheers,

 -- Nikodemus




More information about the slime-devel mailing list