* api-debug.texi (Debugging Examples): New (from CVS HEAD).
authorNeil Jerram <neil@ossau.uklinux.net>
Wed, 19 Mar 2008 23:06:52 +0000 (23:06 +0000)
committerNeil Jerram <neil@ossau.uklinux.net>
Wed, 19 Mar 2008 23:06:52 +0000 (23:06 +0000)
doc/ref/ChangeLog
doc/ref/api-debug.texi

index c9f2c2d044fc5fbe9ae29d3d49da390382c48c94..b41db5cff55034b6615f84c018c7cf6d2526f687 100644 (file)
@@ -1,5 +1,7 @@
 2008-03-19  Neil Jerram  <neil@ossau.uklinux.net>
 
+       * api-debug.texi (Debugging Examples): New (from CVS HEAD).
+
        * scheme-using.texi (Interactive Debugger): Cover continuing
        execution.
        (Stepping and Continuing): New (from CVS HEAD).
index 2ad0aec4e75ad10d9f086c41b22e3b8ff44f3941..6c92d4b7ebd1542677832dbab85245a453dc2d87 100644 (file)
@@ -18,6 +18,7 @@ infrastructure that builds on top of those calls.
 * Evaluation Model::            Evaluation and the Scheme stack.
 * Debug on Error::              Debugging when an error occurs.
 * Traps::
+* Debugging Examples::
 @end menu
 
 @node Evaluation Model
@@ -1688,6 +1689,216 @@ if there isn't one.
 @end deffn
 
 
+@node Debugging Examples
+@subsection Debugging Examples
+
+Here we present some examples of what you can do with the debugging
+facilities just described.
+
+@menu
+* Single Stepping through a Procedure's Code::
+* Profiling or Tracing a Procedure's Code::
+@end menu
+
+
+@node Single Stepping through a Procedure's Code
+@subsubsection Single Stepping through a Procedure's Code
+
+A good way to explore in detail what a Scheme procedure does is to set
+a trap on it and then single step through what it does.  To do this,
+make and install a @code{<procedure-trap>} with the @code{debug-trap}
+behaviour from @code{(ice-9 debugging ice-9-debugger-extensions)}.
+
+The following sample session illustrates this.  It assumes that the
+file @file{matrix.scm} defines a procedure @code{mkmatrix}, which is
+the one we want to explore, and another procedure @code{do-main} which
+calls @code{mkmatrix}.
+
+@lisp
+$ /usr/bin/guile -q
+guile> (use-modules (ice-9 debugger)
+                    (ice-9 debugging ice-9-debugger-extensions)
+                    (ice-9 debugging traps))
+guile> (load "matrix.scm")
+guile> (install-trap (make <procedure-trap>
+                       #:procedure mkmatrix
+                       #:behaviour debug-trap))
+guile> (do-main 4)
+This is the Guile debugger -- for help, type `help'.
+There are 3 frames on the stack.
+
+Frame 2 at matrix.scm:8:3
+        [mkmatrix]
+debug> next
+Frame 3 at matrix.scm:4:3
+        (let ((x 1)) (quote this-is-a-matric))
+debug> info frame
+Stack frame: 3
+This frame is an evaluation.
+The expression being evaluated is:
+matrix.scm:4:3:
+  (let ((x 1)) (quote this-is-a-matric))
+debug> next
+Frame 3 at matrix.scm:5:21
+        (quote this-is-a-matric)
+debug> bt
+In unknown file:
+   ?: 0* [primitive-eval (do-main 4)]
+In standard input:
+   4: 1* [do-main 4]
+In matrix.scm:
+   8: 2  [mkmatrix]
+   ...
+   5: 3  (quote this-is-a-matric)
+debug> quit
+this-is-a-matric
+guile> 
+@end lisp
+
+Or you can use Guile's Emacs interface (GDS), by using the module
+@code{(ice-9 gds-client)} instead of @code{(ice-9 debugger)} and
+@code{(ice-9 debugging ice-9-debugger-extensions)}, and changing
+@code{debug-trap} to @code{gds-debug-trap}.  Then the stack and
+corresponding source locations are displayed in Emacs instead of on
+the Guile command line.
+
+
+@node Profiling or Tracing a Procedure's Code
+@subsubsection Profiling or Tracing a Procedure's Code
+
+What if you wanted to get a trace of everything that the Guile
+evaluator does within a given procedure, but without Guile stopping
+and waiting for your input at every step?  For this requirement you
+can install a trap on the procedure, as in the previous example, but
+instead of @code{debug-trap} or @code{gds-debug-trap}, use the
+@code{trace-trap} and @code{trace-until-exit} behaviours provided by
+the @code{(ice-9 debugging trace)} module.
+
+@lisp
+guile> (use-modules (ice-9 debugging traps) (ice-9 debugging trace))
+guile> (load "matrix.scm")
+guile> (install-trap (make <procedure-trap>
+                       #:procedure mkmatrix
+                       #:behaviour (list trace-trap trace-until-exit)))
+guile> (do-main 4)
+|  2: [mkmatrix]
+|  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> define #f]
+|  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> define #f]
+|  4: (and (memq sym bindings) (let ...))
+|  5: (memq sym bindings)
+|  5: [memq define (debug)]
+|  5: =>#f
+|  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> define #f]
+|  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> define #f]
+|  4: (and (memq sym bindings) (let ...))
+|  5: (memq sym bindings)
+|  5: [memq define (debug)]
+|  5: =>#f
+|  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
+|  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
+|  4: (and (memq sym bindings) (let ...))
+|  5: (memq sym bindings)
+|  5: [memq let (debug)]
+|  5: =>#f
+|  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
+|  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
+|  4: (and (memq sym bindings) (let ...))
+|  5: (memq sym bindings)
+|  5: [memq let (debug)]
+|  5: =>#f
+|  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
+|  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
+|  4: (and (memq sym bindings) (let ...))
+|  5: (memq sym bindings)
+|  5: [memq let (debug)]
+|  5: =>#f
+|  2: (letrec ((yy 23)) (let ((x 1)) (quote this-is-a-matric)))
+|  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
+|  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
+|  4: (and (memq sym bindings) (let ...))
+|  5: (memq sym bindings)
+|  5: [memq let (debug)]
+|  5: =>#f
+|  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
+|  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
+|  4: (and (memq sym bindings) (let ...))
+|  5: (memq sym bindings)
+|  5: [memq let (debug)]
+|  5: =>#f
+|  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
+|  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
+|  4: (and (memq sym bindings) (let ...))
+|  5: (memq sym bindings)
+|  5: [memq let (debug)]
+|  5: =>#f
+|  2: (let ((x 1)) (quote this-is-a-matric))
+|  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
+|  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
+|  4: (and (memq sym bindings) (let ...))
+|  5: (memq sym bindings)
+|  5: [memq let (debug)]
+|  5: =>#f
+|  2: [let (let # #) (# # #)]
+|  2: [let (let # #) (# # #)]
+|  2: =>(#@@let* (x 1) #@@let (quote this-is-a-matric))
+this-is-a-matric
+guile> (do-main 4)
+|  2: [mkmatrix]
+|  2: (letrec ((yy 23)) (let* ((x 1)) (quote this-is-a-matric)))
+|  2: (let* ((x 1)) (quote this-is-a-matric))
+|  2: (quote this-is-a-matric)
+|  2: =>this-is-a-matric
+this-is-a-matric
+guile> 
+@end lisp
+
+This example shows the default configuration for how each line of trace
+output is formatted, which is:
+
+@itemize
+@item
+the character @code{|}, a visual clue that the line is a line of trace
+output, followed by
+
+@item
+a number indicating the real evaluator stack depth (where ``real'' means
+not counting tail-calls), followed by
+
+@item
+a summary of the expression being evaluated (@code{(@dots{})}), the
+procedure being called (@code{[@dots{}]}), or the value being returned
+from an evaluation or procedure call (@code{=>@dots{}}).
+@end itemize
+
+@noindent
+You can customize @code{(ice-9 debugging trace)} to show different
+information in each trace line using the @code{set-trace-layout}
+procedure.  The next example shows how to get the source location in
+each trace line instead of the stack depth.
+
+@lisp
+guile> (set-trace-layout "|~16@@a: ~a\n" trace/source trace/info)
+guile> (do-main 4)
+|  matrix.scm:7:2: [mkmatrix]
+|                : (letrec ((yy 23)) (let* ((x 1)) (quote this-is-a-matric)))
+|  matrix.scm:3:2: (let* ((x 1)) (quote this-is-a-matric))
+|  matrix.scm:4:4: (quote this-is-a-matric)
+|  matrix.scm:4:4: =>this-is-a-matric
+this-is-a-matric
+guile> 
+@end lisp
+
+(For anyone wondering why the first @code{(do-main 4)} call above
+generates lots more trace lines than the subsequent calls: these
+examples also demonstrate how the Guile evaluator ``memoizes'' code.
+When Guile evaluates a source code expression for the first time, it
+changes some parts of the expression so that they will be quicker to
+evaluate when that expression is evaluated again; this is called
+memoization.  The trace output from the first @code{(do-main 4)} call
+shows memoization steps, such as an internal define being transformed to
+a letrec.)
+
+
 @c Local Variables:
 @c TeX-master: "guile.texi"
 @c End: