mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 03:40:34 +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:
parent
b49123789f
commit
46f7666d7f
5 changed files with 608 additions and 709 deletions
|
@ -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>
|
||||
|
||||
* api-utility.texi (Equality): Mentioned the behavior of `equal?'
|
||||
|
|
|
@ -56,6 +56,7 @@ guile_TEXINFOS = preface.texi \
|
|||
gh.texi \
|
||||
api-overview.texi \
|
||||
scheme-debugging.texi \
|
||||
scheme-using.texi \
|
||||
indices.texi \
|
||||
script-getopt.texi \
|
||||
data-rep.texi \
|
||||
|
|
|
@ -137,7 +137,7 @@ x
|
|||
@comment The title is printed in a large font.
|
||||
@title Guile Reference Manual
|
||||
@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
|
||||
@author The Guile Developers
|
||||
|
@ -219,6 +219,8 @@ etc. that make up Guile's application programming interface (API),
|
|||
* Basic Ideas:: Basic ideas in Scheme.
|
||||
* Guile Scheme:: Guile's implementation of Scheme.
|
||||
* 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.
|
||||
* Further Reading:: Where to find out more about Scheme.
|
||||
@end menu
|
||||
|
@ -226,6 +228,7 @@ etc. that make up Guile's application programming interface (API),
|
|||
@include scheme-ideas.texi
|
||||
@include scheme-intro.texi
|
||||
@include scheme-scripts.texi
|
||||
@include scheme-using.texi
|
||||
@include scheme-debugging.texi
|
||||
@include scheme-reading.texi
|
||||
|
||||
|
|
|
@ -28,135 +28,196 @@ execution context at a breakpoint, or when the last error occurred.
|
|||
The details are more complex and more powerful @dots{}
|
||||
|
||||
@menu
|
||||
* Debug Last Error:: Debugging the most recent error.
|
||||
* Examples::
|
||||
* Intro to Breakpoints:: Setting and manipulating them.
|
||||
* Interactive Debugger:: Using the interactive debugger.
|
||||
* Tracing:: Tracing program execution.
|
||||
@end menu
|
||||
|
||||
|
||||
@node Debug Last Error
|
||||
@subsection Debugging the Most Recent Error
|
||||
@node Examples
|
||||
@subsection Examples
|
||||
|
||||
When an error is signalled, Guile remembers the execution context where
|
||||
the error occurred. By default, Guile then displays only 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 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}.
|
||||
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
|
||||
* Backtrace Format:: How to interpret a backtrace.
|
||||
* Single Stepping through a Procedure's Code::
|
||||
* Profiling or Tracing a Procedure's Code::
|
||||
@end menu
|
||||
|
||||
|
||||
@node Backtrace Format
|
||||
@subsubsection How to Interpret a Backtrace
|
||||
@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
|
||||
|
||||
If you are not already familiar with the concept of breakpoints, the
|
||||
first subsection below explains how they work are why they are useful.
|
||||
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.
|
||||
|
||||
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
|
||||
@item
|
||||
type-specific features for @emph{creating} breakpoints of various types
|
||||
|
||||
@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.
|
||||
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::
|
||||
* 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
|
||||
|
||||
|
||||
|
@ -187,8 +248,9 @@ available:
|
|||
|
||||
@itemize @bullet
|
||||
@item
|
||||
all the commands as described for last error debugging (@pxref{Debug
|
||||
Last Error}), which allow you to explore the stack and so on
|
||||
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:
|
||||
|
@ -200,607 +262,13 @@ Use of the interactive debugger is described in @ref{Interactive
|
|||
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
|
||||
@subsection Tracing
|
||||
|
||||
Tracing has already been described as a breakpoint behaviour
|
||||
(@pxref{Breakpoint Behaviours}), 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.
|
||||
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).
|
||||
|
|
411
doc/ref/scheme-using.texi
Normal file
411
doc/ref/scheme-using.texi
Normal 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:
|
Loading…
Add table
Add a link
Reference in a new issue