Hi,
Is there an easy way to access the debugging functions of the Gambit REPL in a programmatic way? I would like to call (for example) a function that would give me the equivalent of ",b" and ",e" inside my exception-catcher.
Thank you, Francois Magnan
P.S.: I searched the source code and I found commands like ##cmd-e but I don't know I to use them.
Afficher les réponses par date
On 8/27/07, François Magnan francois.magnan@licef.teluq.uqam.ca wrote:
Is there an easy way to access the debugging functions of the Gambit REPL in a programmatic way? I would like to call (for example) a function that would give me the equivalent of ",b" and ",e" inside my exception-catcher.
Here's a simple example for ##cmd-b :
(define (stack-to-string) (##continuation-capture (lambda (k) (call-with-output-string "" (lambda (port) (##cmd-b 0 k port))))))
If you use something like this inside an exception handler, I suggest you look into the ##display-exception-in-context procedure. It takes as arguments the exception object, the current continuation captured with ##continuation-capture and a port.
Note that you should install the handler using with-exception-handler (and *not* with-exception-catcher) if you want to do this.
Guillaume
On 27-Aug-07, at 7:12 PM, Guillaume Germain wrote:
On 8/27/07, François Magnan francois.magnan@licef.teluq.uqam.ca wrote:
Is there an easy way to access the debugging functions of the Gambit REPL in a programmatic way? I would like to call (for example) a function that would give me the equivalent of ",b" and ",e" inside my exception-catcher.
Here's a simple example for ##cmd-b :
(define (stack-to-string) (##continuation-capture (lambda (k) (call-with-output-string "" (lambda (port) (##cmd-b 0 k port))))))
Here is the set of procedures, defined in lib/_repl.scm, which implement the REPL commands ,b ,y ,e and ,i:
(##cmd-b depth cont port) (##cmd-y depth cont pinpoint? port) (##cmd-e cont port) (##cmd-i cont port)
If there is interest in having access to the functionality of these procedures I can make them easier to use by removing the ## prefix, adding type checking, and changing the API. Are there any suggestions? For example I could add optional parameters to ##cmd-b for "max-head" and "max-tail".
Marc
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.
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.
I also take this opportunity to give all my gratitude to Marc for your wonderful Gambit-C Scheme System. Without it, I don't know how I could have done my work for the last three years. Cheers!
Thank you, Francois
On 28-Aug-07, at 9:47 AM, Marc Feeley wrote:
On 27-Aug-07, at 7:12 PM, Guillaume Germain wrote:
On 8/27/07, François Magnan francois.magnan@licef.teluq.uqam.ca wrote:
Is there an easy way to access the debugging functions of the Gambit REPL in a programmatic way? I would like to call (for example) a function that would give me the equivalent of ",b" and ",e" inside my exception-catcher.
Here's a simple example for ##cmd-b :
(define (stack-to-string) (##continuation-capture (lambda (k) (call-with-output-string "" (lambda (port) (##cmd-b 0 k port))))))
Here is the set of procedures, defined in lib/_repl.scm, which implement the REPL commands ,b ,y ,e and ,i:
(##cmd-b depth cont port) (##cmd-y depth cont pinpoint? port) (##cmd-e cont port) (##cmd-i cont port)
If there is interest in having access to the functionality of these procedures I can make them easier to use by removing the ## prefix, adding type checking, and changing the API. Are there any suggestions? For example I could add optional parameters to ##cmd-b for "max-head" and "max-tail".
Marc
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)
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)
Hi,
this reminds me of something I was wondering about...
Is it possible to add or edit these ",x" commands? I would like to add ",f" to call my (edit) for example. Especially, I want to know if this is possible without editing the sourcecode?
Thanks
Christian