Hey Marc (and other relevant readers),
I found a bug with the remote debugger. At the end of a session with a client (the running program), when the client exits and disconnects from the remote debugger, the server halts with a "deadlock detection." This seems to always happen with any program, so I wonder if others are experiencing this.
I think I figured out what's going on, and I'm offering a fix. If anyone has any opinions, let me know.
The relevant changes affect how the server reads incoming connections. Before, it would create a server using OPEN-TCP-SERVER, wait for an initial connection, and establish the connection and then use THREAD-JOIN! from the primordial thread (thread A) to the writer thread (thread B) to wait for everything to finish. It seems like the design was to only have the server handle one client and then quit. The problem with this is that thread B wasn't terminated properly, and it sits there waiting for messages using THREAD-RECEIVE, while thread A is waiting for it to finish. Essentially, when the network connections quit and those threads die, you are left with thread A and B in a deadlocked situation.
(That probably only makes sense to those who have studied Marc's remote debugger, which might only be Marc.)
There are 2 solutions:
1. On the server, kill the writer thread at the appropriate time. This is probably when it receives the message that the reader thread has died, meaning that the client connection was lost. The server would simply exit.
2. Change the server so that it loops and continually accepts new client connections. It would only exit with a ^C.
I think #2 is better server design. It seems like it should stay open, continually accepting new connections. This makes it very usable as simply a background process.
Here are my changes to implement #2. You simple need to replace RDI-OPEN-SERVER with this one:
(define (rdi-open-server rdi) (let ((listen-port (open-tcp-server (list port-number: (rdi-port-num rdi) reuse-address: #t)))) (let loop () (let ((connection (read listen-port))) (let ((request (read connection))) (if (not (equal? request rdi-version1)) (error "unexpected debuggee version") (begin
(write rdi-version2 connection) (force-output connection)
(let ((reader-thread (rdi-create-reader-thread rdi connection))) (rdi-connection-set! rdi connection) (thread-start! reader-thread) (loop)))))))))
Now, the main thread doesn't to use THREAD-JOIN!, but it simply loops forever. So, the call (rdi-force-connection rdi) in debugger.scm never returns, but starts the loop.
I've attached my current version of the remote debugger. It also features a different server interface; you pass in the host/port when running (gsi -:dar,h10000 debugger.scm 20000).
- James
Afficher les réponses par date