[slime-devel] Single-stepping in Slime

Helmut Eller heller at common-lisp.net
Wed Apr 21 16:18:15 UTC 2010


* Andrei Stebakov [2010-04-20 20:45+0200] writes:

> I was never able to use this feature, but I think now it's time to figure it
> out :)
> I have SBCL 1.0.37 on Ubuntu on the server side + latest Slime.
> On the client side GNU Emacs 23.1.50.1on WinXP + latest Slime.
> Connection is established via ssh (putty).
> When I have a function like this:
> (defun test ()
> ? (declare (optimize (debug 3)))
> ? (break)
> ? (let ((a 1)
> ??????? (b 2)
> ??????? (c))
> ???
> ??? (setq c (+ a b))
> ??? (setq c (* a b))))
>
> When I evaluate it and the debugger stops at the (break), can I step through
> the code using the "s" command watching c assuming different values?
> Currently when I press "s" the function just executes non-stop and returns
> the value.
> What should I expect from a single-step debugging in Slime and how can I
> enable it?

SBCL's stepper works by instrumenting: at certain points it inserts
essentially (signal 'step-condition ...).  Slime handles that almost
like a normal condition the only difference is that it automatically
highlights the source form.

The points where the compiler inserts instrumentation code are function
calls.  But it's decided somewhat late in the compilation pipeline
especially after constant folding.  In your case everything gets folded
and no call remains.  If you look at disassembled function you'll see
that there's only a #<fdefinition break> but no #<fdefinition *>.  Those
fdefinition things are needed to make named calls.

A debugger for say C would stop at statement boundaries, but Lisp has
no real "statements" so it's not so clear where to stop.  IF expressions
would probably also be a candidate but SBCL doesn't do that right now.
GDB also lets you also stop at line boundaries; that's is even more
complicated to do because it quite difficult to say what the "next" line
in compiled code is.  Stepping to the next ) would probably make some
sense but compiler optimizations and limited debug-info make that hard
to find.

If you insert a call that the compiler can't optimize away, say:

(defun test ()
  (declare (optimize (debug 3)))
  (break)
  (let ((a 1)
        (b 2)
        (c))
    (foo)
    (setq c (+ a b))
    (setq c (* a b))))

then the debugger should pop up right before FOO gets called and
highlight (foo) in the source buffer.

Helmut





More information about the slime-devel mailing list