* 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 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 ` Interactive Debugging 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 --
[not found] <mailman.75.1571500806.2224.guile-user@gnu.org>
2019-10-19 19:04 ` Interactive Debugging 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
2019-10-18 4:39 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
-- 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).