[gambit-list] Non-REPL Debugging in Gambit

Marc Feeley feeley at iro.umontreal.ca
Tue Aug 28 12:10:45 EDT 2007


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)




More information about the Gambit-list mailing list