remove (system vm debug)
authorAndy Wingo <wingo@pobox.com>
Fri, 16 Jul 2010 11:19:33 +0000 (13:19 +0200)
committerAndy Wingo <wingo@pobox.com>
Fri, 16 Jul 2010 15:35:43 +0000 (17:35 +0200)
* module/system/vm/debug.scm: Remove.
* module/Makefile.am: Update.

* module/system/repl/debug.scm: Add some TODOs and a commented-out
  function here.

module/Makefile.am
module/system/repl/debug.scm
module/system/vm/debug.scm [deleted file]

index f445ac1..a2fb0f3 100644 (file)
@@ -310,7 +310,6 @@ OOP_SOURCES = \
 SYSTEM_SOURCES =                               \
   system/vm/inspect.scm                                \
   system/vm/coverage.scm                       \
-  system/vm/debug.scm                          \
   system/vm/frame.scm                          \
   system/vm/instruction.scm                    \
   system/vm/objcode.scm                                \
index 1164c6b..01b1b4c 100644 (file)
             print-locals print-frame print-frames frame->module
             stack->vector narrow-stack->vector))
 
-;;; FIXME: add more repl meta-commands: continue, inspect, etc...
+;; TODO:
+;;
+;; Update this TODO list ;)
+;; partial meta-commands  (,qui -> ,quit)
+;; eval expression in context of frame
+;; set local variable in frame
+;; step until next instruction
+;; step until next function call/return
+;; step until return from frame
+;; step until different source line
+;; step until greater source line
+;; watch expression
+;; break on a function
+;; remove breakpoints
+;; set printing width
+;; display a truncated backtrace
+;; go to a frame by index
+;; (reuse gdb commands perhaps)
+;; disassemble a function
+;; disassemble the current function
+;; inspect any object
+;; hm, trace via reassigning global vars. tricksy.
+;; (state associated with vm ?)
 
 ;;;
 ;;; Debugger
 (define (narrow-stack->vector stack . args)
   (stack->vector (apply make-stack (stack-ref stack 0) args)))
 
+;; (define (debug)
+;;   (run-debugger
+;;    (narrow-stack->vector
+;;     (make-stack #t)
+;;     ;; Narrow the `make-stack' frame and the `debug' frame
+;;     2
+;;     ;; Narrow the end of the stack to the most recent start-stack.
+;;     (and (pair? (fluid-ref %stacks))
+;;          (cdar (fluid-ref %stacks))))))
+
diff --git a/module/system/vm/debug.scm b/module/system/vm/debug.scm
deleted file mode 100644 (file)
index dfc7140..0000000
+++ /dev/null
@@ -1,522 +0,0 @@
-;;; Guile VM debugging facilities
-
-;;; Copyright (C) 2001, 2009, 2010 Free Software Foundation, Inc.
-;;;
-;;; This library is free software; you can redistribute it and/or
-;;; modify it under the terms of the GNU Lesser General Public
-;;; License as published by the Free Software Foundation; either
-;;; version 3 of the License, or (at your option) any later version.
-;;;
-;;; This library is distributed in the hope that it will be useful,
-;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-;;; Lesser General Public License for more details.
-;;;
-;;; You should have received a copy of the GNU Lesser General Public
-;;; License along with this library; if not, write to the Free Software
-;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-;;; Code:
-
-(define-module (system vm debug)
-  #:use-module (system base pmatch)
-  #:use-module (system base syntax)
-  #:use-module (system base language)
-  #:use-module (system vm vm)
-  #:use-module (system vm frame)
-  #:use-module (ice-9 rdelim)
-  #:use-module (ice-9 pretty-print)
-  #:use-module (ice-9 format)
-  #:use-module ((system vm inspect) #:select ((inspect . %inspect)))
-  #:use-module (system vm program)
-  #:export (*debug-input-port*
-            *debug-output-port*
-            debug run-debugger
-            call-with-error-handling with-error-handling))
-
-\f
-
-(define *debug-input-port* (make-fluid))
-(define *debug-output-port* (make-fluid))
-
-(define (debug-input-port)
-  (or (fluid-ref *debug-input-port*)
-      (current-input-port)))
-(define (debug-output-port)
-  (or (fluid-ref *debug-output-port*)
-      (current-error-port)))
-
-\f
-(define (reverse-hashq h)
-  (let ((ret (make-hash-table)))
-    (hash-for-each
-     (lambda (k v)
-       (hashq-set! ret v (cons k (hashq-ref ret v '()))))
-     h)
-    ret))
-
-(define (catch-bad-arguments thunk bad-args-thunk)
-  (catch 'wrong-number-of-args
-    (lambda ()
-      (catch 'keyword-argument-error
-        thunk
-        (lambda (k . args)
-          (bad-args-thunk))))
-    (lambda (k . args)
-      (bad-args-thunk))))
-
-(define (read-args prompt)
-  (define (read* reader)
-    (repl-reader prompt reader))
-  (define (next)
-    (read* read-char))
-  (define (cmd chr)
-    (cond
-     ((eof-object? chr) (list chr))
-     ((char=? chr #\newline) (cmd (next)))
-     ((char-whitespace? chr) (cmd (next)))
-     (else
-      (unread-char chr)
-      (let ((tok (read* read)))
-        (args (list tok) (next))))))
-  (define (args out chr)
-    (cond
-     ((eof-object? chr) (reverse out))
-     ((char=? chr #\newline) (reverse out))
-     ((char-whitespace? chr) (args out (next)))
-     (else
-      (unread-char chr)
-      (let ((tok (read* read)))
-        (args (cons tok out) (next))))))
-  (cmd (next)))
-
-(define* (print-locals frame #:optional (port (current-output-port))
-                       #:key (width 72) (per-line-prefix ""))
-  (let ((bindings (frame-bindings frame)))
-    (cond
-     ((null? bindings)
-      (format port "~aNo local variables.~%" per-line-prefix))
-     (else
-      (format port "~aLocal variables:~%" per-line-prefix)
-      (for-each
-       (lambda (binding)
-         (format port "~a~4d ~a~:[~; (boxed)~] = ~v:@y\n"
-                 per-line-prefix
-                 (binding:index binding)
-                 (binding:name binding)
-                 (binding:boxed? binding)
-                 width
-                 (let ((x (frame-local-ref frame (binding:index binding))))
-                   (if (binding:boxed? binding)
-                       (variable-ref x)
-                       x))))
-       (frame-bindings frame))))))
-
-(define* (print-frames frames
-                       #:optional (port (current-output-port))
-                       #:key (width 72) (full? #f) (forward? #f) count)
-  (let* ((len (vector-length frames))
-         (lower-idx (if (or (not count) (positive? count))
-                        0
-                        (max 0 (+ len count))))
-         (upper-idx (if (and count (negative? count))
-                        (1- len)
-                        (1- (if count (min count len) len))))
-         (inc (if forward? 1 -1)))
-    (let lp ((i (if forward? lower-idx upper-idx))
-             (last-file ""))
-      (if (<= lower-idx i upper-idx)
-          (let* ((frame (vector-ref frames i))
-                 (source (frame-source frame))
-                 (file (and source
-                            (or (source:file source)
-                                "current input")))
-                 (line (and=> source source:line)))
-            (if (and file (not (equal? file last-file)))
-                (format port "~&In ~a:~&" file))
-            (format port "~:[~*~6_~;~5d:~]~3d ~v:@y~%" line line
-                    i width (frame-call-representation frame))
-            (if full?
-                (print-locals frame #:width width
-                              #:per-line-prefix "     "))
-            (lp (+ i inc) (or file last-file)))))))
-
-;; 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.
-;; Patches welcome!
-(define (frame->module frame)
-  (let ((proc (frame-procedure frame)))
-    (if (program? proc)
-        (let* ((mod (or (program-module proc) (current-module)))
-               (mod* (make-module)))
-          (module-use! mod* mod)
-          (for-each
-           (lambda (binding)
-             (let* ((x (frame-local-ref frame (binding:index binding)))
-                    (var (if (binding:boxed? binding) x (make-variable x))))
-               (format (debug-output-port)
-                       "~:[Read-only~;Mutable~] local variable ~a = ~70:@y\n"
-                       (binding:boxed? binding)
-                       (binding:name binding)
-                       (if (variable-bound? var) (variable-ref var) var))
-               (module-add! mod* (binding:name binding) var)))
-           (frame-bindings frame))
-          mod*)
-        (current-module))))
-
-
-;;;
-;;; Debugger
-;;;
-
-(define-record <debugger> vm level breakpoints module)
-
-(define (make-debugger-module)
-  (let ((m (make-fresh-user-module)))
-    m))
-
-(define vm-debugger
-  (let ((prop (make-object-property)))
-    (lambda (vm)
-      (or (prop vm)
-          (let ((debugger (make-debugger vm 0 '() (make-debugger-module))))
-            (set! (prop vm) debugger)
-            debugger)))))
-
-;; FIXME: Instead of dynamically binding the input and output ports in the
-;; context of the error, the debugger should really be a kind of coroutine,
-;; having its own dynamic input and output bindings. Delimited continuations can
-;; do this.
-(define* (run-debugger frames #:optional (vm (the-vm)) #:key
-                       (input (debug-input-port)) (output (debug-output-port)))
-  (let* ((db (vm-debugger vm))
-         (level (debugger-level db)))
-    (dynamic-wind
-      (lambda ()
-        (set! (debugger-level db) (1+ level))
-        (set! input (set-current-input-port input)))
-      (lambda () 
-        (dynamic-wind
-          (lambda () (set! output (set-current-output-port output)))
-          (lambda () (debugger-repl db frames))
-          (lambda () (set! output (set-current-output-port output)))))
-      (lambda ()
-        (set! input (set-current-input-port input))
-        (set! (debugger-level db) level)))))
-
-(define (debugger-repl db frames)
-  (let* ((index 0)
-         (top (vector-ref frames index))
-         (cur top)
-         (level (debugger-level db))
-         (last #f))
-    (define (frame-at-index idx)
-      (and (< idx (vector-length frames))
-           (vector-ref frames idx)))
-    (define (show-frame)
-      ;;      #2  0x009600e0 in do_std_select (args=0xbfffd9e0) at threads.c:1668
-      ;;      1668         select (select_args->nfds,
-      (format #t "#~2a 0x~8,'0x in ~60@y~%"
-              index
-              (frame-instruction-pointer cur)
-              (frame-call-representation cur)))
-
-    (define-syntax define-command
-      (syntax-rules ()
-        ((_ ((mod cname alias ...) . args) body ...)
-         (define cname
-           (let ((c (lambda* args body ...)))
-             (set-procedure-property! c 'name 'cname)
-             (module-define! mod 'cname c)
-             (module-add! mod 'alias (module-local-variable mod 'cname))
-             ...
-             c)))))
-
-    (let ((commands (make-module)))
-      (define (prompt)
-        (format #f "~a~a debug> "
-                (if (= level 1)
-                    ""
-                    (format #f "~a:" level))
-                index))
-      
-      (define (print* . vals)
-        (define (print x)
-          (run-hook before-print-hook x)
-          (set! last x)
-          (pretty-print x))
-        (if (and (pair? vals)
-                 (not (and (null? (cdr vals))
-                           (unspecified? (car vals)))))
-            (for-each print vals)))
-
-      (define-command ((commands backtrace bt) #:optional count
-                       #:key (width 72) full?)
-        "Print a backtrace of all stack frames, or innermost COUNT frames.
-If COUNT is negative, the last COUNT frames will be shown."
-        (print-frames frames 
-                      #:count count
-                      #:width width
-                      #:full? full?))
-      
-      (define-command ((commands up) #:optional (count 1))
-        "Select and print stack frames that called this one.
-An argument says how many frames up to go"
-        (cond
-         ((or (not (integer? count)) (<= count 0))
-          (format #t "Invalid argument to `up': expected a positive integer for COUNT.~%"))
-         ((>= (+ count index) (vector-length frames))
-          (cond
-           ((= index (1- (vector-length frames)))
-            (format #t "Already at outermost frame.\n"))
-           (else
-            (set! index (1- (vector-length frames)))
-            (set! cur (vector-ref frames index))
-            (show-frame))))
-         (else
-          (set! index (+ count index))
-          (set! cur (vector-ref frames index))
-          (show-frame))))
-
-      (define-command ((commands down) #:optional (count 1))
-        "Select and print stack frames called by this one.
-An argument says how many frames down to go"
-        (cond
-         ((or (not (integer? count)) (<= count 0))
-          (format #t "Invalid argument to `down': expected a positive integer for COUNT.~%"))
-         ((< (- index count) 0)
-          (cond
-           ((zero? index)
-            (format #t "Already at innermost frame.\n"))
-           (else
-            (set! index 0)
-            (set! cur (vector-ref frames index))
-            (show-frame))))
-         (else
-          (set! index (- index count))
-          (set! cur (vector-ref frames index))
-          (show-frame))))
-
-      (define-command ((commands frame f) #:optional idx)
-        "Show the selected frame.
-With an argument, select a frame by index, then show it."
-        (cond
-         (idx
-          (cond
-           ((or (not (integer? idx)) (< idx 0))
-            (format #t "Invalid argument to `frame': expected a non-negative integer for IDX.~%"))
-           ((frame-at-index idx)
-            => (lambda (f)
-                 (set! cur f)
-                 (set! index idx)
-                 (show-frame)))
-           (else
-            (format #t "No such frame.~%"))))
-         (else (show-frame))))
-
-      (define-command ((commands repl r))
-        "Run a new REPL in the context of the current frame."
-        (save-module-excursion
-         (lambda ()
-           (set-current-module (frame->module cur))
-           ((@ (system repl repl) start-repl)))))
-
-      (define-command ((commands procedure proc))
-        "Print the procedure for the selected frame."
-        (print* (frame-procedure cur)))
-      
-      (define-command ((commands inspect i))
-        "Launch the inspector on the last-printed object."
-        (%inspect last))
-      
-      (define-command ((commands locals))
-        "Show locally-bound variables in the selected frame."
-        (print-locals cur))
-      
-      (define-command ((commands quit q continue cont c))
-        "Quit the debugger and let the program continue executing."
-        (throw 'quit))
-      
-      (define-command ((commands help h ?) #:optional cmd)
-        "Show this help message."
-        (let ((rhash (reverse-hashq (module-obarray commands))))
-          (define (help-cmd cmd)
-            (let* ((v (module-local-variable commands cmd))
-                   (p (variable-ref v))
-                   (canonical-name (procedure-name p)))
-              ;; la la la
-              (format #t "~a~{ ~:@(~a~)~}~?~%~a~&~%"
-                      canonical-name (program-lambda-list p)
-                      "~#[~:;~40t(aliases: ~@{~a~^, ~})~]"
-                      (delq canonical-name (hashq-ref rhash v))
-                      (procedure-documentation p))))
-          (cond
-           (cmd
-            (cond
-             ((and (symbol? cmd) (module-local-variable commands cmd))
-              (help-cmd cmd))
-             (else
-              (format #t "Invalid command ~s.~%" cmd)
-              (format #t "Try `help' for a list of commands~%"))))
-           (else
-            (let ((names (sort
-                           (hash-map->list
-                            (lambda (k v)
-                              (procedure-name (variable-ref k)))
-                            rhash)
-                           (lambda (x y)
-                             (string<? (symbol->string x)
-                                       (symbol->string y))))))
-              (format #t "Available commands:~%~%")
-              (for-each help-cmd names))))))
-
-      (define (handle cmd . args)
-        (cond
-         ((and (symbol? cmd)
-               (module-local-variable commands cmd))
-          => (lambda (var)
-               (let ((proc (variable-ref var)))
-                 (catch-bad-arguments
-                  (lambda ()
-                    (apply (variable-ref var) args))
-                  (lambda ()
-                    (format (current-error-port)
-                            "Invalid arguments to ~a. Try `help ~a'.~%"
-                            (procedure-name proc) (procedure-name proc)))))))
-         ((and (integer? cmd) (exact? cmd))
-          (frame cmd))
-         ((eof-object? cmd)
-          (newline)
-          (throw 'quit))
-         (else
-          (format (current-error-port)
-                  "~&Unknown command: ~a. Try `help'.~%" cmd)
-          *unspecified*)))
-
-      (catch 'quit
-        (lambda ()
-          (let loop ()
-            (let ((args (call-with-error-handling
-                         (lambda ()
-                           (save-module-excursion
-                            (lambda ()
-                              (set-current-module commands)
-                              (read-args prompt))))
-                         #:on-error 'pass)))
-              ;; args will be unspecified if there was a read error.
-              (if (not (unspecified? args))
-                  (apply handle args))
-              (loop))))
-        (lambda (k . args)
-          (apply values args))))))
-
-
-;; TODO:
-;;
-;; eval expression in context of frame
-;; set local variable in frame
-;; step until next instruction
-;; step until next function call/return
-;; step until return from frame
-;; step until different source line
-;; step until greater source line
-;; watch expression
-;; break on a function
-;; remove breakpoints
-;; set printing width
-;; display a truncated backtrace
-;; go to a frame by index
-;; (reuse gdb commands perhaps)
-;; disassemble a function
-;; disassemble the current function
-;; inspect any object
-;; hm, trace via reassigning global vars. tricksy.
-;; (state associated with vm ?)
-
-(define (stack->vector stack)
-  (let* ((len (stack-length stack))
-         (v (make-vector len)))
-    (if (positive? len)
-        (let lp ((i 0) (frame (stack-ref stack 0)))
-          (if (< i len)
-              (begin
-                (vector-set! v i frame)
-                (lp (1+ i) (frame-previous frame))))))
-    v))
-
-(define (debug)
-  (run-debugger
-   (narrow-stack->vector
-    (make-stack #t)
-    ;; Narrow the `make-stack' frame and the `debug' frame
-    2
-    ;; Narrow the end of the stack to the most recent start-stack.
-    (and (pair? (fluid-ref %stacks))
-         (cdar (fluid-ref %stacks))))))
-
-(define (narrow-stack->vector stack . args)
-  (stack->vector (apply make-stack (stack-ref stack 0) args)))
-
-(define* (call-with-error-handling thunk #:key
-                                   (on-error 'debug) (post-error 'catch)
-                                   (pass-keys '(quit)))
-  (catch #t
-    (lambda () (%start-stack #t thunk))
-
-    (case post-error
-      ((catch)
-       (lambda (key . args)
-         (if (memq key pass-keys)
-             (apply throw key args)
-             (let ((cep (current-error-port)))
-               (pmatch args
-                 ((,subr ,msg ,args . ,rest)
-                  (run-hook before-error-hook)
-                  (display-error #f cep subr msg args rest)
-                  (run-hook after-error-hook)
-                  (force-output cep))
-                 (else
-                  (format cep "\nERROR: uncaught throw to `~a', args: ~a\n"
-                          key args)))
-               (if #f #f)))))
-      (else
-       (if (procedure? post-error)
-           post-error
-           (error "Unknown post-error strategy" post-error))))
-    
-    (case on-error
-      ((debug)
-       (lambda (key . args)
-         (let ((stack (make-stack #t))
-               (dep (debug-output-port)))
-           (pmatch args
-             ((,subr ,msg ,args . ,rest)
-              (format dep "Throw to key `~a':\n" key)
-              (display-error stack dep subr msg args rest))
-             (else
-              (format dep "Throw to key `~a' with args `~s'." key args)))
-           (format dep "Entering the debugger. Type `bt' for a backtrace")
-           (format dep " or `c' to continue.\n")
-           (run-debugger
-            (narrow-stack->vector
-             stack
-             ;; Cut three frames from the top of the stack: make-stack, this
-             ;; one, and the throw handler.
-             3 
-             ;; Narrow the end of the stack to the most recent start-stack.
-             (and (pair? (fluid-ref %stacks))
-                  (cdar (fluid-ref %stacks))))))))
-      ((pass)
-       (lambda (key . args)
-         ;; fall through to rethrow
-         #t))
-      (else
-       (if (procedure? on-error)
-           on-error
-           (error "Unknown on-error strategy" on-error))))))
-
-(define-syntax with-error-handling
-  (syntax-rules ()
-    ((_ form)
-     (call-with-error-handling (lambda () form)))))