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?
Thank you, Andrei
* 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