Hi!
One of the last CVS updates somehow managed to break slime-edit-definition for me. Sometimes, if I press M-. to go to a function's definition Emacs hangs completely, CPU load goes up to 100%, C-g doesn't work anymore, and I have to kill both Emacs and the Lisp to continue. Needless to say, this is highly annoying.
I'd like to come up with a simple test case but unfortunately this only happens sometimes and when it happens it's too late to debug it.
I've seen this with CMUCL 19a as well as with AllegroCL 7.0, Emacs is FSF 21.3 on Linux.
Am I the only one?
Thanks, Edi.
Edi Weitz edi@agharta.de writes:
One of the last CVS updates somehow managed to break slime-edit-definition for me. Sometimes, if I press M-. to go to a function's definition Emacs hangs completely, CPU load goes up to 100%, C-g doesn't work anymore, and I have to kill both Emacs and the Lisp to continue. Needless to say, this is highly annoying.
This is news to me. Great to have a tricky one to make life interesting before a proposed new release too, I hate it when everything works :-)
Please put something like this in your .swank.lisp:
(setq swank::*log-output* (open "/tmp/log.txt" :direction :output)) (setq swank:*log-events* t)
and then save and post the log file the next time this happens.
Luke Gorrie luke@synap.se writes:
Please put something like this in your .swank.lisp:
(setq swank::*log-output* (open "/tmp/log.txt" :direction :output)) (setq swank:*log-events* t)
and then save and post the log file the next time this happens.
.. or at least an exerpt near the end. I don't know the sort of things you talk about with your Lisp image and I'm not sure that I want to know.. :-)
Cheers, Luke
On 05 Mar 2005 11:34:59 +0100, Luke Gorrie luke@synap.se wrote:
.. or at least an exerpt near the end. I don't know the sort of things you talk about with your Lisp image and I'm not sure that I want to know.. :-)
You'll be surprised... :)
On 05 Mar 2005 11:29:07 +0100, Luke Gorrie luke@synap.se wrote:
Please put something like this in your .swank.lisp:
(setq swank::*log-output* (open "/tmp/log.txt" :direction :output)) (setq swank:*log-events* t)
and then save and post the log file the next time this happens.
OK, will do.
On 05 Mar 2005 11:29:07 +0100, Luke Gorrie luke@synap.se wrote:
Please put something like this in your .swank.lisp:
(setq swank::*log-output* (open "/tmp/log.txt" :direction :output)) (setq swank:*log-events* t)
and then save and post the log file the next time this happens.
OK, I think I now have a reproducible test case although it involves a rather large system using various third-party libraries.
It turns out that if I wait long enough SLIME returns and I don't have to kill Emacs.
The offending part of the log file looks like this (imagine a very long pause between the first lines where slime-edit-definition is invoked and the rest):
READ: (:emacs-rex (swank:find-definitions-for-emacs "get-projects-for-costs") ":acc" t 7)
DISPATCHING: (:EMACS-REX (SWANK:FIND-DEFINITIONS-FOR-EMACS "get-projects-for-costs") ":acc" T 7) DISPATCHING: (:DEBUG #<Process Idle Loop {58004595}> 1 ("Heap (dynamic space) overflow" " [Condition of type KERNEL:HEAP-OVERFLOW]" NIL NIL) (("ABORT" "Abort handling SLIME request.") ("CONTINUE" "Return NIL from load of "home:.cmucl-init".") ("ABORT" "Skip remaining initializations.")) ((0 "((METHOD SWANK-BACKEND:CALL-WITH-DEBUGGING-ENVIRONMENT NIL (T)) #<#1=unused-arg> #<#1#> #<Function "DEFUN DEBUG-IN-EMACS" {59CFEEF1}>)") (1 "(SWANK::CALL-WITH-BINDINGS ((*PRINT-PRETTY*) (*PRINT-LEVEL* . 4) (*PRINT-LENGTH* . 10) (*PRINT-CIRCLE* . T) (*PRINT-READABLY*) ...) #<Function "DEFUN DEBUG-IN-EMACS" {59CFEEB1}>)") (2 "(SWANK::DEBUG-IN-EMACS #<KERNEL:HEAP-OVERFLOW {77F0003D}>)") (3 "(INVOKE-DEBUGGER #<KERNEL:HEAP-OVERFLOW {77F0003D}>)") (4 "(ERROR KERNEL:HEAP-OVERFLOW)") (5 "(KERNEL:DYNAMIC-SPACE-OVERFLOW-WARNING-HIT)")) (7)) WRITE: (:debug 0 1 ("Heap (dynamic space) overflow" " [Condition of type KERNEL:HEAP-OVERFLOW]" nil nil) (("ABORT" "Abort handling SLIME request.") ("CONTINUE" "Return NIL from load of "home:.cmucl-init".") ("ABORT" "Skip remaining initializations.")) ((0 "((METHOD SWANK-BACKEND:CALL-WITH-DEBUGGING-ENVIRONMENT NIL (T)) #<#1=unused-arg> #<#1#> #<Function "DEFUN DEBUG-IN-EMACS" {59CFEEF1}>)") (1 "(SWANK::CALL-WITH-BINDINGS ((*PRINT-PRETTY*) (*PRINT-LEVEL* . 4) (*PRINT-LENGTH* . 10) (*PRINT-CIRCLE* . T) (*PRINT-READABLY*) ...) #<Function "DEFUN DEBUG-IN-EMACS" {59CFEEB1}>)") (2 "(SWANK::DEBUG-IN-EMACS #<KERNEL:HEAP-OVERFLOW {77F0003D}>)") (3 "(INVOKE-DEBUGGER #<KERNEL:HEAP-OVERFLOW {77F0003D}>)") (4 "(ERROR KERNEL:HEAP-OVERFLOW)") (5 "(KERNEL:DYNAMIC-SPACE-OVERFLOW-WARNING-HIT)")) (7)) DISPATCHING: (:DEBUG-ACTIVATE #<Process Idle Loop {58004595}> 1) WRITE: (:debug-activate 0 1) READ: (:emacs-rex (swank:backtrace 1 40) nil 0 8)
DISPATCHING: (:EMACS-REX (SWANK:BACKTRACE 1 40) NIL 0 8) DISPATCHING: (:RETURN #<Process Idle Loop {58004595}> (:OK ((1 "(SWANK::CALL-WITH-BINDINGS ((*PRINT-PRETTY*) (*PRINT-LEVEL* . 4) (*PRINT-LENGTH* . 10) (*PRINT-CIRCLE* . T) (*PRINT-READABLY*) ...) #<Function "DEFUN DEBUG-IN-EMACS" {59CFEEB1}>)") (2 "(SWANK::DEBUG-IN-EMACS #<KERNEL:HEAP-OVERFLOW {77F0003D}>)") (3 "(INVOKE-DEBUGGER #<KERNEL:HEAP-OVERFLOW {77F0003D}>)") (4 "(ERROR KERNEL:HEAP-OVERFLOW)") (5 "(KERNEL:DYNAMIC-SPACE-OVERFLOW-WARNING-HIT)"))) 8) WRITE: (:return (:ok ((1 "(SWANK::CALL-WITH-BINDINGS ((*PRINT-PRETTY*) (*PRINT-LEVEL* . 4) (*PRINT-LENGTH* . 10) (*PRINT-CIRCLE* . T) (*PRINT-READABLY*) ...) #<Function "DEFUN DEBUG-IN-EMACS" {59CFEEB1}>)") (2 "(SWANK::DEBUG-IN-EMACS #<KERNEL:HEAP-OVERFLOW {77F0003D}>)") (3 "(INVOKE-DEBUGGER #<KERNEL:HEAP-OVERFLOW {77F0003D}>)") (4 "(ERROR KERNEL:HEAP-OVERFLOW)") (5 "(KERNEL:DYNAMIC-SPACE-OVERFLOW-WARNING-HIT)"))) 8) DISPATCHING: (:DEBUG-ACTIVATE #<Process Idle Loop {58004595}> 1) WRITE: (:debug-activate 0 1) READ: (:emacs-rex (swank:frame-locals-for-emacs 1) nil 0 9)
Here's the debugging info I get from within SLIME:
Heap (dynamic space) overflow [Condition of type KERNEL:HEAP-OVERFLOW]
Restarts: 0: [ABORT] Abort handling SLIME request. 1: [CONTINUE] Return NIL from load of "home:.cmucl-init". 2: [ABORT] Skip remaining initializations.
Backtrace: 0: ((METHOD SWANK-BACKEND:CALL-WITH-DEBUGGING-ENVIRONMENT NIL (T)) #<#1=unused-arg> #<#1#> #<Function "DEFUN DEBUG-IN-EMACS" {59CFEEF1}>) 1: (SWANK::CALL-WITH-BINDINGS ((*PRINT-PRETTY*) (*PRINT-LEVEL* . 4) (*PRINT-LENGTH* . 10) (*PRINT-CIRCLE* . T) (*PRINT-READABLY*) ...) #<Function "DEFUN DEBUG-IN-EMACS" {59CFEEB1}>) Locals: SWANK::ALIST = ((*PRINT-PRETTY*) (*PRINT-LEVEL* . 4) (*PRINT-LENGTH* . 10) (*PRINT-CIRCLE* . T) (*PRINT-READABLY*) (*PRINT-PPRINT-DISPATCH* . #<PRETTY-PRINT::PPRINT-DISPATCH-TABLE {61E70BCD}>) (*PRINT-GENSYM* . T) (*PRINT-BASE* . 10) (*PRINT-RADIX*) (*PRINT-ARRAY* . T) ...) SWANK::FUN = #<Function "DEFUN DEBUG-IN-EMACS" {59CFEEB1}> FUNCTION = #:INVALID C::VALS = #:INVALID C::VARS = #:INVALID [No catch-tags] 2: (SWANK::DEBUG-IN-EMACS #<KERNEL:HEAP-OVERFLOW {77F0003D}>) Locals: CONDITION = #<KERNEL:HEAP-OVERFLOW {77F0003D}> [No catch-tags] 3: (INVOKE-DEBUGGER #<KERNEL:HEAP-OVERFLOW {77F0003D}>) Locals: CONDITION = #<KERNEL:HEAP-OVERFLOW {77F0003D}> FUNCTION = #:INVALID DEBUG::HOOK = #:INVALID [No catch-tags] 4: (ERROR KERNEL:HEAP-OVERFLOW) Locals: CONDITIONS::ARGUMENTS = NIL CONDITION = #:INVALID CONDITIONS::DATUM = KERNEL:HEAP-OVERFLOW CONDITIONS::FRAME = #:INVALID CONDITIONS::NAME = #:INVALID [No catch-tags] 5: (KERNEL:DYNAMIC-SPACE-OVERFLOW-WARNING-HIT) Locals: [No catch-tags]
What seems strange to me is that one of the restarts I get is
Return NIL from load of "home:.cmucl-init".
At that point loading of ~/.cmucl-init should have been history already.
Let me know if you need more info. I can send you the whole code if needed but I don't want to post it to the list - it's big and ugly and part of a commercial project.
Cheers, Edi.
Edi Weitz edi@agharta.de writes:
The offending part of the log file looks like this (imagine a very long pause between the first lines where slime-edit-definition is invoked and the rest):
READ: (:emacs-rex (swank:find-definitions-for-emacs "get-projects-for-costs") ":acc" t 7)
DISPATCHING: (:EMACS-REX (SWANK:FIND-DEFINITIONS-FOR-EMACS "get-projects-for-costs") ":acc" T 7) DISPATCHING: (:DEBUG #<Process Idle Loop {58004595}> 1 ("Heap (dynamic space) overflow" " [Condition of type KERNEL:HEAP-OVERFLOW]" NIL NIL) (("ABORT" "Abort handling SLIME request.") ("CONTINUE" "Return NIL from load of "home:.cmucl-init".") ("ABORT" "Skip remaining initializations.")) ((0 "((METHOD SWANK-BACKEND:CALL-WITH-DEBUGGING-ENVIRONMENT NIL (T)) #<#1=unused-arg> #<#1#> #<Function "DEFUN DEBUG-IN-EMACS" {59CFEEF1}>)") (1 "(SWANK::CALL-WITH-BINDINGS ((*PRINT-PRETTY*) (*PRINT-LEVEL* . 4) (*PRINT-LENGTH* . 10) (*PRINT-CIRCLE* . T) (*PRINT-READABLY*) ...) #<Function "DEFUN DEBUG-IN-EMACS" {59CFEEB1}>)") (2 "(SWANK::DEBUG-IN-EMACS #<KERNEL:HEAP-OVERFLOW {77F0003D}>)") (3 "(INVOKE-DEBUGGER #<KERNEL:HEAP-OVERFLOW {77F0003D}>)") (4 "(ERROR KERNEL:HEAP-OVERFLOW)") (5 "(KERNEL:DYNAMIC-SPACE-OVERFLOW-WARNING-HIT)")) (7))
.. yikes :-)
Perhaps you can fire up a stand-alone Lisp and try calling:
(swank:find-definitions-for-emacs "get-projects-for-costs")
and see if it drops you into a debugger where you can do some decent poking around? Probably worth whacking it with a SIGINT to see what it's upto during the long pause.
On 05 Mar 2005 21:35:25 +0100, Luke Gorrie luke@synap.se wrote:
Perhaps you can fire up a stand-alone Lisp and try calling:
(swank:find-definitions-for-emacs "get-projects-for-costs")
and see if it drops you into a debugger where you can do some decent poking around? Probably worth whacking it with a SIGINT to see what it's upto during the long pause.
Unfortunately I can't reproduce the problem if I'm not within Emacs. (FWIW, I loaded swank-loader.lisp, then loaded my system with ASDF and finally evaluated the form above. That's what you wanted me to do, right?)
However, as another data point, I seem to come closer to a reproducible case: The problem only surfaces if I had to compile the system anew before invoking slime-edit-definition, i.e. if I removed all *.x86f files before loading the system with ASDF. So maybe some information that SLIME collects during compilation is the culprit?
(Still trying to play detective...)
Cheers, Edi.
Edi Weitz edi@agharta.de writes:
However, as another data point, I seem to come closer to a reproducible case: The problem only surfaces if I had to compile the system anew before invoking slime-edit-definition, i.e. if I removed all *.x86f files before loading the system with ASDF. So maybe some information that SLIME collects during compilation is the culprit?
Have you tried 'kill -INT <pid>' on Lisp when it starts going nuts? Would be interesting to see the backtrace before heap explosion occurs.
BTW: I got a lot of compile problems related to foreign functions when I tried to asdf-install clsql into CMU19a. Any ideas?
On 05 Mar 2005 22:40:34 +0100, Luke Gorrie luke@synap.se wrote:
BTW: I got a lot of compile problems related to foreign functions when I tried to asdf-install clsql into CMU19a. Any ideas?
Works fine here (although I didn't use ASDF-INSTALL). What are these problems?
On 05 Mar 2005 22:40:34 +0100, Luke Gorrie luke@synap.se wrote:
Have you tried 'kill -INT <pid>' on Lisp when it starts going nuts? Would be interesting to see the backtrace before heap explosion occurs.
Here it is. I've expanded the interesting frames further down below. Does that help?
Interrupted at #x10044616. [Condition of type SIMPLE-CONDITION]
Restarts: 0: [CONTINUE] Return from BREAK. 1: [ABORT] Abort handling SLIME request. 2: [ABORT] Return to Top-Level.
Backtrace: 0: (UNIX::SIGINT-HANDLER #<#1=unused-arg> #<#1#> #.(SYSTEM:INT-SAP #x3FFFB728)) 1: (UNIX::SIGINT-HANDLER 3 #<#1=unused-arg> #<#1#> #.(SYSTEM:INT-SAP #x3FFFB728))[:EXTERNAL] 2: ("call_into_lisp+#x8C [#x805495C] /usr/bin/lisp") 3: ("funcall3+#x32 [#x8054768] /usr/bin/lisp") 4: ("interrupt_handle_now+#xFB [#x8050070] /usr/bin/lisp") 5: ("interrupt_handle_pending+#xB9 [#x804FF6E] /usr/bin/lisp") 6: ("sigtrap_handler+#xE6 [#x8054566] /usr/bin/lisp") 7: ((FLET #:G24 LISP::SUB-GC))[:CLEANUP] 8: (LISP::SUB-GC :VERBOSE-P NIL :FORCE-P NIL ...) 9: (LISP::MAYBE-GC NIL) 10: ("call_into_lisp+#x8C [#x805495C] /usr/bin/lisp") 11: ("funcall0+#x27 [#x80546DE] /usr/bin/lisp") 12: ("alloc+#xDF [#x805D9E6] /usr/bin/lisp") 13: ("alloc_overflow_edx+#xE [#x8054B62] /usr/bin/lisp") 14: (LISP::READ-MAYBE-NOTHING #<String-Input Stream> #[) 15: (LISP::READ-LIST #<String-Input Stream> #<unused-arg>) 16: (LISP::READ-MAYBE-NOTHING #<String-Input Stream> #() 17: (LISP::READ-LIST #<String-Input Stream> #<unused-arg>) 18: (LISP::READ-MAYBE-NOTHING #<String-Input Stream> #() 19: (LISP::READ-LIST #<String-Input Stream> #<unused-arg>) 20: (LISP::READ-PRESERVING-WHITESPACE-INTERNAL #<String-Input Stream> T NIL T) 21: (LISP::READ-PRESERVING-WHITESPACE-INTERNAL #<String-Input Stream> T NIL NIL) 22: (LISP::READ-PRESERVING-WHITESPACE-INTERNAL 4 #<String-Input Stream> T NIL ...)[:EXTERNAL] 23: (LISP::READ-INTERNAL #<String-Input Stream> T NIL NIL) 24: (READ #<String-Input Stream> T NIL NIL) 25: (SWANK-BACKEND::READ-SOURCE-FORM 4 #<String-Input Stream>) 26: (SWANK-BACKEND::FORM-NUMBER-STREAM-POSITION 4 0 #<String-Input Stream>) 27: (SWANK-BACKEND::CODE-LOCATION-STREAM-POSITION #<Compiled-Code-Location GET-PROJECTS-FOR-COSTS> #<String-Input Stream>) 28: (SWANK-BACKEND::LOCATION-IN-FILE #1="/tmp/foo/foo1.lisp" #<Compiled-Code-Location GET-PROJECTS-FOR-COSTS> #S(C::DEBUG-SOURCE :FROM :FILE :NAME #1# :COMMENT NIL :CREATED 3319048151 :COMPILED 3319052075 ...)) 29: (SWANK-BACKEND::CODE-LOCATION-SOURCE-LOCATION #<Compiled-Code-Location GET-PROJECTS-FOR-COSTS>) 30: (SWANK-BACKEND::FUNCTION-DEFINITIONS GET-PROJECTS-FOR-COSTS) 31: ((METHOD SWANK-BACKEND:FIND-DEFINITIONS NIL (T)) #<#1=unused-arg> #<#1#> GET-PROJECTS-FOR-COSTS) 32: (SWANK:FIND-DEFINITIONS-FOR-EMACS "get-projects-for-costs") 33: ("DEFUN EVAL-FOR-EMACS") 34: ((METHOD SWANK-BACKEND:CALL-WITH-DEBUGGER-HOOK NIL (T T)) #<#1=unused-arg> #<#1#> #<Function SWANK:SWANK-DEBUGGER-HOOK {588825D1}> #<Closure Over Function "DEFUN EVAL-FOR-EMACS" {5892C8D1}>) 35: ("DEFUN HANDLE-REQUEST") 36: (SWANK::CALL-WITH-REDIRECTED-IO #<SWANK::CONNECTION {58A52B65}> #<Function "DEFUN HANDLE-REQUEST" {58762091}>) 37: (SWANK::HANDLE-REQUEST #<SWANK::CONNECTION {58A52B65}>) 38: (SWANK::PROCESS-AVAILABLE-INPUT #<Stream for descriptor 6> #<Closure Over Function "DEFUN INSTALL-SIGIO-HANDLER" {5892BF19}>) 39: ((FLET SWANK::HANDLER SWANK::INSTALL-SIGIO-HANDLER)) 40: (SWANK-BACKEND::SIGIO-HANDLER #<#1=unused-arg> #<#1#> #<#1#>) 41: ("call_into_lisp+#x8C [#x805495C] /usr/bin/lisp") 42: ("funcall3+#x32 [#x8054768] /usr/bin/lisp") 43: ("interrupt_handle_now+#xFB [#x8050070] /usr/bin/lisp") 44: ("NIL+#x80504B7 [#x80504B7] /usr/bin/lisp") 45: ("NIL+#x4006D678 [#x4006D678] /lib/libc.so.6") 46: (SYSTEM:WAIT-UNTIL-FD-USABLE 0 :INPUT NIL) 47: (LISP::DO-INPUT #<Stream for Standard Input>) 48: (LISP::INPUT-CHARACTER #<Stream for Standard Input> NIL (LISP::*EOF*)) 49: (LISP::SYNONYM-IN #<Synonym Stream to SYSTEM:*STDIN*> NIL (LISP::*EOF*)) 50: (LISP::TWO-WAY-IN #<Two-Way Stream, Input = #<Synonym Stream to SYSTEM:*STDIN*>, Output = #<Synonym Stream to SYSTEM:*STDOUT*>> NIL (LISP::*EOF*)) 51: (LISP::SYNONYM-IN #<Synonym Stream to SWANK::*CURRENT-STANDARD-INPUT*> NIL (LISP::*EOF*)) 52: (READ-CHAR #<Synonym Stream to SWANK::*CURRENT-STANDARD-INPUT*> NIL (LISP::*EOF*) NIL) 53: (LISP::READ-PRESERVING-WHITESPACE-INTERNAL #<Synonym Stream to SWANK::*CURRENT-STANDARD-INPUT*> NIL (:EOF) T) 54: (LISP::READ-PRESERVING-WHITESPACE-INTERNAL #<Synonym Stream to SWANK::*CURRENT-STANDARD-INPUT*> NIL (:EOF) NIL) 55: (LISP::READ-PRESERVING-WHITESPACE-INTERNAL 4 #<Synonym Stream to SWANK::*CURRENT-STANDARD-INPUT*> NIL (:EOF) ...)[:EXTERNAL] 56: (LISP::READ-INTERNAL #<Synonym Stream to SWANK::*CURRENT-STANDARD-INPUT*> NIL (:EOF) NIL) 57: (READ #<Synonym Stream to SWANK::*CURRENT-STANDARD-INPUT*> NIL (:EOF) NIL) 58: (LISP::%TOP-LEVEL) 59: ((LABELS LISP::RESTART-LISP EXTENSIONS:SAVE-LISP))
14: (LISP::READ-MAYBE-NOTHING #<String-Input Stream> #[) Locals: ARRAY = #:INVALID CHAR = #[ LISP::RETVAL = #:INVALID STREAM = #<String-Input Stream> [No catch-tags]
15: (LISP::READ-LIST #<String-Input Stream> #<unused-arg>) Locals: ARRAY = #:INVALID ARRAY#1 = #:INVALID LISP::FIRSTCHAR = #:INVALID LISP::LISTOBJ = #:INVALID LISP::LISTTAIL = (NIL) LISP::NEXTCHAR = #:INVALID LISP::RT = #:INVALID STREAM = #<String-Input Stream> LISP::THELIST = (NIL NIL (QUOTE NIL) NIL NIL NIL NIL NIL NIL NIL ...) [No catch-tags]
16: (LISP::READ-MAYBE-NOTHING #<String-Input Stream> #() Locals: ARRAY = #:INVALID CHAR = #( LISP::RETVAL = #:INVALID STREAM = #<String-Input Stream> [No catch-tags]
17: (LISP::READ-LIST #<String-Input Stream> #<unused-arg>) Locals: ARRAY = #:INVALID ARRAY#1 = #:INVALID LISP::FIRSTCHAR = #:INVALID LISP::LISTOBJ = #:INVALID LISP::LISTTAIL = (NIL) LISP::NEXTCHAR = #:INVALID LISP::RT = #:INVALID STREAM = #<String-Input Stream> LISP::THELIST = (NIL NIL) [No catch-tags]
18: (LISP::READ-MAYBE-NOTHING #<String-Input Stream> #() Locals: ARRAY = #:INVALID CHAR = #( LISP::RETVAL = #:INVALID STREAM = #<String-Input Stream> [No catch-tags]
19: (LISP::READ-LIST #<String-Input Stream> #<unused-arg>) Locals: ARRAY = #:INVALID ARRAY#1 = #:INVALID LISP::FIRSTCHAR = #:INVALID LISP::LISTOBJ = #:INVALID LISP::LISTTAIL = ((NIL)) LISP::NEXTCHAR = #:INVALID LISP::RT = #:INVALID STREAM = #<String-Input Stream> LISP::THELIST = (NIL NIL NIL (NIL)) [No catch-tags]
20: (LISP::READ-PRESERVING-WHITESPACE-INTERNAL #<String-Input Stream> T NIL T) Locals: ARRAY = #:INVALID ARRAY#1 = #:INVALID CHAR = #:INVALID LISP::EOF-ERRORP = T LISP::EOF-VALUE = NIL LISP::RECURSIVEP = T LISP::RESULT = #:INVALID LISP::RT = #:INVALID STREAM = #<String-Input Stream> [No catch-tags]
21: (LISP::READ-PRESERVING-WHITESPACE-INTERNAL #<String-Input Stream> T NIL NIL) Locals: ARRAY = #:INVALID ARRAY#1 = #:INVALID CHAR = #:INVALID LISP::EOF-ERRORP = T LISP::EOF-VALUE = NIL LISP::RECURSIVEP = NIL LISP::RESULT = #:INVALID LISP::RT = #:INVALID STREAM = #<String-Input Stream> [No catch-tags]
22: (LISP::READ-PRESERVING-WHITESPACE-INTERNAL 4 #<String-Input Stream> T NIL ...)[:EXTERNAL] Locals: #:G2 = 4 #:G3 = #<String-Input Stream> #:G4 = T #:G5 = NIL #:G6 = NIL [No catch-tags]
23: (LISP::READ-INTERNAL #<String-Input Stream> T NIL NIL) Locals: ARRAY = #:INVALID LISP::EOF-ERRORP = T LISP::EOF-VALUE = NIL LISP::RECURSIVEP = NIL LISP::RT = #:INVALID STREAM = #<String-Input Stream> LISP::WHITECHAR = #:INVALID [No catch-tags]
24: (READ #<String-Input Stream> T NIL NIL) Locals: LISP::EOF-ERRORP = T LISP::EOF-VALUE = NIL LISP::RECURSIVEP = NIL STREAM = #<String-Input Stream> [No catch-tags]
25: (SWANK-BACKEND::READ-SOURCE-FORM 4 #<String-Input Stream>) Locals: SWANK-BACKEND::I = 3 SWANK-BACKEND::N = 4 STREAM = #<String-Input Stream> [No catch-tags]
26: (SWANK-BACKEND::FORM-NUMBER-STREAM-POSITION 4 0 #<String-Input Stream>) Locals: ARRAY = #:INVALID SWANK-BACKEND::FORM-NUMBER = 0 SWANK-BACKEND::PATH-TABLE = #:INVALID SWANK-BACKEND::POSITION-MAP = #:INVALID STREAM = #<String-Input Stream> SWANK-BACKEND::TLF = #:INVALID SWANK-BACKEND::TLF-NUMBER = 4 [No catch-tags]
27: (SWANK-BACKEND::CODE-LOCATION-STREAM-POSITION #<Compiled-Code-Location GET-PROJECTS-FOR-COSTS> #<String-Input Stream>) Locals: SWANK-BACKEND::CODE-LOCATION = #<Compiled-Code-Location GET-PROJECTS-FOR-COSTS> SWANK-BACKEND:LOCATION = #:INVALID SWANK-BACKEND::POS = #:INVALID STREAM = #<String-Input Stream> [No catch-tags]
28: (SWANK-BACKEND::LOCATION-IN-FILE #1="/tmp/foo/foo1.lisp" #<Compiled-Code-Location GET-PROJECTS-FOR-COSTS> #S(C::DEBUG-SOURCE :FROM :FILE :NAME #1# :COMMENT NIL :CREATED 3319048151 :COMPILED 3319052075 ...)) Locals: SWANK-BACKEND::CODE-LOCATION = #<Compiled-Code-Location GET-PROJECTS-FOR-COSTS> SWANK-BACKEND::DEBUG-SOURCE = #S(C::DEBUG-SOURCE :FROM :FILE :NAME "/tmp/foo/foo1.lisp" :COMMENT NIL :CREATED 3319048151 :COMPILED 3319052075 :SOURCE-ROOT 0 :START-POSITIONS #(0 88 224 341 386) :INFO NIL) SWANK-BACKEND::FILENAME = "/tmp/foo/foo1.lisp" SWANK-BACKEND::S = #<String-Input Stream> [No catch-tags]
29: (SWANK-BACKEND::CODE-LOCATION-SOURCE-LOCATION #<Compiled-Code-Location GET-PROJECTS-FOR-COSTS>) Locals: SWANK-BACKEND::C = #:INVALID SWANK-BACKEND::CODE-LOCATION = #<Compiled-Code-Location GET-PROJECTS-FOR-COSTS> [No catch-tags]
30: (SWANK-BACKEND::FUNCTION-DEFINITIONS GET-PROJECTS-FOR-COSTS) Locals: FUNCTION = #:INVALID SWANK-BACKEND::NAME = GET-PROJECTS-FOR-COSTS [No catch-tags]
31: ((METHOD SWANK-BACKEND:FIND-DEFINITIONS NIL (T)) #<#1=unused-arg> #<#1#> GET-PROJECTS-FOR-COSTS) Locals: SWANK-BACKEND::NAME = GET-PROJECTS-FOR-COSTS [No catch-tags]
32: (SWANK:FIND-DEFINITIONS-FOR-EMACS "get-projects-for-costs") Locals: SWANK::DSPEC = #:INVALID ERROR = #:INVALID SWANK::LOC = #:INVALID SWANK::NAME = "get-projects-for-costs" SWANK::SEXP = #:INVALID [No catch-tags]
More data points:
1. I thought this was reproducible but it isn't... :(
2. The reason for all this may be that SLIME (or CMUCL?) gets confused by CLSQL's reader syntax. What happens is that I look for the definition of GET-PROJECTS-FOR-COSTS but SLIME (if it doesn't hang) "finds" the definition for GET-PROJECTS which is two top-level forms off. The relevant part of the code looks like this:
#.(clsql:locally-enable-sql-reader-syntax)
(defun get-project (id) (first (db-select 'project :where [= [id] id])))
(defun get-projects () (db-select 'project))
#.(clsql:restore-sql-reader-syntax-state)
(defun get-projects-for-costs () (sort (let ((parent-hash (make-hash-table)) (projects (get-projects))) (dolist (project projects) (setf (gethash (parent-id project) parent-hash) t)) (loop for project in projects unless (gethash (id project) parent-hash) collect project)) #'project<))
3. In my ~/.cmucl-init I have the form
(mp::startup-idle-and-top-level-loops)
at the end. This could be the reason for the strange restart I got offered.
4. My initial suspicion was that this behaviour is due to a recent SLIME update. However, if it really is due to CLSQL's syntax that would also be an explanation because I only recently started using this syntax. (And I also did it in another project involving AllegroCL which might explain that I have similar problems with Franz' implementation.)
Nevertheless, the fact that usage of this syntax can potentially kill Emacs/SLIME makes me kind of nervous...
Cheers, Edi.
Edi Weitz edi@agharta.de writes:
More data points:
I thought this was reproducible but it isn't... :(
The reason for all this may be that SLIME (or CMUCL?) gets confused by CLSQL's reader syntax. What happens is that I look for the definition of GET-PROJECTS-FOR-COSTS but SLIME (if it doesn't hang) "finds" the definition for GET-PROJECTS which is two top-level forms off. The relevant part of the code looks like this:
#.(clsql:locally-enable-sql-reader-syntax)
Interesting idiom! And I don't think it will play well with our source-path-finder binding *READ-SUPPRESS* to T because this seems to prevent #. from having an effect.
How about if you tweak swank-source-path-parser.lisp to not bind *READ-SUPPRESS* to T?
I don't really see how this would lead to a heap explosion one way or the other but for that I think my last suggestion of running outside SLIME and prodding the definition-finder manually.
What happens if you remove that binding in swank-source-path-parser.lisp?
Nevertheless, the fact that usage of this syntax can potentially kill Emacs/SLIME makes me kind of nervous...
I thought it wasn't killing Emacs after all?
Luke Gorrie luke@synap.se writes:
#.(clsql:locally-enable-sql-reader-syntax)
Interesting idiom! And I don't think it will play well with our source-path-finder binding *READ-SUPPRESS* to T because this seems to prevent #. from having an effect.
In fact it would be very bad without the *READ-SUPPRESS* because then we might read/eval the 'enable' and then find the definition and stop before reaching the 'disable', leaving the syntax globally changed.
CMUCL's own debugger will have one or the other of these problems with it too methinks.
I wonder what Kent Pitman would say about all this..
On 05 Mar 2005 22:25:45 +0100, Luke Gorrie luke@synap.se wrote:
I wonder what Kent Pitman would say about all this..
/Please/ don't ask him....
On 05 Mar 2005 22:14:15 +0100, Luke Gorrie luke@synap.se wrote:
Edi Weitz edi@agharta.de writes:
#.(clsql:locally-enable-sql-reader-syntax)
Interesting idiom!
In defense I can say that this isn't /my/ idiom - it is recommended here:
http://clsql.b9.com/manual/locally-enable-sql-reader-syntax.html
I thought it wasn't killing Emacs after all?
Well, OK, but almost... :)
Let's say what happens isn't really what you want if you're just hacking away.
Cheers, Edi.
Yo! I think I have a simple test case now:
Environment: CMUCL 19a on Linux x86, FSF Emacs 21.3, SLIME from current CVS, CLSQL 3.1.1.
Get the tarball
http://zappa.agharta.de/foo.tar.gz
and unpack it somewhere. Make sure the directory doesn't contain any FASL (*.x86f) files.
Fire up Emacs and start SLIME. Use ,cd to change into the `foo' directory. Now use ,l to load the FOO system. Open (C-x C-f) the file `foo2.lisp' and move point to the `get-projects-for-costs' line (the last one).
Now press M-. for slime-edit-definition - presto!
Hope that also happens on your machine...
Cheers, Edi.
Edi Weitz edi@agharta.de writes:
Yo! I think I have a simple test case now:
Very interesting indeed.
I have narrowed the test case down far enough to take slime out of the picture:
$ rm *.x86f $ lisp * (asdf:oos 'asdf:load-op :foo) * (let ((*read-suppress* t)) (with-open-file (s "foo1.lisp") (dotimes (i 4) (read s)))) ...hits the error...
i.e. it looks like a bug where clsql's reader syntax doesn't work with *READ-SUPPRESS* but just looking at the code I don't see why this is so. Unfortunately I need to stop here to debug some other code :-)
NB: I want buffer-local syntax as much as the next guy but I think this clsql #.(hack-read-syntax) ... #.(unhack-read-syntax) trick is a bit fragile -- I don't think that tools like SLIME or the CMUCL debugger can really do the right thing with it.
BTW, on my machine it also hangs Emacs but that's just due to swappage as the lisp heap expands. I don't have much ram though.
Cheers, Luke
Luke Gorrie luke@synap.se writes:
Edi Weitz edi@agharta.de writes:
Yo! I think I have a simple test case now:
Very interesting indeed.
P.S. `sldb-inspect-in-frame' gets Emacs command-of-the-year award.
On 05 Mar 2005 23:58:28 +0100, Luke Gorrie luke@synap.se wrote:
I have narrowed the test case down far enough to take slime out of the picture:
$ rm *.x86f $ lisp
- (asdf:oos 'asdf:load-op :foo)
- (let ((*read-suppress* t)) (with-open-file (s "foo1.lisp") (dotimes (i 4) (read s))))
...hits the error...
Same here.
i.e. it looks like a bug where clsql's reader syntax doesn't work with *READ-SUPPRESS* but just looking at the code I don't see why this is so.
I think I've found the answer:
Usually, LISP::TOKEN-DELIMITERP returns NIL for #[, but after CLSQL has modified the readtable this macro returns T:
edi@vmware:/tmp$ cmucl ; Loading #p"/home/edi/.cmucl-init". CMU Common Lisp CVS release-19a 19a-release-20040728 + minimal debian patches, running on vmware With core: /usr/lib/cmucl/lisp.core Dumped on: Thu, 2005-02-10 19:05:48+01:00 on vmware For support see http://www.cons.org/cmucl/support.html Send bug reports to the debian BTS. or to pvaneynd@debian.org type (help) for help, (quit) to exit, and (demo) to see the demos
Loaded subsystems: Python 1.1, target Intel x86 CLOS based on Gerd's PCL 2004/04/14 03:32:47 * (asdf:oos 'asdf:load-op :clsql)
; [blabla]
NIL * (lisp::token-delimiterp #[)
NIL * (clsql:locally-enable-sql-reader-syntax)
* (lisp::token-delimiterp #[)
T
Now, when *READ-SUPPRESS* is true then CMUCL's LISP::READ-TOKEN will call LISP::INTERNAL-READ-EXTENDED-TOKEN which in this case (i.e. when looking at #[) will unread the character from the stream and return immediately. At that point the reader is stuck and will try indefinitely to get past the opening bracket.
Something like that...
NB: I want buffer-local syntax as much as the next guy but I think this clsql #.(hack-read-syntax) ... #.(unhack-read-syntax) trick is a bit fragile -- I don't think that tools like SLIME or the CMUCL debugger can really do the right thing with it.
Yep, everything works fine if I use EVAL-WHEN and a copy of the readtable instead so the case is closed for me. Thanks for your help!
BTW, on my machine it also hangs Emacs but that's just due to swappage as the lisp heap expands. I don't have much ram though.
Get more RAM, it's fun... :)
Cheers, Edi.
On Sat, 5 Mar 2005, Luke Gorrie wrote:
NB: I want buffer-local syntax as much as the next guy but I think this clsql #.(hack-read-syntax) ... #.(unhack-read-syntax) trick is a bit fragile -- I don't think that tools like SLIME or the CMUCL debugger can really do the right thing with it.
In the direction of decrasing fragility:
1. Instead of #.(HACK) one should do
(EVAL-WHEN (:COMPILE-TOPLEVEL :LOAD-TOPLEVEL :EXECUTE) (HACK))
...which would be the macroexpansion of an (IN-SYNTAX :FOO) form.
2. Doing (SETF *READTABLE* (FIND-READTABLE :FOO)) instead of hacking the current one is safer: LOAD and COMPILE-FILE bind *READTABLE*, but by identity it's still the same one.
3. Perhaps most importantly, in the absence of a semi-standard IN-SYNTAX/FIND-READTABLE extension the only thing that can allow environments like Slime to do the even approximately the right thing is using #-style custom read-syntax instead of plain brackets or whatever, as that will signal a read-error which the environment can try to handle.
Just my 0.02EUR
Cheers,
-- Nikodemus Schemer: "Buddha is small, clean, and serious." Lispnik: "Buddha is big, has hairy armpits, and laughs."