On 1-Jul-09, at 12:07 AM, James Long wrote:
Hey Marc (and other Gambit folks, I realized this would be good for the gambit list too),
Your remote debugger is awesome. However, it travels further into the land of Gambit IO than I know. I'm having one problem with it (I got the latest version of it).
I found a rather concise example of the problem. It seems that when two errors happen close enough in time, one remote debugger pops open with the correct error, and another pops open with this error:
*** ERROR IN rdi-open-client, "Users/james/projects/scheme/gambit-iphone-example/lib/util/remote- debugger/rdi.scm"@108.5 -- Broken pipe (force-output '#<input-output-port #3 (tcp-client "localhost" 20000)>)
You can get it to do this by just doing this in the debugee:
(thread-start! (make-thread (lambda () (/ 1 0))))
(thread-start! (make-thread (lambda () (/ 1 0))))
Would you mind looking at it?
I couldn't reproduce this on Mac OS X. It looks like a race condition.
As a separate subject, as I was integrating the remote debugger with my iphone app, I realized I can not only have access to the debugger from the iphone, but I can also fire up a main REPL and interactively develop from my main computer on the iphone! That is very cool.
It puts the "remote" in "remote debugger"!
Now, I can't call (##repl-debug-main) in the primordial thread, as your proof of concept does, because the main thread is the program which needs to continue executing. So, my first attempt fired up the REPL from a child thread instead:
(thread-start! (make-thread (lambda () (##repl-debug-main))))
Do you see any problems with this? This seems to work fine (a real Gambit REPL pops open in an xterm when the app start in the iphone simulator). This got me thinking too: what is the relationship between stdin and stdout and the main REPL? It seems that standard output is somehow redirected to this REPL. Rather, if I call DISPLAY on any other thread it somehow appears in my above REPL. How is that so?
There are several ports that have a similarity with the concepts of "standard input" and "standard output". Here is a breakdown:
##stdin-port actual standard input of the process ##stdout-port actual standard output of the process (current-input-port) current input port (current-output-port) current output port (repl-input-port) this thread's REPL input port (repl-output-port) this thread's REPL output port (console-port) the console's bidirectional port
The REPL input/output ports are normally connected to the console (/ dev/tty on Unix, a Windows console on Windows, etc). When a thread calls (##repl-debug-main) the parameter objects current-input-port and current-output-port are dynamically bound to the REPL input/output ports, for the duration of the REPL. This explains why a (display "foo") will output to the console (because the port parameter of display defaults to (current-output-port) as requested by the Scheme standard). Note that when a thread is created with make-thread it inherits the current-input-port and current-output-port bindings of the parent thread, that's why display's output will go to the REPL of the thread that called ##repl-debug-main, if the thread is a descendant of that thread.
Note that the default port for "pp" is the repl-output-port. This is consistent with pp's debugging purpose. So I suggest you try to limit yourself to using pp, or explicitly pass (repl-output-port) to the output procedure you are using when debugging.
Marc