1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-04-30 11:50:28 +02:00

* scheme-debugging.texi (Debug Last Error, Interactive Debugger):

Moved/merged to scheme-using.texi, as REPL features.
(Examples): New.
(Intro to Breakpoints): New introductory text here.  Removed all
subnodes except for Breakpoints Overview.

* scheme-using.texi: New.

* guile.texi (Programming in Scheme): Include new
scheme-using.texi file.

* Makefile.am (guile_TEXINFOS): Include new scheme-using.texi
file.
This commit is contained in:
Neil Jerram 2006-08-01 21:33:17 +00:00
parent b49123789f
commit 46f7666d7f
5 changed files with 608 additions and 709 deletions

View file

@ -1,3 +1,19 @@
2006-08-01 Neil Jerram <neil@ossau.uklinux.net>
* scheme-debugging.texi (Debug Last Error, Interactive Debugger):
Moved/merged to scheme-using.texi, as REPL features.
(Examples): New.
(Intro to Breakpoints): New introductory text here. Removed all
subnodes except for Breakpoints Overview.
* scheme-using.texi: New.
* guile.texi (Programming in Scheme): Include new
scheme-using.texi file.
* Makefile.am (guile_TEXINFOS): Include new scheme-using.texi
file.
2006-06-16 Ludovic Courtès <ludovic.courtes@laas.fr> 2006-06-16 Ludovic Courtès <ludovic.courtes@laas.fr>
* api-utility.texi (Equality): Mentioned the behavior of `equal?' * api-utility.texi (Equality): Mentioned the behavior of `equal?'

View file

@ -56,6 +56,7 @@ guile_TEXINFOS = preface.texi \
gh.texi \ gh.texi \
api-overview.texi \ api-overview.texi \
scheme-debugging.texi \ scheme-debugging.texi \
scheme-using.texi \
indices.texi \ indices.texi \
script-getopt.texi \ script-getopt.texi \
data-rep.texi \ data-rep.texi \

View file

@ -137,7 +137,7 @@ x
@comment The title is printed in a large font. @comment The title is printed in a large font.
@title Guile Reference Manual @title Guile Reference Manual
@subtitle Edition @value{MANUAL-EDITION}, for use with Guile @value{VERSION} @subtitle Edition @value{MANUAL-EDITION}, for use with Guile @value{VERSION}
@c @subtitle $Id: guile.texi,v 1.44 2005-06-22 23:42:23 kryde Exp $ @c @subtitle $Id: guile.texi,v 1.45 2006-08-01 21:33:17 ossau Exp $
@c See preface.texi for the list of authors @c See preface.texi for the list of authors
@author The Guile Developers @author The Guile Developers
@ -219,6 +219,8 @@ etc. that make up Guile's application programming interface (API),
* Basic Ideas:: Basic ideas in Scheme. * Basic Ideas:: Basic ideas in Scheme.
* Guile Scheme:: Guile's implementation of Scheme. * Guile Scheme:: Guile's implementation of Scheme.
* Guile Scripting:: How to write Guile scripts. * Guile Scripting:: How to write Guile scripts.
* Using Guile Interactively:: Guile's REPL features.
* Using Guile in Emacs:: Guile and Emacs.
* Debugging Features:: Features for finding errors. * Debugging Features:: Features for finding errors.
* Further Reading:: Where to find out more about Scheme. * Further Reading:: Where to find out more about Scheme.
@end menu @end menu
@ -226,6 +228,7 @@ etc. that make up Guile's application programming interface (API),
@include scheme-ideas.texi @include scheme-ideas.texi
@include scheme-intro.texi @include scheme-intro.texi
@include scheme-scripts.texi @include scheme-scripts.texi
@include scheme-using.texi
@include scheme-debugging.texi @include scheme-debugging.texi
@include scheme-reading.texi @include scheme-reading.texi

View file

@ -28,135 +28,196 @@ execution context at a breakpoint, or when the last error occurred.
The details are more complex and more powerful @dots{} The details are more complex and more powerful @dots{}
@menu @menu
* Debug Last Error:: Debugging the most recent error. * Examples::
* Intro to Breakpoints:: Setting and manipulating them. * Intro to Breakpoints:: Setting and manipulating them.
* Interactive Debugger:: Using the interactive debugger.
* Tracing:: Tracing program execution. * Tracing:: Tracing program execution.
@end menu @end menu
@node Debug Last Error @node Examples
@subsection Debugging the Most Recent Error @subsection Examples
When an error is signalled, Guile remembers the execution context where Before we dive into the details and reference documentation of
the error occurred. By default, Guile then displays only the most guile-debugging's features, this chapter sets the scene by presenting a
immediate information about where and why the error occurred, for few examples of what you can do with guile-debugging.
example:
@lisp
(make-string (* 4 (+ 3 #\s)) #\space)
@print{}
standard input:2:19: In procedure + in expression (+ 3 #\s):
standard input:2:19: Wrong type argument: #\s
ABORT: (wrong-type-arg)
Type "(backtrace)" to get more information or "(debug)" to enter the debugger.
@end lisp
@noindent
However, as the message above says, you can obtain much more
information about the context of the error by typing
@code{(backtrace)} or @code{(debug)}.
@code{(backtrace)} displays the Scheme call stack at the point where the
error occurred:
@lisp
(backtrace)
@print{}
Backtrace:
In standard input:
2: 0* [make-string ...
2: 1* [* 4 ...
2: 2* [+ 3 #\s]
Type "(debug-enable 'backtrace)" if you would like a backtrace
automatically if an error occurs in the future.
@end lisp
@noindent
In a more complex scenario than this one, this can be extremely useful
for understanding where and why the error occurred. For more on the
format of the displayed backtrace, see the subsection below.
@code{(debug)} takes you into Guile's interactive debugger, which
provides commands that allow you to
@itemize @bullet
@item
display the Scheme call stack at the point where the error occurred
(the @code{backtrace} command --- see @ref{Display Backtrace})
@item
move up and down the call stack, to see in detail the expression being
evaluated, or the procedure being applied, in each @dfn{frame} (the
@code{up}, @code{down}, @code{frame}, @code{position}, @code{info args}
and @code{info frame} commands --- see @ref{Frame Selection} and
@ref{Frame Information})
@item
examine the values of variables and expressions in the context of each
frame (the @code{evaluate} command --- see @ref{Frame Evaluation}).
@end itemize
Use of the interactive debugger, including these commands, is described
in @ref{Interactive Debugger}.
@menu @menu
* Backtrace Format:: How to interpret a backtrace. * Single Stepping through a Procedure's Code::
* Profiling or Tracing a Procedure's Code::
@end menu @end menu
@node Backtrace Format @node Single Stepping through a Procedure's Code
@subsubsection How to Interpret a Backtrace @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 @node Intro to Breakpoints
@subsection Intro to Breakpoints @subsection Intro to Breakpoints
If you are not already familiar with the concept of breakpoints, the Sometimes a piece of Scheme code isn't working and you'd like to go
first subsection below explains how they work are why they are useful. 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.
Broadly speaking, Guile's breakpoint support consists of 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}.
@itemize @bullet When you set a breakpoint, you can specify any ``behaviour'' you like
@item for what should happen when the breakpoint is hit; a breakpoint
type-specific features for @emph{creating} breakpoints of various types ``behaviour'' is just a Scheme procedure with the right signature.
@item
relatively generic features for @emph{manipulating} the behaviour of
breakpoints once they've been created.
@end itemize
Different breakpoint types are implemented as different classes in a
GOOPS hierarchy with common base class @code{<breakpoint>}. The magic
of generic functions then allows most of the manipulation functions to
be generic by default but specializable (by breakpoint class) if the
need arises.
Generic breakpoint support is provided by the @code{(ice-9 debugger
breakpoints)} module, so you will almost always need to use this module
in order to access the functionality described here:
@smalllisp
(use-modules (ice-9 debugger breakpoints))
@end smalllisp
@noindent
You may like to add this to your @file{.guile} file.
@menu @menu
* Breakpoints Overview:: * Breakpoints Overview::
* Source Breakpoints::
* Procedural Breakpoints::
* Setting Breakpoints::
* break! trace! trace-subtree!::
* Accessing Breakpoints::
* Breakpoint Behaviours::
* Enabling and Disabling::
* Deleting Breakpoints::
* Breakpoint Information::
* Other Breakpoint Types::
@end menu @end menu
@ -187,8 +248,9 @@ available:
@itemize @bullet @itemize @bullet
@item @item
all the commands as described for last error debugging (@pxref{Debug all the commands as described for last error debugging
Last Error}), which allow you to explore the stack and so on (@pxref{Interactive Debugger}), which allow you to explore the stack and
so on
@item @item
additional commands for continuing program execution in various ways: additional commands for continuing program execution in various ways:
@ -200,607 +262,13 @@ Use of the interactive debugger is described in @ref{Interactive
Debugger}. Debugger}.
@node Source Breakpoints
@subsubsection Source Breakpoints
A source breakpoint is a breakpoint that triggers whenever program
execution hits a particular source location. A source breakpoint can be
conveniently set simply by evaluating code that has @code{##} inserted
into it at the position where you want the breakpoint to be.
For example, to set a breakpoint immediately before evaluation of
@code{(= n 0)} in the following procedure definition, evaluate:
@smalllisp
(define (fact1 n)
(if ##(= n 0)
1
(* n (fact1 (- n 1)))))
@print{}
Set breakpoint 1: standard input:4:9: (= n 0)
@end smalllisp
@noindent
Note the message confirming that you have set a breakpoint. If you
don't see this, something isn't working.
@code{##} is provided by the @code{(ice-9 debugger breakpoints source)} module,
so you must use this module before trying to set breakpoints in this
way:
@smalllisp
(use-modules (ice-9 debugger breakpoints source))
@end smalllisp
@noindent
You may like to add this to your @file{.guile} file.
The default behaviour for source breakpoints is @code{debug-here}
(@pxref{Breakpoint Behaviours}), which means to enter the command line
debugger when the breakpoint is hit. So, if you now use @code{fact1},
that is what happens.
@smalllisp
guile> (fact1 3)
Hit breakpoint 1: standard input:4:9: (= n 0)
Frame 3 at standard input:4:9
(= n 0)
debug>
@end smalllisp
@node Procedural Breakpoints
@subsubsection Procedural Breakpoints
A procedural breakpoint is a breakpoint that triggers whenever Guile is
about to apply a specified procedure to its (already evaluated)
arguments. To set a procedural breakpoint, call @code{break!} with the
target procedure as a single argument. For example:
@smalllisp
(define (fact1 n)
(if (= n 0)
1
(* n (fact1 (- n 1)))))
(break! fact1)
@print{}
Set breakpoint 1: [fact1]
@result{}
#<<procedure-breakpoint> 808b0b0>
@end smalllisp
Alternatives to @code{break!} are @code{trace!} and
@code{trace-subtree!}. The difference is that these three calls create
a breakpoint in the same place but with three different behaviours,
respectively @code{debug-here}, @code{trace-here} and
@code{trace-subtree}. Breakpoint behaviours are documented fully later
(@pxref{Breakpoint Behaviours}), but to give a quick taste, here's an
example of running code that includes a procedural breakpoint with the
@code{trace-here} behaviour.
@smalllisp
(trace! fact1)
@print{}
Set breakpoint 1: [fact1]
@result{}
#<<procedure-breakpoint> 808b0b0>
(fact1 4)
@print{}
| [fact1 4]
| | [fact1 3]
| | | [fact1 2]
| | | | [fact1 1]
| | | | | [fact1 0]
| | | | | 1
| | | | 2
| | | 6
| | 24
| 24
@result{}
24
@end smalllisp
To set and use procedural breakpoints, you will need to use the
@code{(ice-9 debugger breakpoints procedural)} module:
@smalllisp
(use-modules (ice-9 debugger breakpoints procedural))
@end smalllisp
@noindent
You may like to add this to your @file{.guile} file.
@node Setting Breakpoints
@subsubsection Setting Breakpoints
In general, that is. We've already seen how to set source and
procedural breakpoints conveniently in practice. This section explains
how those conveniences map onto a more general mechanism.
The general mechanism for setting breakpoints is the generic function
@code{set-breakpoint!}. Different kinds of breakpoints define
subclasses of the class @code{<breakpoint>} and provide their own
methods for @code{set-pbreakpoint!}.
For example, @code{(ice-9 debugger breakpoints procedural)} implements
the @code{<procedure-breakpoint>} subclass and provides a
@code{set-breakpoint!} method that takes a procedure argument:
@smalllisp
(set-breakpoint! @var{behavior} fact1)
@print{}
Set breakpoint 1: [fact1]
@result{}
#<<procedure-breakpoint> 808b0b0>
@end smalllisp
A non-type-specific @code{set-breakpoint!} method is provided by the
generic module @code{(ice-9 debugger breakpoints)}. It allows you to
change the behaviour of an existing breakpoint that is identified by
its breakpoint number.
@smalllisp
(set-breakpoint! @var{behavior} 1)
@end smalllisp
@node break! trace! trace-subtree!
@subsubsection break! trace! trace-subtree!
We have already talked above about the use of @code{break!},
@code{trace!} and @code{trace-subtree!} for setting procedural
breakpoints. Now that @code{set-breakpoint!} has been introduced, we
can reveal that @code{break!}, @code{trace!} and @code{trace-subtree!}
are in fact just wrappers for @code{set-breakpoint!} that specify
particular breakpoint behaviours, respectively @code{debug-here},
@code{trace-here} and @code{trace-subtree}.
@smalllisp
(break! . @var{args})
@equiv{} (set-breakpoint! debug-here . @var{args})
(trace! . @var{args})
@equiv{} (set-breakpoint! trace-here . @var{args})
(trace-subtree! . @var{args})
@equiv{} (set-breakpoint! trace-subtree . @var{args})
@end smalllisp
This means that these three procedures can be used to set the
corresponding behaviours for any type of breakpoint for which a
@code{set-breakpoint!} method exists, not just procedural ones.
@node Accessing Breakpoints
@subsubsection Accessing Breakpoints
Information about the state and behaviour of a breakpoint is stored in
an instance of the appropriate breakpoint class. To access and change
that information, therefore, you need to get hold of the desired
breakpoint instance.
The generic function @code{get-breakpoint} meets this need: For every
@code{set-breakpoint!} method there is a corresponding
@code{get-breakpoint} method. Note especially the useful
type-independent case:
@smalllisp
(get-breakpoint 1)
@result{}
#<<procedure-breakpoint> 808b0b0>
@end smalllisp
@node Breakpoint Behaviours
@subsubsection Breakpoint Behaviours
A breakpoint's @dfn{behaviour} determines what happens when that
breakpoint is hit. Several kinds of behaviour are generally useful.
@table @code
@item debug-here
Enter the command line debugger. This gives the opportunity to explore
the stack, evaluate expressions in any of the pending stack frames,
change breakpoint properties or set new breakpoints, and continue
program execution when you are done.
@item trace-here
Trace the current stack frame. For expressions being evaluated, this
shows the expression. For procedure applications, it shows the
procedure name and its arguments @emph{post-evaluation}. For both
expressions and applications, the indentation of the tracing indicates
whether the traced items are mutually tail recursive.
@item trace-subtree
Trace the current stack frame, and enable tracing for all future
evaluations and applications until the current stack frame is exited.
@code{trace-subtree} is a great preliminary exploration tool when all
you know is that there is a bug ``somewhere in XXX or in something that
XXX calls''.
@item (at-exit @var{thunk})
Don't do anything now, but arrange for @var{thunk} to be executed when
the current stack frame is exited. For example, the operation that most
debugging tools call ``finish'' is @code{(at-exit debug-here)}.
@item (at-next @var{count} @var{thunk})
@dots{} arrange for @var{thunk} to be executed when beginning the
@var{count}th next evaluation or application with source location in the
current file.
@item (at-entry @var{count} @var{thunk})
@dots{} arrange for @var{thunk} to be executed when beginning the
@var{count}th next evaluation (regardless of source location).
@item (at-apply @var{count} @var{thunk})
@dots{} arrange for @var{thunk} to be executed just before performing
the @var{count}th next application (regardless of source location).
@item (at-step @var{count} @var{thunk})
Synthesis of @code{at-entry} and @code{at-apply}; counts both
evaluations and applications.
@end table
Every breakpoint instance has a slot in which its behaviour is stored.
If you have a breakpoint instance in hand, you can change its behaviour
using the @code{bp-behaviour} accessor.
An @dfn{accessor} supports the setting of a property like this:
@smalllisp
(set! (bp-behaviour @var{breakpoint}) @var{new-behaviour})
@end smalllisp
@noindent
See the GOOPS manual for further information on accessors.
Alternatively, if you know how to specify the @var{location-args} for
the breakpoint in question, you can change its behaviour using
@code{set-breakpoint!}. For example:
@smalllisp
;; Change behaviour of breakpoint number 2.
(set-breakpoint! @var{new-behaviour} 2)
;; Change behaviour of procedural breakpoint on [fact1].
(set-breakpoint! @var{new-behaviour} fact1)
@end smalllisp
In all cases, the behaviour that you specify should be either a single
thunk, or a list of thunks, to be called when the breakpoint is hit.
The most common behaviours above are exported as thunks from the
@code{(ice-9 debugger behaviour)} module. So, if you use this module, you can
use those behaviours directly like this:
@smalllisp
(use-modules (ice-9 debugger behaviour))
(set-breakpoint! trace-subtree 2)
(set! (bp-behaviour (get-breakpoint 3)) debug-here)
@end smalllisp
@noindent
You can also use the list option to combine common behaviours:
@smalllisp
(set-breakpoint! (list trace-here debug-here) 2)
@end smalllisp
@noindent
Or, for more customized behaviour, you could build and use your own
thunk like this:
@smalllisp
(define (my-behaviour)
(trace-here)
(at-exit (lambda ()
(display "Exiting frame of my-behaviour bp\n")
... do something unusual ...)))
(set-breakpoint my-behaviour 2)
@end smalllisp
@node Enabling and Disabling
@subsubsection Enabling and Disabling
Independently of its behaviour, each breakpoint also keeps track of
whether it is currently enabled. This is a straightforward convenience
to allow breakpoints to be temporarily switched off without losing all
their carefully constructed properties.
If you have a breakpoint instance in hand, you can enable or disable it
using the @code{bp-enabled?} accessor.
Alternatively, you can enable or disable a breakpoint via its location
args by using @code{enable-breakpoint!} or @code{disable-breakpoint!}.
@smalllisp
(disable-breakpoint! fact1) ; disable the procedural breakpoint on fact1
(enable-breakpoint! 1) ; enable breakpoint 1
@end smalllisp
@code{enable-breakpoint!} and @code{disable-breakpoint!} are implemented
using @code{get-breakpoint} and @code{bp-enabled?}, so any
@var{location-args} that are valid for @code{get-breakpoint} will work
also for these procedures.
@node Deleting Breakpoints
@subsubsection Deleting Breakpoints
Given a breakpoint instance in hand, you can deactivate it and remove
it from the global list of current breakpoints by calling
@code{bp-delete!}.
Alternatively, you can delete a breakpoint by its location args:
@smalllisp
(delete-breakpoint! 1) ; delete breakpoint 1
@end smalllisp
@code{delete-breakpoint!} is implemented using @code{get-breakpoint} and
@code{bp-delete!}, so any @var{location-args} that are valid for
@code{get-breakpoint} will work also for @code{delete-breakpoint!}.
There is no way to reinstate a deleted breakpoint. Final destruction of
the breakpoint instance is determined by the usual garbage collection
rules.
@node Breakpoint Information
@subsubsection Breakpoint Information
To get Guile to print a description of a breakpoint instance, use
@code{bp-describe}:
@smalllisp
(bp-describe (get-breakpoint 1) #t) ; #t specifies standard output
@print{}
Breakpoint 1: [fact1]
enabled? = #t
behaviour = #<procedure trace-here ()>
@end smalllisp
Following the usual model, @code{describe-breakpoint} is also provided:
@smalllisp
(describe-breakpoint 1)
@print{}
Breakpoint 1: [fact1]
enabled? = #t
behaviour = #<procedure trace-here ()>
@end smalllisp
Finally, two stragglers. @code{all-breakpoints} returns a list of all
current breakpoints. @code{describe-all-breakpoints} combines
@code{bp-describe} and @code{all-breakpoints} by printing a description
of all current breakpoints to standard output.
@node Other Breakpoint Types
@subsubsection Other Breakpoint Types
Besides source and procedural breakpoints, Guile includes an early
implementation of a third class of breakpoints: @dfn{range} breakpoints.
These are breakpoints that trigger when program execution enters (or
perhaps exits) a defined range of source locations.
Sadly, these don't yet work well. The apparent problem is that the
extra methods for @code{set-breakpoint!} and @code{get-breakpoint} cause
some kind of explosion in the time taken by GOOPS to construct its
method cache and to dispatch calls involving these generic functions.
But we haven't really investigated enough to be sure that this is the
real issue.
If you're interested in looking and/or investigating anyway, please feel
free to check out and play with the @code{(ice-9 debugger breakpoints
range)} module.
The other kind of breakpoint that we'd like to have is watchpoints, but
this hasn't been implemented at all yet. Watchpoints may turn out to be
impractical for performance reasons.
@node Interactive Debugger
@subsection Using the Interactive Debugger
Guile's interactive debugger is a command line application that accepts
commands from you for examining the stack and, if at a breakpoint, for
continuing program execution in various ways. Unlike in the normal
Guile REPL, commands are typed mostly without parentheses.
When you first enter the debugger, it introduces itself with a message
like this:
@lisp
This is the Guile debugger -- for help, type `help'.
There are 3 frames on the stack.
Frame 2 at standard input:36:19
[+ 3 #\s]
debug>
@end lisp
@noindent
``debug>'' is the debugger's prompt, and a useful reminder that you are
not in the normal Guile REPL. The available commands are described in
detail in the following subsections.
@menu
* Display Backtrace:: backtrace.
* Frame Selection:: up, down, frame.
* Frame Information:: info args, info frame, position.
* Frame Evaluation:: evaluate.
* Single Stepping:: step, next.
* Run To Frame Exit:: finish, trace-finish.
* Continue Execution:: continue.
* Leave Debugger:: quit.
@end menu
@node Display Backtrace
@subsubsection Display Backtrace
The @code{backtrace} command, which can also be invoked as @code{bt} or
@code{where}, displays the call stack (aka backtrace) at the point where
the debugger was entered:
@lisp
debug> bt
In standard input:
36: 0* [make-string ...
36: 1* [* 4 ...
36: 2* [+ 3 #\s]
@end lisp
@deffn {Debugger Command} backtrace [count]
@deffnx {Debugger Command} bt [count]
@deffnx {Debugger Command} where [count]
Print backtrace of all stack frames, or of the innermost @var{count}
frames. With a negative argument, print the outermost -@var{count}
frames. If the number of frames isn't explicitly given, the debug
option @code{depth} determines the maximum number of frames printed.
@end deffn
The format of the displayed backtrace is the same as for the
@code{backtrace} procedure --- see @ref{Backtrace Format} for details.
@node Frame Selection
@subsubsection Frame Selection
A call stack consists of a sequence of stack @dfn{frames}, with each
frame describing one level of the nested evaluations and applications
that the program was executing when it hit a breakpoint or an error.
Frames are numbered such that frame 0 is the outermost --- i.e. the
operation on the call stack that began least recently --- and frame N-1
the innermost (where N is the total number of frames on the stack).
When you enter the debugger, the innermost frame is selected, which
means that the commands for getting information about the ``current''
frame, or for evaluating expressions in the context of the current
frame, will do so by default with respect to the innermost frame. To
select a different frame, so that these operations will apply to it
instead, use the @code{up}, @code{down} and @code{frame} commands like
this:
@lisp
debug> up
Frame 1 at standard input:36:14
[* 4 ...
debug> frame 0
Frame 0 at standard input:36:1
[make-string ...
debug> down
Frame 1 at standard input:36:14
[* 4 ...
@end lisp
@deffn {Debugger Command} up [n]
Move @var{n} frames up the stack. For positive @var{n}, this
advances toward the outermost frame, to higher frame numbers, to
frames that have existed longer. @var{n} defaults to one.
@end deffn
@deffn {Debugger Command} down [n]
Move @var{n} frames down the stack. For positive @var{n}, this
advances toward the innermost frame, to lower frame numbers, to frames
that were created more recently. @var{n} defaults to one.
@end deffn
@deffn {Debugger Command} frame [n]
Select and print a stack frame. With no argument, print the selected
stack frame. (See also ``info frame''.) An argument specifies the
frame to select; it must be a stack-frame number.
@end deffn
@node Frame Information
@subsubsection Frame Information
[to be completed]
@deffn {Debugger Command} {info frame}
All about selected stack frame.
@end deffn
@deffn {Debugger Command} {info args}
Argument variables of current stack frame.
@end deffn
@deffn {Debugger Command} position
Display the position of the current expression.
@end deffn
@node Frame Evaluation
@subsubsection Frame Evaluation
[to be completed]
@deffn {Debugger Command} evaluate expression
Evaluate an expression.
The expression must appear on the same line as the command,
however it may be continued over multiple lines.
@end deffn
@node Single Stepping
@subsubsection Single Stepping
[to be completed]
@deffn {Debugger Command} step [n]
Continue until entry to @var{n}th next frame.
@end deffn
@deffn {Debugger Command} next [n]
Continue until entry to @var{n}th next frame in same file.
@end deffn
@node Run To Frame Exit
@subsubsection Run To Frame Exit
[to be completed]
@deffn {Debugger Command} finish
Continue until evaluation of the current frame is complete, and
print the result obtained.
@end deffn
@deffn {Debugger Command} trace-finish
Trace until evaluation of the current frame is complete.
@end deffn
@node Continue Execution
@subsubsection Continue Execution
[to be completed]
@deffn {Debugger Command} continue
Continue program execution.
@end deffn
@node Leave Debugger
@subsubsection Leave Debugger
[to be completed]
@deffn {Debugger Command} quit
Exit the debugger.
@end deffn
@node Tracing @node Tracing
@subsection Tracing @subsection Tracing
Tracing has already been described as a breakpoint behaviour Tracing has already been described as a breakpoint behaviour, but we
(@pxref{Breakpoint Behaviours}), but we mention it again here because it mention it again here because it is so useful, and because Guile
is so useful, and because Guile actually now has @emph{two} mechanisms actually now has @emph{two} mechanisms for tracing, and its worth
for tracing, and its worth clarifying the differences between them. clarifying the differences between them.
@menu @menu
* Old Tracing:: Tracing provided by (ice-9 debug). * Old Tracing:: Tracing provided by (ice-9 debug).

411
doc/ref/scheme-using.texi Normal file
View file

@ -0,0 +1,411 @@
@c -*-texinfo-*-
@c This is part of the GNU Guile Reference Manual.
@c Copyright (C) 2006
@c Free Software Foundation, Inc.
@c See the file guile.texi for copying conditions.
@node Using Guile Interactively
@section Using Guile Interactively
When you start up Guile by typing just @code{guile}, without a
@code{-c} argument or the name of a script to execute, you get an
interactive interpreter where you can enter Scheme expressions, and
Guile will evaluate them and print the results for you. Here are some
simple examples.
@lisp
guile> (+ 3 4 5)
12
guile> (display "Hello world!\n")
Hello world!
guile> (values 'a 'b)
a
b
@end lisp
@noindent
This mode of use is called a @dfn{REPL}, which is short for
``Read-Eval-Print Loop'', because the Guile interpreter first reads the
expression that you have typed, then evaluates it, and then prints the
result.
@menu
* Readline::
* Value Historyx::
* Error Handling::
* Interactive Debugger:: Using the interactive debugger.
@end menu
@node Readline
@subsection Readline
To make it easier for you to repeat and vary previously entered
expressions, or to edit the expression that you're typing in, Guile
can use the GNU Readline library. This is not enabled by default
because of licensing reasons, but all you need to activate Readline is
the following pair of lines.
@lisp
guile> (use-modules (ice-9 readline))
guile> (activate-readline)
@end lisp
It's a good idea to put these two lines (without the ``guile>''
prompts) in your @file{.guile} file. Guile reads this file when it
starts up interactively, so anything in this file has the same effect
as if you type it in by hand at the ``guile>'' prompt.
@node Value Historyx
@subsection Value History
Just as Readline helps you to reuse a previous input line, @dfn{value
history} allows you to use the @emph{result} of a previous evaluation
in a new expression. When value history is enabled, each evaluation
result is automatically assigned to the next in the sequence of
variables @code{$1}, @code{$2}, @dots{}, and you can then use these
variables in subsequent expressions.
@lisp
guile> (iota 10)
$1 = (0 1 2 3 4 5 6 7 8 9)
guile> (apply * (cdr $1))
$2 = 362880
guile> (sqrt $2)
$3 = 602.3952191045344
guile> (cons $2 $1)
$4 = (362880 0 1 2 3 4 5 6 7 8 9)
@end lisp
To enable value history, type @code{(use-modules (ice-9 history))} at
the Guile prompt, or add this to your @file{.guile} file. (It is not
enabled by default, to avoid the possibility of conflicting with some
other use you may have for the variables @code{$1}, @code{$2},
@dots{}, and also because it prevents the stored evaluation results
from being garbage collected, which some people may not want.)
@node Error Handling
@subsection Error Handling
When code being evaluated from the REPL hits an error, Guile remembers
the execution context where the error occurred and can give you three
levels of information about what the error was and exactly where it
occurred.
By default, Guile then displays only the first level, which is the most
immediate information about where and why the error occurred, for
example:
@lisp
(make-string (* 4 (+ 3 #\s)) #\space)
@print{}
standard input:2:19: In procedure + in expression (+ 3 #\s):
standard input:2:19: Wrong type argument: #\s
ABORT: (wrong-type-arg)
Type "(backtrace)" to get more information or "(debug)" to enter the debugger.
@end lisp
@noindent
However, as the message above says, you can obtain more information
about the context of the error by typing @code{(backtrace)} or
@code{(debug)}.
@code{(backtrace)} displays the Scheme call stack at the point where the
error occurred:
@lisp
(backtrace)
@print{}
Backtrace:
In standard input:
2: 0* [make-string ...
2: 1* [* 4 ...
2: 2* [+ 3 #\s]
Type "(debug-enable 'backtrace)" if you would like a backtrace
automatically if an error occurs in the future.
@end lisp
@noindent
In a more complex scenario than this one, this can be extremely useful
for understanding where and why the error occurred. You can make Guile
show the backtrace automatically by adding @code{(debug-enable
'backtrace)} to your @file{.guile}.
@code{(debug)} takes you into Guile's interactive debugger, which
provides commands that allow you to
@itemize @bullet
@item
display the Scheme call stack at the point where the error occurred
(the @code{backtrace} command --- see @ref{Display Backtrace})
@item
move up and down the call stack, to see in detail the expression being
evaluated, or the procedure being applied, in each @dfn{frame} (the
@code{up}, @code{down}, @code{frame}, @code{position}, @code{info args}
and @code{info frame} commands --- see @ref{Frame Selection} and
@ref{Frame Information})
@item
examine the values of variables and expressions in the context of each
frame (the @code{evaluate} command --- see @ref{Frame Evaluation}).
@end itemize
@noindent
This is documented further in the following section.
@node Interactive Debugger
@subsection Using the Interactive Debugger
Guile's interactive debugger is a command line application that accepts
commands from you for examining the stack and, if at a breakpoint, for
continuing program execution in various ways. Unlike in the normal
Guile REPL, commands are typed mostly without parentheses.
When you first enter the debugger, it introduces itself with a message
like this:
@lisp
This is the Guile debugger -- for help, type `help'.
There are 3 frames on the stack.
Frame 2 at standard input:36:19
[+ 3 #\s]
debug>
@end lisp
@noindent
``debug>'' is the debugger's prompt, and a reminder that you are not in
the normal Guile REPL. The available commands are described in the
following subsections.
@menu
* Display Backtrace:: backtrace.
* Frame Selection:: up, down, frame.
* Frame Information:: info args, info frame, position.
* Frame Evaluation:: evaluate.
* Single Stepping:: step, next.
* Run To Frame Exit:: finish, trace-finish.
* Continue Execution:: continue.
* Leave Debugger:: quit.
@end menu
@node Display Backtrace
@subsubsection Display Backtrace
The @code{backtrace} command, which can also be invoked as @code{bt} or
@code{where}, displays the call stack (aka backtrace) at the point where
the debugger was entered:
@lisp
debug> bt
In standard input:
36: 0* [make-string ...
36: 1* [* 4 ...
36: 2* [+ 3 #\s]
@end lisp
@deffn {Debugger Command} backtrace [count]
@deffnx {Debugger Command} bt [count]
@deffnx {Debugger Command} where [count]
Print backtrace of all stack frames, or of the innermost @var{count}
frames. With a negative argument, print the outermost -@var{count}
frames. If the number of frames isn't explicitly given, the debug
option @code{depth} determines the maximum number of frames printed.
@end deffn
The format of the displayed backtrace is the same as for the
@code{backtrace} procedure.
@node Frame Selection
@subsubsection Frame Selection
A call stack consists of a sequence of stack @dfn{frames}, with each
frame describing one level of the nested evaluations and applications
that the program was executing when it hit a breakpoint or an error.
Frames are numbered such that frame 0 is the outermost --- i.e. the
operation on the call stack that began least recently --- and frame N-1
the innermost (where N is the total number of frames on the stack).
When you enter the debugger, the innermost frame is selected, which
means that the commands for getting information about the ``current''
frame, or for evaluating expressions in the context of the current
frame, will do so by default with respect to the innermost frame. To
select a different frame, so that these operations will apply to it
instead, use the @code{up}, @code{down} and @code{frame} commands like
this:
@lisp
debug> up
Frame 1 at standard input:36:14
[* 4 ...
debug> frame 0
Frame 0 at standard input:36:1
[make-string ...
debug> down
Frame 1 at standard input:36:14
[* 4 ...
@end lisp
@deffn {Debugger Command} up [n]
Move @var{n} frames up the stack. For positive @var{n}, this
advances toward the outermost frame, to higher frame numbers, to
frames that have existed longer. @var{n} defaults to one.
@end deffn
@deffn {Debugger Command} down [n]
Move @var{n} frames down the stack. For positive @var{n}, this
advances toward the innermost frame, to lower frame numbers, to frames
that were created more recently. @var{n} defaults to one.
@end deffn
@deffn {Debugger Command} frame [n]
Select and print a stack frame. With no argument, print the selected
stack frame. (See also ``info frame''.) An argument specifies the
frame to select; it must be a stack-frame number.
@end deffn
@node Frame Information
@subsubsection Frame Information
[to be completed]
@deffn {Debugger Command} {info frame}
All about selected stack frame.
@end deffn
@deffn {Debugger Command} {info args}
Argument variables of current stack frame.
@end deffn
@deffn {Debugger Command} position
Display the position of the current expression.
@end deffn
@node Frame Evaluation
@subsubsection Frame Evaluation
[to be completed]
@deffn {Debugger Command} evaluate expression
Evaluate an expression.
The expression must appear on the same line as the command,
however it may be continued over multiple lines.
@end deffn
@node Single Stepping
@subsubsection Single Stepping
[to be completed]
@deffn {Debugger Command} step [n]
Continue until entry to @var{n}th next frame.
@end deffn
@deffn {Debugger Command} next [n]
Continue until entry to @var{n}th next frame in same file.
@end deffn
@node Run To Frame Exit
@subsubsection Run To Frame Exit
[to be completed]
@deffn {Debugger Command} finish
Continue until evaluation of the current frame is complete, and
print the result obtained.
@end deffn
@deffn {Debugger Command} trace-finish
Trace until evaluation of the current frame is complete.
@end deffn
@node Continue Execution
@subsubsection Continue Execution
[to be completed]
@deffn {Debugger Command} continue
Continue program execution.
@end deffn
@node Leave Debugger
@subsubsection Leave Debugger
[to be completed]
@deffn {Debugger Command} quit
Exit the debugger.
@end deffn
@node Using Guile in Emacs
@section Using Guile in Emacs
The Guile distribution includes a rich environment for working on Guile
Scheme code within Emacs. The idea of this environment is to allow you
to work on Guile Scheme code in the same kind of way that Emacs allows
you to work on Emacs Lisp code: providing easy access to help,
evaluating arbitrary fragments of code, a nice debugging interface, and
so on.@footnote{You can also, of course, run a Guile session in Emacs
simply by typing ``guile'' in a @code{*shell*} buffer. The environment
described here provides a much better integration than that, though.}
The thinking behind this environment is that you will usually be doing
one of two things.
@enumerate
@item
Writing or editing code. The code will be in a normal Emacs Scheme
mode buffer, and the Guile/Emacs environment extends Scheme mode to
add keystrokes and menu items for the things that are likely to be
useful to you when working on code:
@itemize
@item
completing the identifier at point
@item
accessing Guile's built in help
@item
evaluating fragments of code to check what they do.
@end itemize
@item
Debugging a Guile Scheme program. When your program hits an error or
a breakpoint, the Guile/Emacs environment shows you the relevant code
and the Scheme stack, and makes it easy to
@itemize
@item
look at the values of local variables
@item
see what is happening at all levels of the Scheme stack
@item
continue execution, either normally or step by step.
@end itemize
@end enumerate
Combinations of these work well too. You can evaluate a fragment of
code (in a Scheme buffer) that contains a breakpoint, then use the
debugging interface to step through the code at the breakpoint. You
can also run a program until it hits a breakpoint, then examine,
modify and reevaluate some of the relevant code, and then tell the
program to continue running.
@c Local Variables:
@c TeX-master: "guile.texi"
@c End: