Wow,
That is exactly what I meant. Now I have great examples to build a sophisticated distributed applications debugging system.
Thank you, Francois Magnan
On 28-Aug-07, at 12:10 PM, Marc Feeley wrote:
On 28-Aug-07, at 10:07 AM, François Magnan wrote:
Thank you both for your answers. Having access to the whole stack (all frames, even if it is long) would be a good addition to the API. It would help the development of some kind of stack inspector I will eventually try to add to the Schemeway plugin for use with Gambit.
That will be neat.
Is there also an easy way to start a REPL in a separate terminal when an exception occurs in some thread. This would help debug Termite applications a lot.
By "terminal" you mean something like xterm? The example "web- repl" implements a terminal using Java. If you want a new xterm to pop up in each thread that encounters an error you can try out the following code. Just put it in the file gambcini.scm and start Gambit with
gsi -:dar
(otherwise only the primordial thread will pop-up an xterm).
Marc
(define (open-console title)
(define (open-xterm) (open-process (list path: "xterm" arguments: (list "-Sz/0" "-T" title) pseudo-terminal: #t)))
(define (input-handler console-port pipe)
;; implement line buffering with editing (backspace) (read-line console-port) ;; get rid of xterm info (let loop1 () (let loop2 ((line '())) (let ((c (read-char console-port))) (if (char? c) (cond ((char=? c #\backspace) (if (null? line) (begin (write-char (integer->char 7) console-port) (force-output console-port) (loop2 line)) (begin (write-char #\backspace console-port) (write-char #\space console-port) (write-char #\backspace console-port) (force-output console-port) (loop2 (cdr line))))) ((or (char=? c #\return) (char=? c #\linefeed)) (write-char #\return console-port) (write-char #\linefeed console-port) (force-output console-port) (display (list->string (reverse line)) pipe) (newline pipe) (force-output pipe) (loop1)) (else (write-char c console-port) (force-output console-port) (loop2 (cons c line)))))))))
(define (output-handler console-port pipe) (let loop1 () (let ((c (read-char pipe))) (if (char? c) (cond ((char=? c #\newline) (write-char #\return console-port) (write-char #\linefeed console-port) (force-output console-port) (loop1)) (else (write-char c console-port) (force-output console-port) (loop1)))))))
(receive (pipe1 pipe2) (open-string-pipe) (let ((console-port (open-xterm)))
(thread-start! (make-thread (lambda () (input-handler console-port pipe2)))) (thread-start! (make-thread (lambda () (output-handler console-port pipe2)))) pipe1)))
(define (make-repl-channel) (let ((port (open-console (object->string (current-thread))))) (##make-repl-channel-ports port port)))
(set! ##thread-make-repl-channel make-repl-channel)