Hello,
Assume you have inferior kawa scheme started as detailed in the beginning of file swank-kawa.scm. Now switch to the *inferior-lisp* buffer and do:
M-: (slime-inferior-connect (get-buffer-process (current-buffer)) \ (slime-inferior-lisp-args (get-buffer-process (current-buffer))))
You should see the following error, which disallows one to restart the swank server. Any fix? Thanks in advance.
Leo
#|kawa:6|# (begin (load "/Users/leo/Desktop/swank-kawa/swank-kawa.zip") (start-swank "/tmp/.leo-tmp-1850X_/slime.37612")) Thread[Thread-16,5,main] #|kawa:7|# connection: Socket[addr=/127.0.0.1,port=60557,localport=60556] listener: Thread[swank-listener,5,main] 936197591 chan@3970ae0 #<environment r13> attaching: 37892 20 attaching2: com.sun.jdi.ProcessAttach (defaults: pid=, timeout=) {pid=pid=37892, timeout=timeout=20} closing socket: ServerSocket[addr=0.0.0.0/0.0.0.0,port=0,localport=60556] exception in thread Thread[swank,5,main]: java.lang.Error: mcase failed tmp (chan@1b50f0a7 (error "java.io.IOException: Unable to determine transport endpoint" "IOException" ("com.sun.tools.jdi.ProcessAttachingConnector.attach(ProcessAttachingConnector.java:98)" "swank$Mnkawa.attach(swank-kawa.scm:1756)" "swank$Mnkawa.vmAttach(swank-kawa.scm:1736)" "swank$Mnkawa.vmMonitor(swank-kawa.scm:1272)" "swank$Mnkawa.apply1(swank-kawa.scm:1270)" "gnu.expr.ModuleBody.applyN(ModuleBody.java:235)" "swank$Mnkawa.applyN(swank-kawa.scm:978)" "gnu.expr.ModuleMethod.applyN(ModuleMethod.java:216)" "gnu.kawa.functions.ApplyToArgs.applyN(ApplyToArgs.java:139)" "gnu.mapping.ProcedureN.apply2(ProcedureN.java:39)" "swank$Mnkawa$frame36.lambda60(swank-kawa.scm:1985)" "swank$Mnkawa$frame36.apply1(swank-kawa.scm:1983)" "gnu.expr.ModuleBody.applyN(ModuleBody.java:235)" "gnu.expr.ModuleMethod.applyN(ModuleMethod.java:216)" "gnu.kawa.functions.ApplyToArgs.applyN(ApplyToArgs.java:139)" "gnu.mapping.ProcedureN.apply2(ProcedureN.java:39)" "swank$Mnkawa$frame35.lambda59(swank-kawa.scm:1976)" "swank$Mnkawa$frame35.apply0(swank-kawa.scm:1976)" "gnu.expr.ModuleBody.applyN(ModuleBody.java:233)" "gnu.expr.ModuleMethod.applyN(ModuleMethod.java:216)" "gnu.kawa.functions.ApplyToArgs.applyN(ApplyToArgs.java:139)" "gnu.mapping.ProcedureN.apply1(ProcedureN.java:31)" "swank$Mnkawa$frame33.lambda56(swank-kawa.scm:1879)" "swank$Mnkawa$frame33.apply0(swank-kawa.scm:1878)" "gnu.expr.ModuleMethod.apply0(ModuleMethod.java:186)" "gnu.mapping.RunnableClosure.run(RunnableClosure.java:78)" "java.lang.Thread.run(Thread.java:680)")))java.lang.Error: mcase failed tmp (chan@1b50f0a7 (error "java.io.IOException: Unable to determine transport endpoint" "IOException" ("com.sun.tools.jdi.ProcessAttachingConnector.attach(ProcessAttachingConnector.java:98)" "swank$Mnkawa.attach(swank-kawa.scm:1756)" "swank$Mnkawa.vmAttach(swank-kawa.scm:1736)" "swank$Mnkawa.vmMonitor(swank-kawa.scm:1272)" "swank$Mnkawa.apply1(swank-kawa.scm:1270)" "gnu.expr.ModuleBody.applyN(ModuleBody.java:235)" "swank$Mnkawa.applyN(swank-kawa.scm:978)" "gnu.expr.ModuleMethod.applyN(ModuleMethod.java:216)" "gnu.kawa.functions.ApplyToArgs.applyN(ApplyToArgs.java:139)" "gnu.mapping.ProcedureN.apply2(ProcedureN.java:39)" "swank$Mnkawa$frame36.lambda60(swank-kawa.scm:1985)" "swank$Mnkawa$frame36.apply1(swank-kawa.scm:1983)" "gnu.expr.ModuleBody.applyN(ModuleBody.java:235)" "gnu.expr.ModuleMethod.applyN(ModuleMethod.java:216)" "gnu.kawa.functions.ApplyToArgs.applyN(ApplyToArgs.java:139)" "gnu.mapping.ProcedureN.apply2(ProcedureN.java:39)" "swank$Mnkawa$frame35.lambda59(swank-kawa.scm:1976)" "swank$Mnkawa$frame35.apply0(swank-kawa.scm:1976)" "gnu.expr.ModuleBody.applyN(ModuleBody.java:233)" "gnu.expr.ModuleMethod.applyN(ModuleMethod.java:216)" "gnu.kawa.functions.ApplyToArgs.applyN(ApplyToArgs.java:139)" "gnu.mapping.ProcedureN.apply1(ProcedureN.java:31)" "swank$Mnkawa$frame33.lambda56(swank-kawa.scm:1879)" "swank$Mnkawa$frame33.apply0(swank-kawa.scm:1878)" "gnu.expr.ModuleMethod.apply0(ModuleMethod.java:186)" "gnu.mapping.RunnableClosure.run(RunnableClosure.java:78)" "java.lang.Thread.run(Thread.java:680)"))) at swank$Mnkawa.ferror$V(swank-kawa.scm:979) at swank$Mnkawa.dispatchEvents(swank-kawa.scm:406) at swank$Mnkawa.setupServer(swank-kawa.scm:363) at swank$Mnkawa$frame.lambda3(swank-kawa.scm:354) at swank$Mnkawa$frame.apply0(swank-kawa.scm:353) at gnu.expr.ModuleBody.applyN(ModuleBody.java:233) at gnu.expr.ModuleMethod.applyN(ModuleMethod.java:216) at gnu.kawa.functions.ApplyToArgs.applyN(ApplyToArgs.java:139) at gnu.mapping.ProcedureN.apply1(ProcedureN.java:31) at swank$Mnkawa$frame33.lambda56(swank-kawa.scm:1879) at swank$Mnkawa$frame33.apply0(swank-kawa.scm:1878) at gnu.expr.ModuleMethod.apply0(ModuleMethod.java:186) at gnu.mapping.RunnableClosure.run(RunnableClosure.java:78) at java.lang.Thread.run(Thread.java:680)
#|kawa:8|#
* Leo [2011-08-04 11:44] writes:
Hello,
Assume you have inferior kawa scheme started as detailed in the beginning of file swank-kawa.scm. Now switch to the *inferior-lisp* buffer and do:
M-: (slime-inferior-connect (get-buffer-process (current-buffer)) \ (slime-inferior-lisp-args (get-buffer-process (current-buffer))))
I assume you do something like
shell# rlwrap java7 -Xss450k -cp /opt/java/current/lib/tools.jar:/scratch/kawa -agentlib:jdwp=transport=dt_socket,server=y,suspend=n kawa.repl -s Listening for transport dt_socket at address: 39670 #|kawa:1|# (require "/home/helmut/lisp/slime/contrib/swank-kawa.scm") #|kawa:2|# (create-swank-server 4005)
Then in Emacs M-x slime-connect followed by M-x slime-disconnect. Then again in the terminal:
#|kawa:3|# (create-swank-server 4005)
You should see the following error, which disallows one to restart the swank server. Any fix? Thanks in advance.
A little background info: the swank server uses the JVM debugging tools in roundabout way. Swank connects to the debugging agent running in the same JVM; essentially one JVM debugs itself. As instructed by the command line option -agentlib, the JVM opens a socket (on port 39670 in the example above). Later we attach to it. Once we are connected nothing is listening on that port. On Linux you can verify that with netstat -tlnp. Since nothing is listening we get the "Unable to determine transport endpoint" exception.
A fix would probably not attach twice, but instead store the vm mirror in a global variable and reuse it as needed.
This patch seems to work:
--- a/contrib/swank-kawa.scm +++ b/contrib/swank-kawa.scm @@ -1267,7 +1267,7 @@
(df vm-monitor ((c <chan>)) (! set-name (current-thread) "swank-vm-monitor") - (let ((vm (vm-attach))) + (let ((vm :: <vm> (or *the-vm* (vm-attach)))) (log-vm-props vm) (request-breakpoint vm) (mlet* (((ev . _) (spawn/chan/catch
Helmut
On 2011-08-04 22:29 +0800, Helmut Eller wrote:
I assume you do something like
shell# rlwrap java7 -Xss450k -cp /opt/java/current/lib/tools.jar:/scratch/kawa -agentlib:jdwp=transport=dt_socket,server=y,suspend=n kawa.repl -s Listening for transport dt_socket at address: 39670 #|kawa:1|# (require "/home/helmut/lisp/slime/contrib/swank-kawa.scm") #|kawa:2|# (create-swank-server 4005)
This was exactly how I started swank. But it does not run in the background. How to stop swank and go back to the REPL?
Another issue I noticed is after leaving emacs idle for a while, surprisingly there appear out of nowhere two pending requests to the swank server. I can't figure out a way to restart the swank server without restarting kawa.
My current setup is adding a 'kawa entry to 'slime-lisp-implementations and M-- M-x slime RET kawa RET (just like suggested in swank-kawa.scm).
But if I disconnect slime-repl (using the repl shortcut ,disconnect) from the inferior swank server, that seems to also stop the swank server.
So I eval in emacs
M-: (slime-inferior-connect (get-buffer-process (current-buffer)) \ (slime-inferior-lisp-args (get-buffer-process (current-buffer))))
to restart the swank server and have the slime-repl buffer open up again. This now works perfectly with your patch.
One inconvenience with the Kawa swank server is it does not respond to slime-interrupt. Is there a workaround?
Thank you very much for your informative answer.
[snipped 36 lines]
Leo
* Leo [2011-08-04 18:16] writes:
On 2011-08-04 22:29 +0800, Helmut Eller wrote:
I assume you do something like
shell# rlwrap java7 -Xss450k -cp /opt/java/current/lib/tools.jar:/scratch/kawa -agentlib:jdwp=transport=dt_socket,server=y,suspend=n kawa.repl -s Listening for transport dt_socket at address: 39670 #|kawa:1|# (require "/home/helmut/lisp/slime/contrib/swank-kawa.scm") #|kawa:2|# (create-swank-server 4005)
This was exactly how I started swank. But it does not run in the background.
You could start it in a new thread: (future (create-swank-server 4005))
How to stop swank and go back to the REPL?
I never implemented a clean shutdown/restart. Restarting the whole JVM was mostly good enough for me (and is almost unavoidable from time to time).
Another issue I noticed is after leaving emacs idle for a while, surprisingly there appear out of nowhere two pending requests to the swank server. I can't figure out a way to restart the swank server without restarting kawa.
That could be a bug triggered by SPC and swank tries to find some arglist but somehow fails along the way.
It could also be a bug in JDI. Hard to say exactly.
My current setup is adding a 'kawa entry to 'slime-lisp-implementations and M-- M-x slime RET kawa RET (just like suggested in swank-kawa.scm).
This might be useful:
(defun kawa () (interactive) (slime 'kawa))
This way M-x kawa starts the 'kawa entry from slime-lisp-implementations.
But if I disconnect slime-repl (using the repl shortcut ,disconnect) from the inferior swank server, that seems to also stop the swank server.
So I eval in emacs
M-: (slime-inferior-connect (get-buffer-process (current-buffer)) \ (slime-inferior-lisp-args (get-buffer-process (current-buffer))))
to restart the swank server and have the slime-repl buffer open up again. This now works perfectly with your patch.
One inconvenience with the Kawa swank server is it does not respond to slime-interrupt. Is there a workaround?
slime-interrupt should work to some degree. E.g we can interrupt and continue this example:
(define (foo) (let loop () (loop))) (foo)
Sometimes it takes a long time until the JVM stops the thread. E.g.
(define (foo) (foo))
There may also be bugs in Swank that prevent it from working in some cases.
Helmut
On 2011-08-05 04:18 +0800, Helmut Eller wrote:
You could start it in a new thread: (future (create-swank-server 4005))
Thanks.
I never implemented a clean shutdown/restart. Restarting the whole JVM was mostly good enough for me (and is almost unavoidable from time to time).
Thanks for the note.
That could be a bug triggered by SPC and swank tries to find some arglist but somehow fails along the way.
It could also be a bug in JDI. Hard to say exactly.
OK, I can ignore it for now.
This might be useful:
(defun kawa () (interactive) (slime 'kawa))
This way M-x kawa starts the 'kawa entry from slime-lisp-implementations.
Thanks.
slime-interrupt should work to some degree. E.g we can interrupt and continue this example:
(define (foo) (let loop () (loop))) (foo)
Sometimes it takes a long time until the JVM stops the thread. E.g.
(define (foo) (foo))
This was exactly the same one I tried. Good to know C-c C-b (slime-interrupt) works in some cases.
Thank you very much. Now swank-kawa is much more usable.
Leo