So I'm trying to get slime and sbcl working together happily. Versions: SBCL 0.8.5.50 (CVS as of 2003/11/23) Slime (CVS as of 2003/11/23)
In order to get slime to work properly, I needed to make two minor modifications to swank-sbcl.lisp and swank.lisp.
The change to swank-sbcl.lisp was to allow SLIME-EDIT-FDEFINITION to work properly. The pathname returned by SWANK:FUNCTION-SOURCE-LOCATION hadn't been resolved via sbcl's LOGICAL-PATHNAME-TRANSLATIONS. Hence, Emacs was sending me to buffers like "SYS:SRC;CODE;DEFMACRO.LISP", rather than "/opt/cvs-trees/sbcl/src/code/defmacro.lisp". Not knowing whether this is even vaguely correct, I added a TRUENAME call as below:
Index: swank-sbcl.lisp =================================================================== RCS file: /project/slime/cvsroot/slime/swank-sbcl.lisp,v retrieving revision 1.26 diff -u -r1.26 swank-sbcl.lisp --- swank-sbcl.lisp 23 Nov 2003 14:16:42 -0000 1.26 +++ swank-sbcl.lisp 23 Nov 2003 17:40:11 -0000 @@ -324,7 +324,7 @@ (pathname (sb-introspect:definition-source-pathname def)) (path (sb-introspect:definition-source-form-path def))) (list :sbcl - :filename (and pathname (namestring pathname)) + :filename (and pathname (namestring (truename pathname))) :position (sb-introspect:definition-source-character-offset def) :path path ;; source-paths depend on the file having been compiled with
The second problem was rather more severe, since swank-sbcl.lisp doesn't define SWANK:EVAL-IN-FRAME, there was a compilation reader error on compiling swank.lisp, specifically:
| compilation aborted because of input error: | READ failure in COMPILE-FILE: | READER-ERROR at 8809 (line 270, column 41) on | #<FILE-STREAM for "file "/opt/cvs-trees/slime/swank.lisp"" {9AFF329}>: | The symbol "EVAL-IN-FRAME" is not external in the SWANK package.
Further, once the slime startup process was almost finished, it entered an infinite loop, which, when interrupted, printed the following error message in *inferior-lisp* buffer:
| ;; Connection to Emacs lost. | ;; [READER-ERROR at 18 (line 1, column 18) on #<SB-IMPL::STRING-INPUT-STREAM | {9D591E9}>: | Symbol "EVAL-STRING" not found in the SWANK package.]
The Elisp debugger output on C-g was:
| Debugger entered--Lisp error: (quit) | (eq (slime-state-name (slime-current-state)) | (quote slime-evaluating-state)) | slime-busy-p() | (while (slime-busy-p) (accept-process-output)) | (let ((debug-on-quit t) (inhibit-quit nil)) | (while (slime-busy-p) (accept-process-output))) | slime-do-eval((swank:getpid) nil (:catch-tag slime-result-76376))
I fixed this by making this modification to swank.lisp:
Index: swank.lisp =================================================================== RCS file: /project/slime/cvsroot/slime/swank.lisp,v retrieving revision 1.64 diff -u -r1.64 swank.lisp --- swank.lisp 23 Nov 2003 14:16:42 -0000 1.64 +++ swank.lisp 23 Nov 2003 17:46:07 -0000 @@ -267,7 +267,7 @@ (continue *swank-debugger-condition*))
(defslimefun eval-string-in-frame (string index) - (to-string (swank-backend:eval-in-frame (from-string string) index))) + (to-string (swank-backend::eval-in-frame (from-string string) index)))
;;;; Evaluation
Whilst this is probably not at all correct, "it works for me".
lawrence mitchell wence@gmx.li writes:
So I'm trying to get slime and sbcl working together happily. Versions: SBCL 0.8.5.50 (CVS as of 2003/11/23) Slime (CVS as of 2003/11/23)
In order to get slime to work properly, I needed to make two minor modifications to swank-sbcl.lisp and swank.lisp.
The change to swank-sbcl.lisp was to allow SLIME-EDIT-FDEFINITION to work properly. The pathname returned by SWANK:FUNCTION-SOURCE-LOCATION hadn't been resolved via sbcl's LOGICAL-PATHNAME-TRANSLATIONS. Hence, Emacs was sending me to buffers like "SYS:SRC;CODE;DEFMACRO.LISP", rather than "/opt/cvs-trees/sbcl/src/code/defmacro.lisp". Not knowing whether this is even vaguely correct, I added a TRUENAME call as below:
[...]
:filename (and pathname (namestring pathname))
:filename (and pathname (namestring (truename pathname)))
This code has been working previously so I wonder if something has changed in SBCL? I'm building the latest now, but have committed the change anyway - thanks!
I also committed some small fixage to the Elisp code for looking up definitions in SBCL when source-form number isn't available and it has to use regexps.
The second problem was rather more severe, since swank-sbcl.lisp doesn't define SWANK:EVAL-IN-FRAME, there was a compilation reader error on compiling swank.lisp, specifically:
[...]
(defslimefun eval-string-in-frame (string index)
- (to-string (swank-backend:eval-in-frame (from-string string) index)))
- (to-string (swank-backend::eval-in-frame (from-string string) index)))
Whoops, something I broke yesterday. Applied, thanks again.
Cheers, Luke
Luke Gorrie luke@bluetail.com writes:
This code has been working previously so I wonder if something has changed in SBCL? I'm building the latest now, but have committed the change anyway - thanks!
SBCL quite recently started using logical pathnames to build from. This is because otherwise the pathnames for SBCL functions in a binary distribution will be wrong (e.g. "/tmp/buildroot/usr/src/sbcl/foo.lisp" when you probably wanted "/usr/src/sbcl/foo.lisp")
Unrelatedly, I'm playing with adding SLIME support to Araneida, so that errors caused by HTTP request handlers will spawn sldb. As these happen asynchronously with respect to user input at the repl, it seems that the easiest thing to do is add :debug as a valid transition for the idle state -
--- slime.el 22 Nov 2003 07:44:11 -0000 1.101 +++ slime.el 24 Nov 2003 09:58:29 -0000 @@ -1206,6 +1206,10 @@ ((activate) (assert (= sldb-level 0)) (slime-repl-maybe-prompt)) + ((:debug level condition restarts frames) + (slime-push-state + (slime-debugging-state level condition restarts frames + (current-window-configuration)))) ((:emacs-evaluate form-string package-name continuation) (slime-output-evaluate-request form-string package-name) (slime-push-state (slime-evaluating-state continuation))))
The diff is vs FAIRLY-STABLE. Any comments?
-dan
Daniel Barlow dan@telent.net writes:
Unrelatedly, I'm playing with adding SLIME support to Araneida, so that errors caused by HTTP request handlers will spawn sldb.
Sounds nice indeed :-)
As these happen asynchronously with respect to user input at the repl, it seems that the easiest thing to do is add :debug as a valid transition for the idle state -
I think that's the way to go, patch looks good.
Then on the Lisp side I suppose you need to arrange for a few variables to be bound for the debugger, e.g. *emacs-io* and *buffer-package*, which are usually only bound while serving evaluation requests.
This will be good beyond Araneida. Now that we've taken over the REPL, it makes sense for us take over standard-IO, *debugger-hook*, etc, all the time Emacs is connected, not just during explicit requests. At least as an option.
-Luke
Luke Gorrie luke@bluetail.com writes:
Then on the Lisp side I suppose you need to arrange for a few variables to be bound for the debugger, e.g. *emacs-io* and *buffer-package*, which are usually only bound while serving evaluation requests.
Yes. I'm thinking about adding (araneida:use-slime-debugger) or something, which would be run from *slime-repl* where the appropriate streams are visible. It would save references to said streams and install a debugger hook
I'm guessing that Slime is not going to like it if multiple requests all cause errors and attempt to start the debugger in quick succession. Even if it does or can be made to, I'm unsure that I'd want to use it that way, so some form of locking in the debugger hook would probably be a good idea.
This will be good beyond Araneida. Now that we've taken over the REPL, it makes sense for us take over standard-IO, *debugger-hook*, etc, all the time Emacs is connected, not just during explicit requests. At least as an option.
Beyond a general lack of faith in the layers on layers of stuff that this involves (this might just be my own problem, I'm a software Luddite), I'm still not sure how this would work in the presence of foreign code, which doesn't have Lisp streams to print to, just file descriptors. i think output from that is still going to end up in *inferior-lisp*
-dan
Daniel Barlow dan@telent.net writes:
I'm guessing that Slime is not going to like it if multiple requests all cause errors and attempt to start the debugger in quick succession. Even if it does or can be made to, I'm unsure that I'd want to use it that way, so some form of locking in the debugger hook would probably be a good idea.
Are you running this off SERVE-EVENT or with threads?
The sldb-loop does blocking reads from Emacs, so in a single-threaded setup there is no SERVE-EVENT dispatching during debugging -- the server would freeze until sldb returns. So, on the bright side, there shouldn't be any race conditions :-)
Threads aren't a solved problem in SLIME yet, but if you're planning to debug a multithreaded webserver then now is the time to solve it. I suspect it would be sufficient to have a global lock on the SLIME connection, and to hold that lock throughout debugging - so SLIME is only passed between threads when the connection is idle (as in slime-idle-state).
This will be good beyond Araneida. Now that we've taken over the REPL, it makes sense for us take over standard-IO, *debugger-hook*, etc, all the time Emacs is connected, not just during explicit requests. At least as an option.
Beyond a general lack of faith in the layers on layers of stuff that this involves (this might just be my own problem, I'm a software Luddite), I'm still not sure how this would work in the presence of foreign code, which doesn't have Lisp streams to print to, just file descriptors. i think output from that is still going to end up in *inferior-lisp*
But *inferior-lisp* is under our power - all roads lead to Emacs :-)
You could be right - we can explore this stuff afterwards.
Cheers, Luke