summaryrefslogtreecommitdiff
path: root/doc/ref/scheme-debugging.texi
diff options
context:
space:
mode:
authorNeil Jerram <neil@ossau.uklinux.net>2008-03-19 22:51:24 +0000
committerNeil Jerram <neil@ossau.uklinux.net>2008-03-19 22:51:24 +0000
commit24dbb5ed1080132c1dc67bf100d10ab4cc011af1 (patch)
tree166a47d34204621bb5fa4a05ebdcd54f55d6a59f /doc/ref/scheme-debugging.texi
parentcc7e01ceddaae8723feeedf33cca4fd106111025 (diff)
downloadguile-24dbb5ed1080132c1dc67bf100d10ab4cc011af1.tar.gz
* api-debug.texi (Low Level Trap Calls): Removed (material
duplicated elsewhere); doc for with-traps and debug-object? moved to section on evaluator trap options. (High Level Traps): Renamed just `Traps'. Add references to evaluator trap options and debug options. Make language appropriate for core Guile (as opposed to previously separate package). (Location Traps): Corrected to reflect that location traps now specify a specific position, not a range of positions. (Debugging Examples): New (content moved here from scheme-debugging.texi, and updated to use traps instead of breakpoints). * api-modules.texi (Included Guile Modules): Change `Debugging Features' reference to `Tracing'. * api-options.texi (Evaluator trap options): Doc for with-traps and debug-object? is now here. * guile.texi, scheme-debugging.texi: Move the `Tracing' content of scheme-debugging.texi to the Modules section. * scheme-using.texi (Using Guile in Emacs, GDS Getting Started): Minor edits. * scheme-debugging.texi (Debugging Features, Intro to Breakpoints): Removed. (Examples): Moved to api-debug.texi. (Tracing, Old Tracing): Promoted one level. (New Tracing, Tracing Compared): Removed.
Diffstat (limited to 'doc/ref/scheme-debugging.texi')
-rw-r--r--doc/ref/scheme-debugging.texi396
1 files changed, 1 insertions, 395 deletions
diff --git a/doc/ref/scheme-debugging.texi b/doc/ref/scheme-debugging.texi
index 32a6a46bd..07511263b 100644
--- a/doc/ref/scheme-debugging.texi
+++ b/doc/ref/scheme-debugging.texi
@@ -5,280 +5,8 @@
@c See the file guile.texi for copying conditions.
@page
-@node Debugging Features
-@section Debugging Features
-
-Guile includes debugging tools to help you work out what is going wrong
-when a program signals an error or behaves differently to how you would
-expect. This chapter describes how to use these tools.
-
-Broadly speaking, Guile's debugging support allows you to do two things:
-
-@itemize @bullet
-@item
-specify @dfn{breakpoints} --- points in the execution of a program where
-execution should pause so you can see what is going on
-
-@item
-examine in detail the ``scene of the crime'' --- in other words, the
-execution context at a breakpoint, or when the last error occurred.
-@end itemize
-
-@noindent
-The details are more complex and more powerful @dots{}
-
-@menu
-* Examples::
-* Intro to Breakpoints:: Setting and manipulating them.
-* Tracing:: Tracing program execution.
-@end menu
-
-
-@node Examples
-@subsection Examples
-
-Before we dive into the details and reference documentation of
-guile-debugging's features, this chapter sets the scene by presenting a
-few examples of what you can do with guile-debugging.
-
-@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
-breakpoint on it and then single step through what it does. To do this,
-use the @code{break-in} procedure from the @code{(ice-9 debugging
-breakpoints)} module 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 breakpoints))
-guile> (load "matrix.scm")
-guile> (break-in 'mkmatrix #:behaviour debug-trap)
-#<<break-in> 808cb70>
-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-debugging'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? In this case you set a breakpoint on the
-procedure using @code{break-in} (the same as in the previous example),
-but 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 breakpoints) (ice-9 debugging trace))
-guile> (load "matrix.scm")
-guile> (break-in 'mkmatrix #:behaviour (list trace-trap trace-until-exit))
-#<<break-in> 808b430>
-guile> (do-main 4)
-| 2: [mkmatrix]
-| 3: [define (define yy 23) ((()) #<eval-closure 4028db30>)]
-| 3: [define (define yy 23) ((()) #<eval-closure 4028db30>)]
-| 3: =>(#@@define yy 23)
-| 3: [let (let # #) (# #)]
-| 3: [let (let # #) (# #)]
-| 3: =>(#@@let* (x 1) #@@let (quote this-is-a-matric))
-| 2: (letrec ((yy 23)) (let ((x 1)) (quote this-is-a-matric)))
-| 3: [let (let # #) (# # #)]
-| 3: [let (let # #) (# # #)]
-| 3: =>(#@@let* (x 1) #@@let (quote this-is-a-matric))
-| 2: (let ((x 1)) (quote this-is-a-matric))
-| 3: [quote (quote this-is-a-matric) ((x . 1) ((yy) 23) (()) ...)]
-| 3: [quote (quote this-is-a-matric) ((x . 1) ((yy) 23) (()) ...)]
-| 3: =>(#@@quote this-is-a-matric)
-| 2: (quote this-is-a-matric)
-| 2: =>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:20: (quote this-is-a-matric)
-| matrix.scm:4:20: =>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.)
-
-
-@node Intro to Breakpoints
-@subsection Intro to Breakpoints
-
-Sometimes a piece of Scheme code isn't working and you'd like to go
-through it step by step. You can do this in Guile by setting a
-breakpoint at the start of the relevant code, and then using the command
-line or Emacs interface to step through it.
-
-A breakpoint can be specified by procedure name or by location -- the
-relevant code's file name, line number and column number. For details
-please see the full documentation for @code{break-in} and
-@code{break-at} in @ref{Intro to Breakpoints}.
-
-When you set a breakpoint, you can specify any ``behaviour'' you like
-for what should happen when the breakpoint is hit; a breakpoint
-``behaviour'' is just a Scheme procedure with the right signature.
-
-@menu
-* Breakpoints Overview::
-@end menu
-
-
-@node Breakpoints Overview
-@subsubsection How Breakpoints Work and Why They Are Useful
-
-Often, debugging the last error is not enough to tell you what went
-wrong. For example, the root cause of the error may have arisen a long
-time before the error was signalled, in which case the execution context
-of the error is too late to be useful. Or your program might not signal
-an error at all, just return an unexpected result or have some incorrect
-side effect.
-
-In many such cases, it's useful to pause the program at or before the
-point where you suspect the problem arises. Then you can explore the
-stack, display the values of key variables, and generally check that the
-state of the program is as you expect. If all is well, you can let the
-program continue running normally, or step more slowly through each
-expression that the Scheme interpreter evaluates. Single-stepping may
-reveal that the program is going through blocks of code that you didn't
-intend --- a useful data point for understanding what the underlying
-problem is.
-
-Telling Guile where or when to pause a program is called @dfn{setting a
-breakpoint}. When a breakpoint is hit, Guile's default behaviour is to
-enter the interactive debugger, where there are now two sets of commands
-available:
-
-@itemize @bullet
-@item
-all the commands as described for last error debugging
-(@pxref{Interactive Debugger}), which allow you to explore the stack and
-so on
-
-@item
-additional commands for continuing program execution in various ways:
-@code{next}, @code{step}, @code{finish}, @code{trace-finish} and
-@code{continue}.
-@end itemize
-
-Use of the interactive debugger is described in @ref{Interactive
-Debugger}.
-
-
@node Tracing
-@subsection Tracing
-
-Tracing has already been described as a breakpoint behaviour, but we
-mention it again here because it is so useful, and because Guile
-actually now has @emph{two} mechanisms for tracing, and its worth
-clarifying the differences between them.
-
-@menu
-* Old Tracing:: Tracing provided by (ice-9 debug).
-* New Tracing:: Breakpoint-based tracing.
-* Tracing Compared:: Differences between old and new.
-@end menu
-
-
-@node Old Tracing
-@subsubsection Tracing Provided by @code{(ice-9 debug)}
+@section Tracing
The @code{(ice-9 debug)} module implements tracing of procedure
applications. When a procedure is @dfn{traced}, it means that every
@@ -391,128 +119,6 @@ there is no need for Guile to create a new stack frame for each
iteration. Tracing reveals this optimization in operation.
-@node New Tracing
-@subsubsection Breakpoint-based Tracing
-
-Guile's newer mechanism implements tracing as an optional behaviour for
-any kind of breakpoint.
-
-To trace a procedure (in the same kind of way as the older tracing), use
-the @code{trace!} procedure to set a procedure breakpoint with
-@code{trace-here} behaviour:
-
-@lisp
-(trace! fact1)
-@print{}
-Set breakpoint 1: [fact1]
-@result{}
-#<<procedure-breakpoint> 40337bf0>
-
-(fact1 4)
-@print{}
-| [fact1 4]
-| | [fact1 3]
-| | | [fact1 2]
-| | | | [fact1 1]
-| | | | | [fact1 0]
-| | | | | 1
-| | | | 2
-| | | 6
-| | 24
-| 24
-@result{}
-24
-@end lisp
-
-To trace evaluation of a source expression, evaluate code containing a
-breakpoint marker @code{##} in the appropriate place, then use
-@code{set-breakpoint} to change the behaviour of the new breakpoint to
-@code{trace-here}:
-
-@lisp
-(define (fact1 n)
- (if ##(= n 0)
- 1
- (* n (fact1 (- n 1)))))
-@print{}
-Set breakpoint 4: standard input:13:9: (= n 0)
-
-(use-modules (ice-9 debugger behaviour))
-(set-breakpoint! trace-here 4)
-@print{}
-Breakpoint 4: standard input:13:9: (= n 0)
- enabled? = #t
- behaviour = #<procedure trace-here ()>
-
-(fact1 4)
-@print{}
-| (= n 0)
-| #f
-| (= n 0)
-| #f
-| (= n 0)
-| #f
-| (= n 0)
-| #f
-| (= n 0)
-| #t
-@result{}
-24
-@end lisp
-
-@noindent
-(Note --- this example reveals a bug: each occurrence of @code{(= n 0)}
-should be shown indented with respect to the one before it, as
-@code{fact1} does not call itself tail-recursively.)
-
-You can also give a breakpoint the @code{trace-subtree} behaviour, which
-means to trace the breakpoint location itself plus any evaluations and
-applications that occur below it in the call stack. In the following
-example, this allows us to see the evaluated arguments that are being
-compared by the @code{=} procedure:
-
-@lisp
-(set-breakpoint! trace-subtree 4)
-@print{}
-Breakpoint 4: standard input:13:9: (= n 0)
- enabled? = #t
- behaviour = #<procedure trace-subtree ()>
-
-(fact1 4)
-@print{}
-| (= n 0)
-| [= 4 0]
-| #f
-| (= n 0)
-| [= 3 0]
-| #f
-| (= n 0)
-| [= 2 0]
-| #f
-| (= n 0)
-| [= 1 0]
-| #f
-| (= n 0)
-| [= 0 0]
-| #t
-@result{}
-24
-@end lisp
-
-
-@node Tracing Compared
-@subsubsection Differences Between Old and New Tracing Mechanisms
-
-The newer tracing mechanism is more general and so more powerful than
-the older one: it works for expressions as well as procedure
-applications, and it implements the useful @code{trace-subtree}
-behaviour as well as the more traditional @code{trace-here}.
-
-The older mechanism will probably become obsolete eventually, but it's
-worth keeping it around for a while until we are sure that the new
-mechanism is correct and does what programmers need.
-
-
@c Local Variables:
@c TeX-master: "guile.texi"
@c End: