unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
* Interactive Debugging
@ 2019-10-18  4:37 Christopher Howard
  0 siblings, 0 replies; 11+ messages in thread
From: Christopher Howard @ 2019-10-18  4:37 UTC (permalink / raw)
  To: Guile User

Hi, it seems like with the flexibility of Guile, I should be able to do
something like this:
```(define (foo)  (let ((a 1)        (b 2)        (c 3))    (jump-into-
debugging-repl)))```
And have access to a, b, and c and their values. But I'm not quite
figuring out how to this.
I know from 6.26.3.2 that it possible to throw an error and capture the
error stack, but I don't know how you turn that error stack into a
repl, if you get what I'm trying to say.
From poking around in the source code, I found (system repl repl) and
related modules. (start-repl) does throw me into a repl, but without
debug information. start-repl has a #:debug key, but I can't figure out
what I'm suppose to pass to it.
I can do something like this, with a break:
```(define (foo)  (let ((a 1)        (b 2)        (c
3))    (bp)    (display "done!")))
(define (bp)  '())```
But I'm not sure how to get to those locals:
```scheme@(buffer cbuff)> ,break bpTrap 1: Breakpoint at #<procedure bp
()>.scheme@(guile-user)> (foo)Trap 1: Breakpoint at #<procedure bp
()>Entering a new prompt.  Type `,bt' for a backtrace or `,q' to
continue.scheme@(guile-user) [1]> ,btIn current input:    700:4  1
(foo)    703:0  0 (bp)scheme@(guile-user) [1]> ,locals  No local
variables.scheme@(guile-user) [1]> ,upIn current input:    700:4  1
(foo)scheme@(guile-user) [1]> ,locals  No local variables.```

-- 
Christopher Howard
p: +1 (907) 374-0257
w: https://librehacker.com
social feed: https://gnusocial.club/librehacker
xmpp: creationist@member.fsf.org
otr: E9685B53 01F038DD D29281C9 30FDA71E BD0095D4
gnupg: 23FD5CC5 (keys.gnupg.net)
radio: KL1TL
featured: https://u.fsf.org/user-liberation


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Interactive Debugging
@ 2019-10-18  4:39 Christopher Howard
  2019-10-18 12:39 ` Matt Wette
  0 siblings, 1 reply; 11+ messages in thread
From: Christopher Howard @ 2019-10-18  4:39 UTC (permalink / raw)
  To: Guile User

Hi, it seems like with the flexibility of Guile, I should be able to do
something like this:
```(define (foo)  (let ((a 1)        (b 2)        (c 3))    (jump-into-
debugging-repl)))```
And have access to a, b, and c and their values. But I'm not quite
figuring out how to this.
I know from 6.26.3.2 that it possible to throw an error and capture the
error stack, but I don't know how you turn that error stack into a
repl, if you get what I'm trying to say.
From poking around in the source code, I found (system repl repl) and
related modules. (start-repl) does throw me into a repl, but without
debug information. start-repl has a #:debug key, but I can't figure out
what I'm suppose to pass to it.
I can do something like this, with a break:
```(define (foo)  (let ((a 1)        (b 2)        (c
3))    (bp)    (display "done!")))
(define (bp)  '())```
But I'm not sure how to get to those locals:
```scheme@(buffer cbuff)> ,break bpTrap 1: Breakpoint at #<procedure bp
()>.scheme@(guile-user)> (foo)Trap 1: Breakpoint at #<procedure bp
()>Entering a new prompt.  Type `,bt' for a backtrace or `,q' to
continue.scheme@(guile-user) [1]> ,btIn current input:    700:4  1
(foo)    703:0  0 (bp)scheme@(guile-user) [1]> ,locals  No local
variables.scheme@(guile-user) [1]> ,upIn current input:    700:4  1
(foo)scheme@(guile-user) [1]> ,locals  No local variables.```

-- 
Christopher Howard
p: +1 (907) 374-0257
w: https://librehacker.com
social feed: https://gnusocial.club/librehacker
xmpp: creationist@member.fsf.org
otr: E9685B53 01F038DD D29281C9 30FDA71E BD0095D4
gnupg: 23FD5CC5 (keys.gnupg.net)
radio: KL1TL
featured: https://u.fsf.org/user-liberation


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Interactive Debugging
  2019-10-18  4:39 Interactive Debugging Christopher Howard
@ 2019-10-18 12:39 ` Matt Wette
  2019-10-18 13:18   ` Thompson, David
  0 siblings, 1 reply; 11+ messages in thread
From: Matt Wette @ 2019-10-18 12:39 UTC (permalink / raw)
  To: guile-user

On 10/17/19 9:39 PM, Christopher Howard wrote:
> Hi, it seems like with the flexibility of Guile, I should be able to do
> something like this:
> ```(define (foo)  (let ((a 1)        (b 2)        (c 3))    (jump-into-
> debugging-repl)))```
> And have access to a, b, and c and their values. But I'm not quite
> figuring out how to this.
>

Define dump-into-debugging-repl as

(start-repl #:debug (make-debug (stack->vector (make-stack #t)) 0 
"trap!" #t))

But as for getting access to locals I don't know if there is a 
solution.   I have worked on removing slot sharing in the CPS processing 
but it's not working and I probably won't work on it anytime soon.

Apparently the best option for debugging is to use guile-1.8.

Matt




^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Interactive Debugging
  2019-10-18 12:39 ` Matt Wette
@ 2019-10-18 13:18   ` Thompson, David
  2019-10-18 21:21     ` Mark H Weaver
  0 siblings, 1 reply; 11+ messages in thread
From: Thompson, David @ 2019-10-18 13:18 UTC (permalink / raw)
  To: Matt Wette; +Cc: Guile User

On Fri, Oct 18, 2019 at 8:40 AM Matt Wette <matt.wette@gmail.com> wrote:
>
> On 10/17/19 9:39 PM, Christopher Howard wrote:
> > Hi, it seems like with the flexibility of Guile, I should be able to do
> > something like this:
> > ```(define (foo)  (let ((a 1)        (b 2)        (c 3))    (jump-into-
> > debugging-repl)))```
> > And have access to a, b, and c and their values. But I'm not quite
> > figuring out how to this.
> >
>
> Define dump-into-debugging-repl as
>
> (start-repl #:debug (make-debug (stack->vector (make-stack #t)) 0
> "trap!" #t))

I think something like this should be shipped in the (system repl
debug) module.  I'm used to quick and easy access to a debugger in
other languages, such as Ruby, and having to wrap your head around the
REPL, debug, and stack code is too much to ask of any new Guiler.

Would a patch like this appeal to the maintainers?

- Dave



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Interactive Debugging
       [not found] <mailman.2435.1571402405.9712.guile-user@gnu.org>
@ 2019-10-18 13:38 ` Christopher Howard
  0 siblings, 0 replies; 11+ messages in thread
From: Christopher Howard @ 2019-10-18 13:38 UTC (permalink / raw)
  To: guile-user

> 
> Define dump-into-debugging-repl as
> 
> (start-repl #:debug (make-debug (stack->vector (make-stack #t)) 0 
> "trap!" #t))
> 
> But as for getting access to locals I don't know if there is a 
> solution.   I have worked on removing slot sharing in the CPS
> processing 
> but it's not working and I probably won't work on it anytime soon.
> 
> Apparently the best option for debugging is to use guile-1.8.
> 
> Matt
> 
> 

For posterity: the required modules are

```
(use-modules (system repl repl)
             (system repl debug))
```

-- 
Christopher Howard
p: +1 (907) 374-0257
w: https://librehacker.com
social feed: https://gnusocial.club/librehacker
xmpp: creationist@member.fsf.org
otr: E9685B53 01F038DD D29281C9 30FDA71E BD0095D4
gnupg: 23FD5CC5 (keys.gnupg.net)
radio: KL1TL
featured: https://answersingenesis.org/



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Interactive Debugging
  2019-10-18 13:18   ` Thompson, David
@ 2019-10-18 21:21     ` Mark H Weaver
  2019-10-19 14:42       ` Matt Wette
  2019-10-23 23:48       ` Christopher Lam
  0 siblings, 2 replies; 11+ messages in thread
From: Mark H Weaver @ 2019-10-18 21:21 UTC (permalink / raw)
  To: Thompson, David; +Cc: Guile User, Matt Wette

"Thompson, David" <dthompson2@worcester.edu> writes:

> On Fri, Oct 18, 2019 at 8:40 AM Matt Wette <matt.wette@gmail.com> wrote:
>>
>> On 10/17/19 9:39 PM, Christopher Howard wrote:
>> > Hi, it seems like with the flexibility of Guile, I should be able to do
>> > something like this:
>> > ```(define (foo)  (let ((a 1)        (b 2)        (c 3))    (jump-into-
>> > debugging-repl)))```
>> > And have access to a, b, and c and their values. But I'm not quite
>> > figuring out how to this.
>> >
>>
>> Define dump-into-debugging-repl as
>>
>> (start-repl #:debug (make-debug (stack->vector (make-stack #t)) 0
>> "trap!" #t))
>
> I think something like this should be shipped in the (system repl
> debug) module.  I'm used to quick and easy access to a debugger in
> other languages, such as Ruby, and having to wrap your head around the
> REPL, debug, and stack code is too much to ask of any new Guiler.

For what it's worth, I think something like this would be a welcome
addition.  However, my knowledge of the Guile debugger is currently
quite weak, so I'd prefer to hear from Andy before proceeding.

     Thanks,
       Mark



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Interactive Debugging
  2019-10-18 21:21     ` Mark H Weaver
@ 2019-10-19 14:42       ` Matt Wette
  2019-10-23 23:48       ` Christopher Lam
  1 sibling, 0 replies; 11+ messages in thread
From: Matt Wette @ 2019-10-19 14:42 UTC (permalink / raw)
  To: guile-user

Below is something I played with years ago.  I'm not sure kill-opt is up to date.   Try with


   > (load "jtd.scm")
   > (foo)
   [1]> ,loc





;; potluck/jtd - jump to debugger, detour to debugger

;;(define-module (potluck jtd) #:export (kill-opt trap-here foo))

(use-modules (system repl repl))
(use-modules (system repl debug))
(use-modules (system repl common))
(use-modules (system repl command))
(use-modules (system vm frame))
(use-modules (system vm vm))
(use-modules (ice-9 control))
(use-modules (ice-9 rdelim))
(use-modules (ice-9 pretty-print))

;; kill optimization
(define (kill-opt)
   (set! (@@ (language tree-il optimize) tree-il-default-optimization-options)
         (lambda () '()))
   (set! (@@ (language cps optimize) cps-default-optimization-options)
         (lambda () '())))

;; notes
;; 1) needs new set of commands:
;;    C-d loops and enters again, i.e., continues => disable
;;    debug needs ,continue -- aka ,c  -- HAS it,  see ",quit"
;;    need ,quit -- aka ,q
;; 2) for non-interactive use probably need to call guile with "--debug"
;; 3) need to determine if repl is running (pair? (fluid-ref *repl-stack*))
;;    and start one if not
;; 4) maybe set hook on next instrucrtion (trap-here-2)
;; 5) see debug-trap-handler in system/repl/error-handling.scm to see how
;;    a debug session is spontaneously started.  See also near line 124.
;; 6) another strategy might be to have a procedure and set a trap in there
;; 7) use prompts (delineated continuations)
;; 8) trap handlers take one argument: a frame
;; 9) possible frame goodies:
;;    (frame-lookup-binging frame var)
;;    (frame-next-source frame) ;; NO MORE :(
;;    (frame-source frame)

;; given frame
;; (frame-procedure frame) => procedure
;; (procedure-source procedure) => source ???
;; (source-properties <obj>) => '((filename . "foo.scm") (line . 2) ...)

;; Here is what the debugger step command does:
;; (add-ephemeral-stepping-trap! cur (repl-next-resumer msg)
;;                               #:into? #t #:instruction? #f)
;; (throw 'quit)))

;;(simple-format #t "~S\n" (provided? 'debug-extensions))
;;(simple-format #t "repl:~S\n" (fluid-ref *repl-stack*))
;;(define repl-next-resumer (@@ (system repl command) repl-next-resumer))

;;(simple-format #t "vm-engine: ~S\n" (vm-engine))

;; get a few lines from file
(define (get-lines filename lineno)
   (let ((port (open-input-file filename)))
     (let iter ((prev #f) (curr #f) (offs lineno))
       (case offs
        ((1) (iter (cons " " (read-line port)) curr (1- offs)))
        ((0) (iter prev (cons "*" (read-line port)) (1- offs)))
        ((-1) (list prev curr (cons " " (read-line port))))
        (else (read-line port) (iter prev curr (1- offs)))))))

(define (show-src-loc locn)
   (let* ((line (assq-ref locn 'line))
	 (column (assq-ref locn 'column))
	 (filename (assq-ref locn 'filename)))
     (for-each
      (lambda (pair)
        (if pair
	   (simple-format #t "~A ~A\n" (car pair) (cdr pair))))
      (get-lines filename line))))

(define here-repl #f)

;; @deffn make-debug frames index err-msg for-trap?
;; Generate a data structure used for the repl.
;; @table @var
;; @item frames
;; TBD
;; @item index
;; I think this is the current frame from the deepest
;; @item err-msg
;; TBD
;; @item for-trap?
;; TBD
;; @end table

;; make-stack : in manual, generates a list of frames
;; stack->vector : convert list to vector

;; in commands, cur is (vector-ref (debug-frames debug) (debug-index debug))
;;  or the current frame

;; The first thing we do is kill off optimization
(kill-opt)

(define give-warning
   (let ((warned? #f))
     (lambda ()
       (unless warned?
	(simple-format (current-error-port) "trap requires --debug\n")
	(set! warned? #t)))))
       
(define-syntax-rule (jump-to-debugger)
   (if (eqv? 'regular (vm-engine))
       (give-warning)
       (start-repl
        #:debug (make-debug (stack->vector (make-stack #t)) 0 "trap!" #t))))

(define-syntax-rule (trap-here-0)
   (start-repl
    #:debug (make-debug (stack->vector (make-stack #t)) 0 "trap!" #t)))

#;(define-syntax-rule (trap-here-2)
   (let ((loc (current-source-location))
	)
     #t
     ))

;; step:
;;    (add-ephemeral-stepping-trap! cur (repl-next-resumer msg)
;;                                  #:into? #t #:instruction? #f)
;;    (throw 'quit)))

;; quit:
;; (throw 'quit)
(define (my-repl-welcome repl)
   (display "Enter `,help' for help.\n"))
(set! (@ (system repl common) repl-welcome) my-repl-welcome)


;; copy from system/repl/command.scm
;; this returns a continuation
(define (repl-next-resumer msg)
   ;; Capture the dynamic environment with this prompt thing. The
   ;; result is a procedure that takes a frame.
   (% (let ((stack (abort
                    (lambda (k)
                      ;; Call frame->stack-vector before reinstating the
                      ;; continuation, so that we catch the %stacks fluid
                      ;; at the time of capture.
                      (lambda (frame)
                        (k (frame->stack-vector frame)))))))
        (format #t "~a~%" msg)
        ((module-ref (resolve-interface '(system repl repl)) 'start-repl)
         #:debug (make-debug stack 0 msg #t)))))

#;(define-meta-command (resume repl)
   "resume"
   (let ((debug (repl-debug repl)))
     (if debug
	(let ((msg (simple-format #f "resume ..."))
	      (cur (vector-ref (debug-frames debug) (debug-index debug))))
	  (add-ephemeral-stepping-trap! cur (repl-next-resumer msg)
					#:into? #t #:instruction? #f)
	  ))))

;; This allows user to just get the hell out of guile.
;;(define-meta-command ((quit-guile extra) repl)
(define-meta-command ((qq extra) repl)
   "quit-guile
Quit the guile session."
   (primitive-exit 1))

(define-meta-command ((loc extra) repl)
   "loc
Show where in source."
   (let* ((debug (repl-debug repl))
	 (indx (debug-index debug))
	 (frms (debug-frames debug))
	 (frm (vector-ref frms (1+ indx)))
	 (src (and frm (frame-source frm)))
	 (loc `((column . ,(car src))
		(filename . ,(cadr src))
		(line . ,(caddr src))))
	 )
     (show-src-loc loc)
     ))

(define (foo)
   (let ((a 1) (b 2) (c 3))
     (set! b 22)
     ;;(show-src-loc (current-source-location))
     (let iter ((sum 0) (vals '(1 2 3 5 8 2)))
       (if (zero? sum) (jump-to-debugger))
       (cond
        ((null? vals) sum)
        (else
	(simple-format #t "~S\n" sum)
	(iter (+ sum (car vals)) (cdr vals)))))))

;;(simple-format #t "~S\n" (foo))

;;; --- last line ---
  




^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Interactive Debugging
       [not found] <mailman.75.1571500806.2224.guile-user@gnu.org>
@ 2019-10-19 19:04 ` Christopher Howard
  2019-10-19 19:09   ` Matt Wette
  0 siblings, 1 reply; 11+ messages in thread
From: Christopher Howard @ 2019-10-19 19:04 UTC (permalink / raw)
  To: guile-user


> Below is something I played with years ago.  I'm not sure kill-opt is
> up to date.   Try with
>
>
>   > (load "jtd.scm")
>   > (foo)
>   [1]> ,loc

The code seems to evaluate fine, but does not produce useful results:

```
scheme@(guile-user)> ,use (potluck jtd)
scheme@(guile-user)> (foo)
scheme@(guile-user) [1]> ,loc
While executing meta-command:
Wrong type (expecting string): #f
scheme@(guile-user) [1]> ,locals
  No local variables.
```



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Interactive Debugging
  2019-10-19 19:04 ` Christopher Howard
@ 2019-10-19 19:09   ` Matt Wette
  0 siblings, 0 replies; 11+ messages in thread
From: Matt Wette @ 2019-10-19 19:09 UTC (permalink / raw)
  To: guile-user

On 10/19/19 12:04 PM, Christopher Howard wrote:
>> Below is something I played with years ago.  I'm not sure kill-opt is
>> up to date.   Try with
>>
>>
>>     > (load "jtd.scm")
>>     > (foo)
>>     [1]> ,loc
> The code seems to evaluate fine, but does not produce useful results:
>
> ```
> scheme@(guile-user)> ,use (potluck jtd)
> scheme@(guile-user)> (foo)
> scheme@(guile-user) [1]> ,loc
> While executing meta-command:
> Wrong type (expecting string): #f
> scheme@(guile-user) [1]> ,locals
>    No local variables.
> ```
>

On guile 2.2.3, ubuntu 18.04 I get this:

scheme@(guile-user)> (load "jtd.scm")
scheme@(guile-user)> (foo)
scheme@(guile-user) [1]> ,loc
       (let iter ((sum 0) (vals '(1 2 3 5 8 2)))
*       (if (zero? sum) (jump-to-debugger))
         (cond




^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Interactive Debugging
  2019-10-18 21:21     ` Mark H Weaver
  2019-10-19 14:42       ` Matt Wette
@ 2019-10-23 23:48       ` Christopher Lam
  2019-10-24  9:22         ` Amirouche Boubekki
  1 sibling, 1 reply; 11+ messages in thread
From: Christopher Lam @ 2019-10-23 23:48 UTC (permalink / raw)
  To: Mark H Weaver; +Cc: guile-user, Thompson, David, Matt Wette

Agree it'll be a major aid to decreasing the learning curve. For now the
only way to analyse a variable in a script is to (pk) it, which is annoying
when it's a record/alist etc. Need to refine the pk several times or write
a custom printer.

Not sure how much knowledge of debugger is required, all I want to do is to
dump local variables at the breakpoint.

On Sat, 19 Oct 2019, 05:23 Mark H Weaver, <mhw@netris.org> wrote:

> "Thompson, David" <dthompson2@worcester.edu> writes:
>
> > On Fri, Oct 18, 2019 at 8:40 AM Matt Wette <matt.wette@gmail.com> wrote:
> >>
> >> On 10/17/19 9:39 PM, Christopher Howard wrote:
> >> > Hi, it seems like with the flexibility of Guile, I should be able to
> do
> >> > something like this:
> >> > ```(define (foo)  (let ((a 1)        (b 2)        (c 3))
> (jump-into-
> >> > debugging-repl)))```
> >> > And have access to a, b, and c and their values. But I'm not quite
> >> > figuring out how to this.
> >> >
> >>
> >> Define dump-into-debugging-repl as
> >>
> >> (start-repl #:debug (make-debug (stack->vector (make-stack #t)) 0
> >> "trap!" #t))
> >
> > I think something like this should be shipped in the (system repl
> > debug) module.  I'm used to quick and easy access to a debugger in
> > other languages, such as Ruby, and having to wrap your head around the
> > REPL, debug, and stack code is too much to ask of any new Guiler.
>
> For what it's worth, I think something like this would be a welcome
> addition.  However, my knowledge of the Guile debugger is currently
> quite weak, so I'd prefer to hear from Andy before proceeding.
>
>      Thanks,
>        Mark
>
>


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Interactive Debugging
  2019-10-23 23:48       ` Christopher Lam
@ 2019-10-24  9:22         ` Amirouche Boubekki
  0 siblings, 0 replies; 11+ messages in thread
From: Amirouche Boubekki @ 2019-10-24  9:22 UTC (permalink / raw)
  To: Christopher Lam; +Cc: guile-user, Thompson, David, Matt Wette

Le jeu. 24 oct. 2019 à 01:48, Christopher Lam
<christopher.lck@gmail.com> a écrit :

[...]

> Not sure how much knowledge of debugger is required, all I want to do is to
> dump local variables at the breakpoint.

For records there is (set-record-type-printer! type proc):

  https://www.gnu.org/software/guile/manual/html_node/SRFI_002d9-Records.html#index-set_002drecord_002dtype_002dprinter_0021

It is similar to how one set MyClass.__repr__ in python.

For other types there is usually a foobar->alist or foobar->list procedures.


Hope this helps



^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2019-10-24  9:22 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-18  4:39 Interactive Debugging Christopher Howard
2019-10-18 12:39 ` Matt Wette
2019-10-18 13:18   ` Thompson, David
2019-10-18 21:21     ` Mark H Weaver
2019-10-19 14:42       ` Matt Wette
2019-10-23 23:48       ` Christopher Lam
2019-10-24  9:22         ` Amirouche Boubekki
     [not found] <mailman.75.1571500806.2224.guile-user@gnu.org>
2019-10-19 19:04 ` Christopher Howard
2019-10-19 19:09   ` Matt Wette
     [not found] <mailman.2435.1571402405.9712.guile-user@gnu.org>
2019-10-18 13:38 ` Christopher Howard
  -- strict thread matches above, loose matches on Subject: below --
2019-10-18  4:37 Christopher Howard

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).