From: Jan Nieuwenhuizen <janneke@gnu.org>
To: guile-devel@gnu.org
Subject: [PATCH] debugger: Initial GUD integration support v2
Date: Tue, 02 Sep 2014 23:20:12 +0200 [thread overview]
Message-ID: <87iol5vhwz.fsf@drakenvlieg.flower> (raw)
[-- Attachment #1: Type: text/plain, Size: 227 bytes --]
Hi,
Find attached the second version of the frienlier debug prompt patch
that enables Emacs GUD integration.
* Thinko in examples/gud-break.scm
* Do not print absolute file name for relative file names
Greetings, Jan
[-- Attachment #2: 0001-Initial-GUD-integration-support.patch --]
[-- Type: text/x-diff, Size: 8727 bytes --]
From b9631f41f2621f787fca5b36eb3ee20cc601a3e8 Mon Sep 17 00:00:00 2001
From: Jan Nieuwenhuizen <janneke@gnu.org>
Date: Tue, 5 Aug 2014 12:34:09 +0200
Subject: [PATCH] Initial GUD integration support.
* examples/gud-break.scm: New example; showing initial GUD
integration.
* module/system/repl/debug.scm (debug-prompt): New procedure;
gdb-like debug prompt. Experimental!
* module/system/repl/error-handling.scm (call-with-error-handling):
* module/system/repl/command.scm (step, step-instruction, next)
(next-instruction): Use it.
---
examples/gud-break.scm | 56 +++++++++++++++++++++++++++++++++++
module/system/repl/command.scm | 8 ++---
module/system/repl/debug.scm | 54 +++++++++++++++++++++++++++++++++
module/system/repl/error-handling.scm | 3 +-
4 files changed, 116 insertions(+), 5 deletions(-)
create mode 100644 examples/gud-break.scm
diff --git a/examples/gud-break.scm b/examples/gud-break.scm
new file mode 100644
index 0000000..dbef6f3
--- /dev/null
+++ b/examples/gud-break.scm
@@ -0,0 +1,56 @@
+#! /bin/sh
+# -*-scheme-*-
+exec guile -e main -s "$0" "$@"
+!#
+;; Experimental GUD support for Guile REPL
+;; Find a gud.el that you want to patch, e.g.
+;; zcat /usr/share/emacs/24.3/lisp/progmodes/gud.el.gz > ~/.emacs.d/gud.el
+;; or
+;; M-x find-function gdb RET
+;; C-x C-w ~/.emacs.d/gud.el RET
+;; Patch it
+;; patch ~/.emacs.d/gud.el < 0001-Initial-Guile-REPL-guiler-debugger-support-for-GUD.patch
+;; M-x load-library ~/.emacs.d/gud.el RET
+;; M-x guiler RET
+;; ,m gud-break
+;; ,br main
+;; (main)
+;; ,n
+;; ,n # no easy RET shortcut yet
+;;
+;; And see |> marker in Emac's left margin track the program's execution.
+
+(read-set! keywords 'prefix)
+
+(define (main . args)
+ (eval '(main (command-line)) (resolve-module '(gud-break))))
+
+(define-module (gud-break)
+ :export (main))
+
+(define (stderr fmt . args)
+ (apply format (cons (current-error-port) (cons* fmt args)))
+ (force-output (current-error-port)))
+
+(define (main . args)
+ (stderr "~a:hello world\n" (current-source-location))
+ (let
+ ((a #f)
+ (b #f))
+ (set! a 1)
+ (stderr "set: a=~a\n" a)
+ (set! b 2)
+ (stderr "set: b=~a\n" b)
+ (let
+ ((c #f)
+ (d #f))
+ (set! c 3)
+ (stderr "set: c=~a\n" c)
+ (set! d 4)
+ (stderr "set: d=~a\n" d))
+ (stderr "~a:leaving...\n" (current-source-location)))
+ (stderr "~a:goodbye world\n" (current-source-location)))
+
+
+
+
diff --git a/module/system/repl/command.scm b/module/system/repl/command.scm
index 62bc297..3999c5e 100644
--- a/module/system/repl/command.scm
+++ b/module/system/repl/command.scm
@@ -740,7 +740,7 @@ Resume execution, breaking when the current frame finishes."
Step until control reaches a different source location.
Step until control reaches a different source location."
- (let ((msg (format #f "Step into ~a" cur)))
+ (let ((msg (debug-prompt cur)))
(add-ephemeral-stepping-trap! cur (repl-next-resumer msg)
#:into? #t #:instruction? #f)
(throw 'quit)))
@@ -750,7 +750,7 @@ Step until control reaches a different source location."
Step until control reaches a different instruction.
Step until control reaches a different VM instruction."
- (let ((msg (format #f "Step into ~a" cur)))
+ (let ((msg (debug-prompt cur)))
(add-ephemeral-stepping-trap! cur (repl-next-resumer msg)
#:into? #t #:instruction? #t)
(throw 'quit)))
@@ -760,7 +760,7 @@ Step until control reaches a different VM instruction."
Step until control reaches a different source location in the current frame.
Step until control reaches a different source location in the current frame."
- (let ((msg (format #f "Step into ~a" cur)))
+ (let ((msg (debug-prompt cur)))
(add-ephemeral-stepping-trap! cur (repl-next-resumer msg)
#:into? #f #:instruction? #f)
(throw 'quit)))
@@ -770,7 +770,7 @@ Step until control reaches a different source location in the current frame."
Step until control reaches a different instruction in the current frame.
Step until control reaches a different VM instruction in the current frame."
- (let ((msg (format #f "Step into ~a" cur)))
+ (let ((msg (debug-prompt cur)))
(add-ephemeral-stepping-trap! cur (repl-next-resumer msg)
#:into? #f #:instruction? #t)
(throw 'quit)))
diff --git a/module/system/repl/debug.scm b/module/system/repl/debug.scm
index 300145d..b27c900 100644
--- a/module/system/repl/debug.scm
+++ b/module/system/repl/debug.scm
@@ -24,6 +24,7 @@
#:use-module (system base language)
#:use-module (system vm vm)
#:use-module (system vm frame)
+ #:use-module (ice-9 and-let-star)
#:use-module (ice-9 rdelim)
#:use-module (ice-9 pretty-print)
#:use-module (ice-9 format)
@@ -32,6 +33,7 @@
#:export (<debug>
make-debug debug?
debug-frames debug-index debug-error-message
+ debug-prompt
terminal-width
print-registers print-locals print-frame print-frames frame->module
stack->vector narrow-stack->vector
@@ -160,6 +162,58 @@
(lp (+ i inc)
(frame-source frame)))))))
+(define *source-alist* '())
+(define (source-add file-name source)
+ (set! *source-alist* (assoc-set! *source-alist* file-name source))
+ source)
+
+(define (read-source-file file-name)
+ (or (assoc-ref *source-alist* file-name)
+ (and-let* ((source (with-input-from-file file-name read-string))
+ (lines (string-split source #\newline)))
+ (source-add file-name lines))))
+
+(define (fs-find-file file-name)
+ (if (file-exists? file-name)
+ file-name
+ (%search-load-path file-name)))
+
+(define (relative-file-name file-name)
+ (let ((cwd (getcwd)))
+ (if (and file-name (string-prefix? cwd file-name))
+ (string-drop file-name (1+ (string-length cwd)))
+ file-name)))
+
+(define (source-code file-name line-number)
+ (or (and-let* ((file-name file-name)
+ (line-number line-number)
+ (lines (read-source-file file-name)))
+ (list-ref lines line-number))
+ ""))
+
+(define *last-source* #f)
+(define* (debug-prompt frame #:optional (last-source *last-source*) (message ""))
+ "A gdb,pydb-like debug prompt."
+ (define (source:pretty-file source)
+ (if source
+ (or (source:file source) "current input")
+ "unknown file"))
+ (let* ((source (frame-source frame))
+ (file (source:pretty-file source))
+ (file-name (relative-file-name (fs-find-file file)))
+ (line (and=> source source:line))
+ (col (and=> source source:column))
+ (code (source-code file-name line))
+ (line-column (format #f "~a~a" (if line (1+ line) "")
+ (if col (format #f ":~a" col) ""))))
+ (set! *last-source* source)
+ (string-append
+ (if (and file (not (equal? file (source:pretty-file last-source))))
+ (format #f "~&~a:~a:~a~&" file-name line-column message) ;;GNU standard!
+ ;;(format #f "~&In ~a:~a~&" file-name message) ;;or awkward Guile convention?
+ "")
+ (format #f "~&~10a~a" line-column code))))
+
;; Ideally here we would have something much more syntactic, in that a set! to a
;; local var that is not settable would raise an error, and export etc forms
;; would modify the module in question: but alack, this is what we have now.
diff --git a/module/system/repl/error-handling.scm b/module/system/repl/error-handling.scm
index 94a9f2a..1777854 100644
--- a/module/system/repl/error-handling.scm
+++ b/module/system/repl/error-handling.scm
@@ -80,7 +80,8 @@
(begin
(format #t "~a~%" error-msg)
(format #t "Entering a new prompt. ")
- (format #t "Type `,bt' for a backtrace or `,q' to continue.\n")))
+ (format #t "Type `,bt' for a backtrace or `,q' to continue.\n")
+ (format #t "~a~&" (debug-prompt frame #f))))
((@ (system repl repl) start-repl) #:debug debug)))))
(define (null-trap-handler frame trap-idx trap-name)
--
Jan Nieuwenhuizen <janneke@gnu.org> | GNU LilyPond http://lilypond.org
Freelance IT http://JoyofSource.com | Avatar® http://AvatarAcademy.nl
[-- Attachment #3: Type: text/plain, Size: 154 bytes --]
--
Jan Nieuwenhuizen <janneke@gnu.org> | GNU LilyPond http://lilypond.org
Freelance IT http://JoyofSource.com | Avatar® http://AvatarAcademy.nl
reply other threads:[~2014-09-02 21:20 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/guile/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87iol5vhwz.fsf@drakenvlieg.flower \
--to=janneke@gnu.org \
--cc=guile-devel@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).