1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-04-30 03:40:34 +02:00

* api-debug.texi (Low Level Trap Calls): Removed (material

duplicated elsewhere); doc for with-traps and debug-object? moved
to section on evaluator trap options.
(High Level Traps): Renamed just `Traps'.  Add references to
evaluator trap options and debug options.  Make language
appropriate for core Guile (as opposed to previously separate
package).
(Location Traps): Corrected to reflect that location traps now
specify a specific position, not a range of positions.
(Debugging Examples): New (content moved here from
scheme-debugging.texi, and updated to use traps instead of
breakpoints).

* api-modules.texi (Included Guile Modules): Change `Debugging
Features' reference to `Tracing'.

* api-options.texi (Evaluator trap options): Doc for with-traps
and debug-object? is now here.

* guile.texi, scheme-debugging.texi: Move the `Tracing' content of
scheme-debugging.texi to the Modules section.

* scheme-using.texi (Using Guile in Emacs, GDS Getting Started):
Minor edits.

* scheme-debugging.texi (Debugging Features, Intro to
Breakpoints): Removed.
(Examples): Moved to api-debug.texi.
(Tracing, Old Tracing): Promoted one level.
(New Tracing, Tracing Compared): Removed.
This commit is contained in:
Neil Jerram 2008-03-19 22:51:24 +00:00
parent cc7e01cedd
commit 24dbb5ed10
7 changed files with 402 additions and 644 deletions

View file

@ -1,3 +1,36 @@
2008-03-19 Neil Jerram <neil@ossau.uklinux.net>
* api-debug.texi (Low Level Trap Calls): Removed (material
duplicated elsewhere); doc for with-traps and debug-object? moved
to section on evaluator trap options.
(High Level Traps): Renamed just `Traps'. Add references to
evaluator trap options and debug options. Make language
appropriate for core Guile (as opposed to previously separate
package).
(Location Traps): Corrected to reflect that location traps now
specify a specific position, not a range of positions.
(Debugging Examples): New (content moved here from
scheme-debugging.texi, and updated to use traps instead of
breakpoints).
* api-modules.texi (Included Guile Modules): Change `Debugging
Features' reference to `Tracing'.
* api-options.texi (Evaluator trap options): Doc for with-traps
and debug-object? is now here.
* guile.texi, scheme-debugging.texi: Move the `Tracing' content of
scheme-debugging.texi to the Modules section.
* scheme-using.texi (Using Guile in Emacs, GDS Getting Started):
Minor edits.
* scheme-debugging.texi (Debugging Features, Intro to
Breakpoints): Removed.
(Examples): Moved to api-debug.texi.
(Tracing, Old Tracing): Promoted one level.
(New Tracing, Tracing Compared): Removed.
2008-03-08 Julian Graham <joolean@gmail.com>
* api-scheduling.texi (Threads): Add documentation for new

View file

@ -17,9 +17,9 @@ infrastructure that builds on top of those calls.
@menu
* Evaluation Model:: Evaluation and the Scheme stack.
* Debug on Error:: Debugging when an error occurs.
* Low Level Trap Calls::
* High Level Traps::
* Traps::
* Breakpoints::
* Debugging Examples::
@end menu
@node Evaluation Model
@ -610,65 +610,8 @@ Invoke the Guile debugger to explore the context of the last error.
@end deffn
@node Low Level Trap Calls
@subsection Low Level Trap Calls
@cindex Low level trap calls
@cindex Evaluator trap calls
Guile's evaluator can be configured to call the following four user-specified
procedures at various points in its operation.
@table @dfn
@item apply-frame-handler
@item enter-frame-handler
@item exit-frame-handler
@item memoize-symbol-handler
@end table
These procedures, and the circumstances under which the evaluator
calls them, are configured by the ``evaluator trap options'' interface
(@pxref{Evaluator trap options}), and by the @code{trace} and
@code{breakpoints} fields of the ``debug options'' interface
(@pxref{Debugger options}).
It is not necessary to understand the fine details of these low level
calls, and of the options which configure them, in order to use the
class-based trap interface effectively. @code{guile-debugging} takes
care of setting these options as required for whatever set of
installed trap objects the user specifies.@footnote{And consequently,
when using the class-based trap interface, users/applications should
@emph{not} modify these options themselves, to avoid interfering with
@code{guile-debugging}'s option settings.} It is useful, though, to
have a overall idea of how the evaluator works and when these low
level calls can happen, as follows.
@cindex Frame entry
@cindex Frame exit
On the basis of this description, we can now specify the points where
low level trap calls may occur (subject to configuration). Namely,
whenever a new frame is added to the stack, because the evaluator is
about to begin a new evaluation or to perform a new application, and
whenever a frame is being removed from the stack because the
computation that it refers to has completed and is returning its
value@footnote{If this raises the question of how expressions with
no return value are handled, the answer is that all computations in
Guile return a value. Those that appear to have no return value do so
by using the special @code{*unspecified*} value, which the Guile REPL
avoids displaying to the user.} to its caller.
@deffn {Scheme Procedure} with-traps thunk
@deffnx {C Function} scm_with_traps (thunk)
Call @var{thunk} with traps enabled.
@end deffn
@deffn {Scheme Procedure} debug-object? obj
@deffnx {C Function} scm_debug_object_p (obj)
Return @code{#t} if @var{obj} is a debug object.
@end deffn
@node High Level Traps
@subsection High Level Traps
@node Traps
@subsection Traps
@cindex Traps
@cindex Evaluator trap calls
@ -678,29 +621,33 @@ Return @code{#t} if @var{obj} is a debug object.
@cindex Code coverage
@cindex Profiling
The low level C code of Guile's evaluator can be configured to call
out at key points to arbitrary user-specified code. In principle this
allows Scheme code to implement any model it chooses for examining the
evaluation stack as program execution proceeds, and for suspending
execution to be resumed later. Possible applications of this feature
include breakpoints, runtime tracing, code coverage, and profiling.
out at key points to arbitrary user-specified procedures. These
procedures, and the circumstances under which the evaluator calls
them, are configured by the ``evaluator trap options'' interface
(@pxref{Evaluator trap options}), and by the @code{trace} and
@code{breakpoints} fields of the ``debug options'' interface
(@pxref{Debugger options}). In principle this allows Scheme code to
implement any model it chooses for examining the evaluation stack as
program execution proceeds, and for suspending execution to be resumed
later. Possible applications of this feature include breakpoints,
runtime tracing, code coverage, and profiling.
@cindex Trap classes
@cindex Trap objects
Based on these low level trap calls, the enhancements described here
provide a much higher level, object-oriented interface for the
manipulation of traps. Different kinds of trap are represented as
GOOPS classes; for example, the @code{<procedure-trap>} class
describes traps that are triggered by invocation of a specified
procedure. A particular instance of a trap class --- or @dfn{trap
object} --- describes the condition under which a single trap will be
triggered, and what will happen then; for example, an instance of
@code{<procedure-trap>} whose @code{procedure} and @code{behaviour}
slots contain @code{my-factorial} and @code{debug-trap} would be a
trap that enters the command line debugger when the
@code{my-factorial} procedure is invoked.
Based on these low level trap calls, Guile provides a higher level,
object-oriented interface for the manipulation of traps. Different
kinds of trap are represented as GOOPS classes; for example, the
@code{<procedure-trap>} class describes traps that are triggered by
invocation of a specified procedure. A particular instance of a trap
class --- or @dfn{trap object} --- describes the condition under which
a single trap will be triggered, and what will happen then; for
example, an instance of @code{<procedure-trap>} whose @code{procedure}
and @code{behaviour} slots contain @code{my-factorial} and
@code{debug-trap} would be a trap that enters the command line
debugger when the @code{my-factorial} procedure is invoked.
The following subsubsections describe all this in greater detail, for both
the user wanting to use traps, and the developer interested in
The following subsections describe all this in detail, for both the
user wanting to use traps, and the developer interested in
understanding how the interface hangs together.
@ -813,8 +760,8 @@ shorthands for setting common kinds of traps. @xref{Trap Shorthands},
for some examples.
The ability to install, uninstall and reinstall a trap without losing
its definition is @code{guile-debugging}'s equivalent of the
disable/enable commands provided by debuggers like GDB.
its definition is Guile's equivalent of the disable/enable commands
provided by debuggers like GDB.
@deffn {Generic Function} install-trap trap
Install the trap object @var{trap}, so that its behaviour will be
@ -832,9 +779,9 @@ met.
@subsubsection Specifying Trap Behaviour
@cindex Trap behaviour
@code{guile-debugging} provides several ``out-of-the-box'' behaviours
for common needs. All of the following can be used directly as the
value of the @code{#:behaviour} option when creating a trap object.
Guile provides several ``out-of-the-box'' behaviours for common needs.
All of the following can be used directly as the value of the
@code{#:behaviour} option when creating a trap object.
@deffn {Procedure} debug-trap trap-context
Enter Guile's command line debugger to explore the stack at
@ -1179,9 +1126,9 @@ guile> (rev '(a b c))
@node Tracing and (ice-9 debug)
@subsubsection Tracing and (ice-9 debug)
The @code{(ice-9 debug)} module of the core Guile distribution
provides a tracing facility that is roughly similar to that described
here, but there are important differences.
The @code{(ice-9 debug)} module provides a tracing facility
(@pxref{Tracing}) that is roughly similar to that described here, but
there are important differences.
@itemize @bullet
@item
@ -1202,35 +1149,30 @@ in stack depth, by using indentation like this:
@end lisp
However its output can @emph{only} show the information seen here,
which corresponds to @code{guile-debugging}'s @code{trace/info}
procedure; it cannot be configured to show other pieces of information
about the trap context in the way that @code{guile-debugging}'s trace
feature can.
which corresponds to @code{(ice-9 debugging trace)}'s
@code{trace/info} procedure; it cannot be configured to show other
pieces of information about the trap context in the way that the
@code{(ice-9 debugging trace)} implementation can.
@item
The @code{(ice-9 debug)} trace only allows the tracing of procedure
applications and their return values, whereas @code{guile-debugging}'s
trace allows any kind of trap to be traced.
applications and their return values, whereas the @code{(ice-9 debugging
trace)} implementation allows any kind of trap to be traced.
It's interesting to note that @code{(ice-9 debug)}'s restriction here,
which might initially appear to be just a straightforward consequence
of its implementation, is also somewhat dictated by its pictorial
display. The use of indentation in the output relies on hooking into
the low level trap calls in such a way that the trapped application
entries and exits exactly balance each other.
@code{guile-debugging}'s more general traps interface allows traps to
be installed such that entry and exit traps don't necessarily balance,
which means that, in general, indentation diagrams like the one above
don't work.
entries and exits exactly balance each other. The @code{ice-9
debugging trace} implementation allows traps to be installed such that
entry and exit traps don't necessarily balance, which means that, in
general, indentation diagrams like the one above don't work.
@end itemize
It isn't currently possible to use both @code{(ice-9 debug)} trace and
@code{guile-debugging} in the same Guile session, because their settings
of the low level trap options conflict with each other. (It should be
possible to fix this, by modifying @code{(ice-9 debug)} to use
@code{guile-debugging}'s trap installation interface, but only if and
when @code{guile-debugging} is integrated into the core Guile
distribution.)
@code{(ice-9 debugging trace)} in the same Guile session, because
their settings of the low level trap options conflict with each other.
@node Traps Installing More Traps
@ -1456,9 +1398,9 @@ user would intuitively think of as single-stepping through their code,
either through code in general (roughly corresponding to GDB's
@code{step} command, for example), or through code from a particular
source file (roughly corresponding to GDB's @code{next}). Therefore
if you are using @code{guile-debugging} to single-step through code
and finding its behaviour counter-intuitive, please let me know so
that I can improve it.
if you are using a step trap to single-step through code and finding
its behaviour counter-intuitive, please report that so we can improve
it.
The implementation and options of the @code{<step-trap>} class are
complicated by the fact that it is unreliable to determine whether a
@ -1620,16 +1562,16 @@ following subsubsection.
@subsubsection Location Traps
The @code{<location-trap>} class implements traps that are triggered
by evaluation of code at a specific source location or within a
specified range of source locations. When compared with source traps,
they are easier to set, and do not become irrelevant when the relevant
code is reloaded; but unfortunately they are considerably less
efficient, as they require running some ``are we in the right place
for a trap'' code on every low level frame entry trap call.
by evaluation of code at a specific source location. When compared
with source traps, they are easier to set, and do not become
irrelevant when the relevant code is reloaded; but unfortunately they
are a lot less efficient, as they require running some ``are we in the
right place for a trap'' code on every low level frame entry trap
call.
@deffn {Class} <location-trap>
Class for traps triggered by evaluation of code at a specific source
location or in a specified range of source locations.
location.
@end deffn
@deffn {Trap Option} #:file-regexp regexp
@ -1637,31 +1579,27 @@ A regular expression specifying the filenames that will match this
trap. This option must be specified when creating a location trap.
@end deffn
@deffn {Trap Option} #:line line-spec
If specified, @var{line-spec} describes either a single line, in which
case it is a single integer, or a range of lines, in which case it is
a pair of the form @code{(@var{min-line} . @var{max-line})}. All line
numbers are 0-based, and the range form is inclusive-inclusive. If
@code{#f} or not specified, the trap is not restricted by line number.
(Default value @code{#f}.)
@deffn {Trap Option} #:line line
The line number (0-based) of the source location at which the trap
should be triggered. This option must be specified when creating a
location trap.
@end deffn
@deffn {Trap Option} #:column column-spec
If specified, @var{column-spec} describes either a single column, in
which case it is a single integer, or a range of columns, in which
case it is a pair of the form @code{(@var{min-column}
. @var{max-column})}. All column numbers are 0-based, and the range
form is inclusive-inclusive. If @code{#f} or not specified, the trap
is not restricted by column number. (Default value @code{#f}.)
@deffn {Trap Option} #:column column
The column number (0-based) of the source location at which the trap
should be triggered. This option must be specified when creating a
location trap.
@end deffn
@noindent
Example:
Here is an example, which matches the @code{(facti (- n 1) (* a n))}
expression in @file{ice-9/debugging/example-fns.scm}:
@lisp
(install-trap (make <location-trap>
#:file-regexp "example-fns.scm"
#:line '(11 . 13)
#:line 11
#:column 6
#:behaviour gds-debug-trap))
@end lisp
@ -1672,8 +1610,7 @@ Example:
If the code described in the preceding subsubsections for creating and
manipulating traps seems a little long-winded, it is of course
possible to define more convenient shorthand forms for typical usage
patterns. For example, my own @file{.guile} file contains the
following definitions for setting breakpoints and for tracing.
patterns. Here are some examples.
@lisp
(define (break! proc)
@ -1694,11 +1631,11 @@ following definitions for setting breakpoints and for tracing.
trace-until-exit))))
@end lisp
Definitions like these are not provided out-of-the-box by
@code{guile-debugging}, because different users will have different
ideas about what their default debugger should be, or, for example,
which of the common trap options (@pxref{Common Trap Options}) it
might be useful to expose through such shorthand procedures.
Definitions like these are not provided out-of-the-box by Guile,
because different users will have different ideas about what their
default debugger should be, or, for example, which of the common trap
options (@pxref{Common Trap Options}) it might be useful to expose
through such shorthand procedures.
@node Trap Utilities
@ -1760,12 +1697,11 @@ While they are an important piece of infrastructure, and directly
usable in some scenarios, traps are still too low level to meet some
of the requirements of interactive development.
For example, in my experience a common scenario is that a newly
written procedure is not working properly, and so you'd like to be
able to step or trace through its code to find out why. Ideally this
should be possible from the IDE and without having to modify the
source code. There are two problems with using traps directly in this
scenario.
A common scenario is that a newly written procedure is not working
properly, and so you'd like to be able to step or trace through its
code to find out why. Ideally this should be possible from the IDE
and without having to modify the source code. There are two problems
with using traps directly in this scenario.
@enumerate
@item
@ -1885,6 +1821,216 @@ be managed through GDS. For the details of GDS's breakpoints
interface, see @ref{Setting and Managing Breakpoints}.
@node Debugging Examples
@subsection Debugging Examples
Here we present some examples of what you can do with the debugging
facilities just described.
@menu
* Single Stepping through a Procedure's Code::
* Profiling or Tracing a Procedure's Code::
@end menu
@node Single Stepping through a Procedure's Code
@subsubsection Single Stepping through a Procedure's Code
A good way to explore in detail what a Scheme procedure does is to set
a trap on it and then single step through what it does. To do this,
make and install a @code{<procedure-trap>} with the @code{debug-trap}
behaviour from @code{(ice-9 debugging ice-9-debugger-extensions)}.
The following sample session illustrates this. It assumes that the
file @file{matrix.scm} defines a procedure @code{mkmatrix}, which is
the one we want to explore, and another procedure @code{do-main} which
calls @code{mkmatrix}.
@lisp
$ /usr/bin/guile -q
guile> (use-modules (ice-9 debugger)
(ice-9 debugging ice-9-debugger-extensions)
(ice-9 debugging traps))
guile> (load "matrix.scm")
guile> (install-trap (make <procedure-trap>
#:procedure mkmatrix
#:behaviour debug-trap))
guile> (do-main 4)
This is the Guile debugger -- for help, type `help'.
There are 3 frames on the stack.
Frame 2 at matrix.scm:8:3
[mkmatrix]
debug> next
Frame 3 at matrix.scm:4:3
(let ((x 1)) (quote this-is-a-matric))
debug> info frame
Stack frame: 3
This frame is an evaluation.
The expression being evaluated is:
matrix.scm:4:3:
(let ((x 1)) (quote this-is-a-matric))
debug> next
Frame 3 at matrix.scm:5:21
(quote this-is-a-matric)
debug> bt
In unknown file:
?: 0* [primitive-eval (do-main 4)]
In standard input:
4: 1* [do-main 4]
In matrix.scm:
8: 2 [mkmatrix]
...
5: 3 (quote this-is-a-matric)
debug> quit
this-is-a-matric
guile>
@end lisp
Or you can use Guile's Emacs interface (GDS), by using the module
@code{(ice-9 gds-client)} instead of @code{(ice-9 debugger)} and
@code{(ice-9 debugging ice-9-debugger-extensions)}, and changing
@code{debug-trap} to @code{gds-debug-trap}. Then the stack and
corresponding source locations are displayed in Emacs instead of on
the Guile command line.
@node Profiling or Tracing a Procedure's Code
@subsubsection Profiling or Tracing a Procedure's Code
What if you wanted to get a trace of everything that the Guile
evaluator does within a given procedure, but without Guile stopping
and waiting for your input at every step? For this requirement you
can install a trap on the procedure, as in the previous example, but
instead of @code{debug-trap} or @code{gds-debug-trap}, use the
@code{trace-trap} and @code{trace-until-exit} behaviours provided by
the @code{(ice-9 debugging trace)} module.
@lisp
guile> (use-modules (ice-9 debugging traps) (ice-9 debugging trace))
guile> (load "matrix.scm")
guile> (install-trap (make <procedure-trap>
#:procedure mkmatrix
#:behaviour (list trace-trap trace-until-exit)))
guile> (do-main 4)
| 2: [mkmatrix]
| 3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> define #f]
| 3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> define #f]
| 4: (and (memq sym bindings) (let ...))
| 5: (memq sym bindings)
| 5: [memq define (debug)]
| 5: =>#f
| 3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> define #f]
| 3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> define #f]
| 4: (and (memq sym bindings) (let ...))
| 5: (memq sym bindings)
| 5: [memq define (debug)]
| 5: =>#f
| 3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
| 3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
| 4: (and (memq sym bindings) (let ...))
| 5: (memq sym bindings)
| 5: [memq let (debug)]
| 5: =>#f
| 3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
| 3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
| 4: (and (memq sym bindings) (let ...))
| 5: (memq sym bindings)
| 5: [memq let (debug)]
| 5: =>#f
| 3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
| 3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
| 4: (and (memq sym bindings) (let ...))
| 5: (memq sym bindings)
| 5: [memq let (debug)]
| 5: =>#f
| 2: (letrec ((yy 23)) (let ((x 1)) (quote this-is-a-matric)))
| 3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
| 3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
| 4: (and (memq sym bindings) (let ...))
| 5: (memq sym bindings)
| 5: [memq let (debug)]
| 5: =>#f
| 3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
| 3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
| 4: (and (memq sym bindings) (let ...))
| 5: (memq sym bindings)
| 5: [memq let (debug)]
| 5: =>#f
| 3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
| 3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
| 4: (and (memq sym bindings) (let ...))
| 5: (memq sym bindings)
| 5: [memq let (debug)]
| 5: =>#f
| 2: (let ((x 1)) (quote this-is-a-matric))
| 3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
| 3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
| 4: (and (memq sym bindings) (let ...))
| 5: (memq sym bindings)
| 5: [memq let (debug)]
| 5: =>#f
| 2: [let (let # #) (# # #)]
| 2: [let (let # #) (# # #)]
| 2: =>(#@@let* (x 1) #@@let (quote this-is-a-matric))
this-is-a-matric
guile> (do-main 4)
| 2: [mkmatrix]
| 2: (letrec ((yy 23)) (let* ((x 1)) (quote this-is-a-matric)))
| 2: (let* ((x 1)) (quote this-is-a-matric))
| 2: (quote this-is-a-matric)
| 2: =>this-is-a-matric
this-is-a-matric
guile>
@end lisp
This example shows the default configuration for how each line of trace
output is formatted, which is:
@itemize
@item
the character @code{|}, a visual clue that the line is a line of trace
output, followed by
@item
a number indicating the real evaluator stack depth (where ``real'' means
not counting tail-calls), followed by
@item
a summary of the expression being evaluated (@code{(@dots{})}), the
procedure being called (@code{[@dots{}]}), or the value being returned
from an evaluation or procedure call (@code{=>@dots{}}).
@end itemize
@noindent
You can customize @code{(ice-9 debugging trace)} to show different
information in each trace line using the @code{set-trace-layout}
procedure. The next example shows how to get the source location in
each trace line instead of the stack depth.
@lisp
guile> (set-trace-layout "|~16@@a: ~a\n" trace/source trace/info)
guile> (do-main 4)
| matrix.scm:7:2: [mkmatrix]
| : (letrec ((yy 23)) (let* ((x 1)) (quote this-is-a-matric)))
| matrix.scm:3:2: (let* ((x 1)) (quote this-is-a-matric))
| matrix.scm:4:4: (quote this-is-a-matric)
| matrix.scm:4:4: =>this-is-a-matric
this-is-a-matric
guile>
@end lisp
(For anyone wondering why the first @code{(do-main 4)} call above
generates lots more trace lines than the subsequent calls: these
examples also demonstrate how the Guile evaluator ``memoizes'' code.
When Guile evaluates a source code expression for the first time, it
changes some parts of the expression so that they will be quicker to
evaluate when that expression is evaluated again; this is called
memoization. The trace output from the first @code{(do-main 4)} call
shows memoization steps, such as an internal define being transformed to
a letrec.)
@c Local Variables:
@c TeX-master: "guile.texi"
@c End:

View file

@ -679,7 +679,7 @@ Guile starts up.
@item (ice-9 debug)
Mikael Djurfeldt's source-level debugging support for Guile
(@pxref{Debugging Features}).
(@pxref{Tracing}).
@item (ice-9 expect)
Actions based on matching input from a port (@pxref{Expect}).

View file

@ -613,7 +613,6 @@ way.
@var{retval} is the return value.
@end deffn
@deffn memoize-symbol-handler key cont expression env
Called when the evaluator memoizes the value of a procedure symbol
@ -626,6 +625,16 @@ way.
@var{retval} is the return value.
@end deffn
@deffn {Scheme Procedure} with-traps thunk
@deffnx {C Function} scm_with_traps (thunk)
Call @var{thunk} with traps enabled.
@end deffn
@deffn {Scheme Procedure} debug-object? obj
@deffnx {C Function} scm_debug_object_p (obj)
Return @code{#t} if @var{obj} is a debug object.
@end deffn
@node Debugger options
@subsubsection Debugger options

View file

@ -138,7 +138,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.48 2006-11-18 18:14:55 civodul Exp $
@c @subtitle $Id: guile.texi,v 1.49 2008-03-19 22:51:23 ossau Exp $
@c See preface.texi for the list of authors
@author The Guile Developers
@ -222,7 +222,6 @@ etc. that make up Guile's application programming interface (API),
* 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
@ -230,7 +229,6 @@ etc. that make up Guile's application programming interface (API),
@include scheme-intro.texi
@include scheme-scripts.texi
@include scheme-using.texi
@include scheme-debugging.texi
@include scheme-reading.texi
@node Programming in C
@ -351,6 +349,7 @@ available through both Scheme and C interfaces.
* Buffered Input:: Ports made from a reader function.
* Expect:: Controlling interactive programs with Guile.
* The Scheme shell (scsh):: Using scsh interfaces in Guile.
* Tracing:: Tracing program execution.
@end menu
@include slib.texi
@ -361,6 +360,7 @@ available through both Scheme and C interfaces.
@include misc-modules.texi
@include expect.texi
@include scsh.texi
@include scheme-debugging.texi
@include data-rep.texi
@include fdl.texi

View file

@ -5,280 +5,8 @@
@c See the file guile.texi for copying conditions.
@page
@node Debugging Features
@section Debugging Features
Guile includes debugging tools to help you work out what is going wrong
when a program signals an error or behaves differently to how you would
expect. This chapter describes how to use these tools.
Broadly speaking, Guile's debugging support allows you to do two things:
@itemize @bullet
@item
specify @dfn{breakpoints} --- points in the execution of a program where
execution should pause so you can see what is going on
@item
examine in detail the ``scene of the crime'' --- in other words, the
execution context at a breakpoint, or when the last error occurred.
@end itemize
@noindent
The details are more complex and more powerful @dots{}
@menu
* Examples::
* Intro to Breakpoints:: Setting and manipulating them.
* Tracing:: Tracing program execution.
@end menu
@node Examples
@subsection Examples
Before we dive into the details and reference documentation of
guile-debugging's features, this chapter sets the scene by presenting a
few examples of what you can do with guile-debugging.
@menu
* Single Stepping through a Procedure's Code::
* Profiling or Tracing a Procedure's Code::
@end menu
@node Single Stepping through a Procedure's Code
@subsubsection Single Stepping through a Procedure's Code
A good way to explore in detail what a Scheme procedure does is to set a
breakpoint on it and then single step through what it does. To do this,
use the @code{break-in} procedure from the @code{(ice-9 debugging
breakpoints)} module with the @code{debug-trap} behaviour from
@code{(ice-9 debugging ice-9-debugger-extensions)}. The following
sample session illustrates this. It assumes that the file
@file{matrix.scm} defines a procedure @code{mkmatrix}, which is the one
we want to explore, and another procedure @code{do-main} which calls
@code{mkmatrix}.
@lisp
$ /usr/bin/guile -q
guile> (use-modules (ice-9 debugger)
(ice-9 debugging ice-9-debugger-extensions)
(ice-9 debugging breakpoints))
guile> (load "matrix.scm")
guile> (break-in 'mkmatrix #:behaviour debug-trap)
#<<break-in> 808cb70>
guile> (do-main 4)
This is the Guile debugger -- for help, type `help'.
There are 3 frames on the stack.
Frame 2 at matrix.scm:8:3
[mkmatrix]
debug> next
Frame 3 at matrix.scm:4:3
(let ((x 1)) (quote this-is-a-matric))
debug> info frame
Stack frame: 3
This frame is an evaluation.
The expression being evaluated is:
matrix.scm:4:3:
(let ((x 1)) (quote this-is-a-matric))
debug> next
Frame 3 at matrix.scm:5:21
(quote this-is-a-matric)
debug> bt
In unknown file:
?: 0* [primitive-eval (do-main 4)]
In standard input:
4: 1* [do-main 4]
In matrix.scm:
8: 2 [mkmatrix]
...
5: 3 (quote this-is-a-matric)
debug> quit
this-is-a-matric
guile>
@end lisp
Or you can use guile-debugging's Emacs interface (GDS), by using the
module @code{(ice-9 gds-client)} instead of @code{(ice-9 debugger)} and
@code{(ice-9 debugging ice-9-debugger-extensions)}, and changing
@code{debug-trap} to @code{gds-debug-trap}. Then the stack and
corresponding source locations are displayed in Emacs instead of on the
Guile command line.
@node Profiling or Tracing a Procedure's Code
@subsubsection Profiling or Tracing a Procedure's Code
What if you wanted to get a trace of everything that the Guile evaluator
does within a given procedure, but without Guile stopping and waiting
for your input at every step? In this case you set a breakpoint on the
procedure using @code{break-in} (the same as in the previous example),
but use the @code{trace-trap} and @code{trace-until-exit} behaviours
provided by the @code{(ice-9 debugging trace)} module.
@lisp
guile> (use-modules (ice-9 debugging breakpoints) (ice-9 debugging trace))
guile> (load "matrix.scm")
guile> (break-in 'mkmatrix #:behaviour (list trace-trap trace-until-exit))
#<<break-in> 808b430>
guile> (do-main 4)
| 2: [mkmatrix]
| 3: [define (define yy 23) ((()) #<eval-closure 4028db30>)]
| 3: [define (define yy 23) ((()) #<eval-closure 4028db30>)]
| 3: =>(#@@define yy 23)
| 3: [let (let # #) (# #)]
| 3: [let (let # #) (# #)]
| 3: =>(#@@let* (x 1) #@@let (quote this-is-a-matric))
| 2: (letrec ((yy 23)) (let ((x 1)) (quote this-is-a-matric)))
| 3: [let (let # #) (# # #)]
| 3: [let (let # #) (# # #)]
| 3: =>(#@@let* (x 1) #@@let (quote this-is-a-matric))
| 2: (let ((x 1)) (quote this-is-a-matric))
| 3: [quote (quote this-is-a-matric) ((x . 1) ((yy) 23) (()) ...)]
| 3: [quote (quote this-is-a-matric) ((x . 1) ((yy) 23) (()) ...)]
| 3: =>(#@@quote this-is-a-matric)
| 2: (quote this-is-a-matric)
| 2: =>this-is-a-matric
this-is-a-matric
guile> (do-main 4)
| 2: [mkmatrix]
| 2: (letrec ((yy 23)) (let ((x 1)) (quote this-is-a-matric)))
| 2: (let ((x 1)) (quote this-is-a-matric))
| 2: (quote this-is-a-matric)
| 2: =>this-is-a-matric
this-is-a-matric
guile>
@end lisp
This example shows the default configuration for how each line of trace
output is formatted, which is:
@itemize
@item
the character @code{|}, a visual clue that the line is a line of trace
output, followed by
@item
a number indicating the real evaluator stack depth (where ``real'' means
not counting tail-calls), followed by
@item
a summary of the expression being evaluated (@code{(@dots{})}), the
procedure being called (@code{[@dots{}]}), or the value being returned
from an evaluation or procedure call (@code{=>@dots{}}).
@end itemize
@noindent
You can customize @code{(ice-9 debugging trace)} to show different
information in each trace line using the @code{set-trace-layout}
procedure. The next example shows how to get the source location in
each trace line instead of the stack depth.
@lisp
guile> (set-trace-layout "|~16@@a: ~a\n" trace/source trace/info)
guile> (do-main 4)
| matrix.scm:7:2: [mkmatrix]
| : (letrec ((yy 23)) (let ((x 1)) (quote this-is-a-matric)))
| matrix.scm:3:2: (let ((x 1)) (quote this-is-a-matric))
| matrix.scm:4:20: (quote this-is-a-matric)
| matrix.scm:4:20: =>this-is-a-matric
this-is-a-matric
guile>
@end lisp
(For anyone wondering why the first @code{(do-main 4)} call above
generates lots more trace lines than the subsequent calls: these
examples also demonstrate how the Guile evaluator ``memoizes'' code.
When Guile evaluates a source code expression for the first time, it
changes some parts of the expression so that they will be quicker to
evaluate when that expression is evaluated again; this is called
memoization. The trace output from the first @code{(do-main 4)} call
shows memoization steps, such as an internal define being transformed to
a letrec.)
@node Intro to Breakpoints
@subsection Intro to Breakpoints
Sometimes a piece of Scheme code isn't working and you'd like to go
through it step by step. You can do this in Guile by setting a
breakpoint at the start of the relevant code, and then using the command
line or Emacs interface to step through it.
A breakpoint can be specified by procedure name or by location -- the
relevant code's file name, line number and column number. For details
please see the full documentation for @code{break-in} and
@code{break-at} in @ref{Intro to Breakpoints}.
When you set a breakpoint, you can specify any ``behaviour'' you like
for what should happen when the breakpoint is hit; a breakpoint
``behaviour'' is just a Scheme procedure with the right signature.
@menu
* Breakpoints Overview::
@end menu
@node Breakpoints Overview
@subsubsection How Breakpoints Work and Why They Are Useful
Often, debugging the last error is not enough to tell you what went
wrong. For example, the root cause of the error may have arisen a long
time before the error was signalled, in which case the execution context
of the error is too late to be useful. Or your program might not signal
an error at all, just return an unexpected result or have some incorrect
side effect.
In many such cases, it's useful to pause the program at or before the
point where you suspect the problem arises. Then you can explore the
stack, display the values of key variables, and generally check that the
state of the program is as you expect. If all is well, you can let the
program continue running normally, or step more slowly through each
expression that the Scheme interpreter evaluates. Single-stepping may
reveal that the program is going through blocks of code that you didn't
intend --- a useful data point for understanding what the underlying
problem is.
Telling Guile where or when to pause a program is called @dfn{setting a
breakpoint}. When a breakpoint is hit, Guile's default behaviour is to
enter the interactive debugger, where there are now two sets of commands
available:
@itemize @bullet
@item
all the commands as described for last error debugging
(@pxref{Interactive Debugger}), which allow you to explore the stack and
so on
@item
additional commands for continuing program execution in various ways:
@code{next}, @code{step}, @code{finish}, @code{trace-finish} and
@code{continue}.
@end itemize
Use of the interactive debugger is described in @ref{Interactive
Debugger}.
@node Tracing
@subsection Tracing
Tracing has already been described as a breakpoint behaviour, but we
mention it again here because it is so useful, and because Guile
actually now has @emph{two} mechanisms for tracing, and its worth
clarifying the differences between them.
@menu
* Old Tracing:: Tracing provided by (ice-9 debug).
* New Tracing:: Breakpoint-based tracing.
* Tracing Compared:: Differences between old and new.
@end menu
@node Old Tracing
@subsubsection Tracing Provided by @code{(ice-9 debug)}
@section Tracing
The @code{(ice-9 debug)} module implements tracing of procedure
applications. When a procedure is @dfn{traced}, it means that every
@ -391,128 +119,6 @@ there is no need for Guile to create a new stack frame for each
iteration. Tracing reveals this optimization in operation.
@node New Tracing
@subsubsection Breakpoint-based Tracing
Guile's newer mechanism implements tracing as an optional behaviour for
any kind of breakpoint.
To trace a procedure (in the same kind of way as the older tracing), use
the @code{trace!} procedure to set a procedure breakpoint with
@code{trace-here} behaviour:
@lisp
(trace! fact1)
@print{}
Set breakpoint 1: [fact1]
@result{}
#<<procedure-breakpoint> 40337bf0>
(fact1 4)
@print{}
| [fact1 4]
| | [fact1 3]
| | | [fact1 2]
| | | | [fact1 1]
| | | | | [fact1 0]
| | | | | 1
| | | | 2
| | | 6
| | 24
| 24
@result{}
24
@end lisp
To trace evaluation of a source expression, evaluate code containing a
breakpoint marker @code{##} in the appropriate place, then use
@code{set-breakpoint} to change the behaviour of the new breakpoint to
@code{trace-here}:
@lisp
(define (fact1 n)
(if ##(= n 0)
1
(* n (fact1 (- n 1)))))
@print{}
Set breakpoint 4: standard input:13:9: (= n 0)
(use-modules (ice-9 debugger behaviour))
(set-breakpoint! trace-here 4)
@print{}
Breakpoint 4: standard input:13:9: (= n 0)
enabled? = #t
behaviour = #<procedure trace-here ()>
(fact1 4)
@print{}
| (= n 0)
| #f
| (= n 0)
| #f
| (= n 0)
| #f
| (= n 0)
| #f
| (= n 0)
| #t
@result{}
24
@end lisp
@noindent
(Note --- this example reveals a bug: each occurrence of @code{(= n 0)}
should be shown indented with respect to the one before it, as
@code{fact1} does not call itself tail-recursively.)
You can also give a breakpoint the @code{trace-subtree} behaviour, which
means to trace the breakpoint location itself plus any evaluations and
applications that occur below it in the call stack. In the following
example, this allows us to see the evaluated arguments that are being
compared by the @code{=} procedure:
@lisp
(set-breakpoint! trace-subtree 4)
@print{}
Breakpoint 4: standard input:13:9: (= n 0)
enabled? = #t
behaviour = #<procedure trace-subtree ()>
(fact1 4)
@print{}
| (= n 0)
| [= 4 0]
| #f
| (= n 0)
| [= 3 0]
| #f
| (= n 0)
| [= 2 0]
| #f
| (= n 0)
| [= 1 0]
| #f
| (= n 0)
| [= 0 0]
| #t
@result{}
24
@end lisp
@node Tracing Compared
@subsubsection Differences Between Old and New Tracing Mechanisms
The newer tracing mechanism is more general and so more powerful than
the older one: it works for expressions as well as procedure
applications, and it implements the useful @code{trace-subtree}
behaviour as well as the more traditional @code{trace-here}.
The older mechanism will probably become obsolete eventually, but it's
worth keeping it around for a while until we are sure that the new
mechanism is correct and does what programmers need.
@c Local Variables:
@c TeX-master: "guile.texi"
@c End:

View file

@ -163,10 +163,10 @@ The interactive debugger 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.
Guile's interactive debugger is a command line application that
accepts commands from you for examining the stack and, if stopped at a
trap, 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:
@ -359,15 +359,15 @@ debugger to continue.)
@node Using Guile in Emacs
@section Using Guile in Emacs
There are quite a few options for working on Guile Scheme code in
Emacs. The simplest options are to use Emacs's standard
@code{scheme-mode} for editing code, and to run the interpreter when you
need it by typing ``guile'' at the prompt of a @code{*shell*} buffer,
but there are Emacs libraries available which add various bells and
whistles to this. The following diagram shows these libraries and how
they relate to each other, with the arrows indicating ``builds on'' or
``extends''. For example, the Quack library builds on cmuscheme, which
in turn builds on the standard scheme mode.
There are several options for working on Guile Scheme code in Emacs.
The simplest are to use Emacs's standard @code{scheme-mode} for
editing code, and to run the interpreter when you need it by typing
``guile'' at the prompt of a @code{*shell*} buffer, but there are
Emacs libraries available which add various bells and whistles to
this. The following diagram shows these libraries and how they relate
to each other, with the arrows indicating ``builds on'' or
``extends''. For example, the Quack library builds on cmuscheme,
which in turn builds on the standard scheme mode.
@example
scheme
@ -408,25 +408,24 @@ interpreters and remembers which one you used last time; and so on.
Quack is available from @uref{http://www.neilvandyke.org/quack}.
@dfn{GDS}, written by Neil Jerram, also builds on the scheme/cmuscheme
combination, but with a fundamental change to the way that Scheme code
fragments are sent to the interpreter for evaluation. cmuscheme and
Quack send code fragments to the interpreter's standard input, on the
assumption that the interpreter is expecting to read Scheme expressions
there, and then monitor the interpreter's standard output to infer what
the result of the evaluation is. GDS doesn't use standard input and
combination, but with a change to the way that Scheme code fragments
are sent to the interpreter for evaluation. cmuscheme and Quack send
code fragments to the interpreter's standard input, on the assumption
that the interpreter is expecting to read Scheme expressions there,
and then monitor the interpreter's standard output to infer what the
result of the evaluation is. GDS doesn't use standard input and
output like this. Instead, it sets up a socket connection between the
Scheme interpreter and Emacs, and sends and receives messages using a
simple protocol through this socket. The messages include requests to
evaluate Scheme code, and responses conveying the results of an
evaluation, thus providing similar function to cmuscheme or Quack. They
also include requests for setting breakpoints, stack exploration and
debugging, which go beyond what cmuscheme or Quack can do. The price of
this extra power, however, is that GDS is Guile-specific. GDS requires
the Scheme interpreter, or any program that GDS is debugging, to run
some GDS-specific library code; currently this code is written as a
Guile module and uses a lot of debugging-related features that are
evaluation, thus providing similar function to cmuscheme or Quack.
They also include requests for stack exploration and debugging, which
go beyond what cmuscheme or Quack can do. The price of this extra
power, however, is that GDS is Guile-specific. GDS requires the
Scheme interpreter to run some GDS-specific library code; currently
this code is written as a Guile module and uses features that are
specific to Guile. GDS is now included in the Guile distribution; for
previous Guile releases (1.8.x and earlier) it can be obtained as part
previous Guile releases (1.8.4 and earlier) it can be obtained as part
of the @code{guile-debugging} package from
@uref{http://www.ossau.uklinux.net/guile}.
@ -540,7 +539,7 @@ Emacs. This code, consisting of the installed files @file{gds.el} and
@file{gds-server.el}, is responsible for displaying information from
Guile in Emacs windows, and for responding to Emacs commands and
keystrokes by sending instructions back to the Guile program being
debugged.
worked on.
@item
The GDS @dfn{server} code is written in Scheme and runs as an Emacs
@ -584,12 +583,12 @@ The data exchanged between client and server components, and between
server and interface, is a sequence of sexps (parenthesised expressions)
that are designed so as to be directly readable by both Scheme and Emacs
Lisp. The use of a TCP connection means that the server and Emacs
interface can theoretically be on a different computer from the programs
being debugged, but in practice there are currently two problems with
interface can theoretically be on a different computer from the client
programs, but in practice there are currently two problems with
this. Firstly the GDS API doesn't provide any way of specifying a
non-local server to connect to, and secondly there is no security or
authentication mechanism in the GDS protocol. These are issues that
should be addressed in the near future.
should be addressed in the future.
@node GDS Getting Started
@ -620,7 +619,7 @@ and the @code{gds-debug} buffer will contain a Scheme backtrace ending
with the message:
@lisp
no code for module (ossau gds-server)
no code for module (ice-9 gds-server)
@end lisp
@noindent
@ -645,10 +644,10 @@ Emacs to open the file @file{gds-tutorial.txt} (which should have been
installed as part of Guile, perhaps under @file{/usr/share/doc/guile}),
and then follow the steps in that file.
When you want to use GDS to explore or debug an independent Guile
When you want to use GDS to work on an independent Guile
application, you need to add something to that application's Scheme code
to cause it to connect to and interact with GDS at the right times. The
following subsections describe the various ways of doing this.
following subsections describe the ways of doing this.
@subsubsection Setting Specific Breakpoints
@ -667,10 +666,10 @@ the following.
@end lisp
@noindent
The @code{#:behaviour gds-debug-trap} clauses mean to use GDS to display
the stack when one of these breakpoints is hit. For more on
breakpoints, @code{break-in} and @code{break-at}, see @ref{Intro to
Breakpoints}.
The @code{#:behaviour gds-debug-trap} clauses mean to use GDS to
display the stack when one of these breakpoints is hit. For more on
breakpoints, @code{break-in} and @code{break-at}, see
@ref{Breakpoints}.
@subsubsection Setting GDS-managed Breakpoints
@ -723,7 +722,7 @@ is pre-1.8) around the code of interest like this:
(gds-debug-trap (throw->trap-context key args))))
@end lisp
In all cases you will need to use the @code{(ice-9 gds-client)} and
Either way, you will need to use the @code{(ice-9 gds-client)} and
@code{(ice-9 debugging traps)} modules.
Two special cases of this are the lazy-catch that the Guile REPL code
@ -738,7 +737,6 @@ procedure as follows.
@lisp
(use-modules (ice-9 gds-client)
(ice-9 debugging traps))
(on-lazy-handler-dispatch gds-debug-trap)
@end lisp
@ -787,16 +785,12 @@ This approach is not yet implemented, though.
@subsubsection Utility Guile Implementation
We conclude this subsection with an aside, by noting that the
``utility'' Guile client described above is nothing more than a
combination of the previous options.
To be precise, the code for the utility Guile client is essentially just
this:
The ``utility'' Guile client mentioned above is a simple combination
of the mechanisms that we have just described. In fact the code for
the utility Guile client is essentially just this:
@lisp
(use-modules (ice-9 gds-client))
(set-gds-breakpoints)
(named-module-use! '(guile-user) '(ice-9 session))
(gds-accept-input #f))
@ -805,17 +799,22 @@ this:
@code{set-gds-breakpoints} works as already described. The
@code{named-module-use!} line ensures that the client can process
@code{help} and @code{apropos} expressions, to implement lookups in
Guile's online help. The @code{#f} parameter to @code{gds-accept-input}
means that the @code{continue} instruction will not cause the
instruction loop to exit, which makes sense here because the utility
client has nothing to do except to process GDS instructions.
Guile's online help. The @code{#f} parameter to
@code{gds-accept-input} means that the @code{continue} instruction
will not cause the instruction loop to exit, which makes sense here
because the utility client has nothing to do except to process GDS
instructions.
(The utility client does not use @code{on-lazy-handler-dispatch},
because it has its own mechanism for catching and reporting exceptions
in the code that it is asked to evaluate. This mechanism summarizes the
exception and gives the user a button they can click to see the full
stack, so the end result is very similar to what
@code{on-lazy-handler-dispatch} provides.)
The utility client does not use @code{on-lazy-handler-dispatch} at its
top level, because it has its own mechanism for catching and reporting
exceptions in the code that it is asked to evaluate. This mechanism
summarizes the exception and gives the user a button they can click to
see the full stack, so the end result is very similar to what
@code{on-lazy-handler-dispatch} provides. Deep inside
@code{gds-accept-input}, in the part that handles evaluating
expressions from Emacs, the GDS client code uses
@code{throw->trap-context} and @code{gds-debug-trap} to implement
this.
@node Working with GDS in Scheme Buffers
@ -850,7 +849,7 @@ or before the cursor but can also be entered or edited in the
minibuffer. The available help is popped up in a temporary Emacs
window.
@item C-h C-g
@item C-h G
@findex gds-apropos
List all accessible Guile symbols matching a given regular expression,
with the same results as if you had typed @code{(apropos REGEXP)} into
@ -1211,35 +1210,9 @@ display in action. To do this add
@noindent
to your @file{testgds.scm} buffer and type @kbd{C-x C-e} (which
evaluates the expression that the cursor is just after the end of). The
result is:
@lisp
(fact1 4)
;;; Evaluating in current module (guile-user)
@result{} 24
--:** *Guile Evaluation* (Scheme:ready)--All------------
@end lisp
@noindent
which is correct, but indicates that we forgot the step needed to enable
the trap mechanism. To do this, type @kbd{C-c C-e} and then enter
@lisp
(trap-enable 'traps)
@end lisp
@noindent
into the minibuffer. (You could equally have typed this into your test
file and evaluated it from there; we use @kbd{C-c C-e} here to
demonstrate the minibuffer option and because you typically wouldn't
want to leave this kind of global setting in the source code that you
are working on.)
If you now type @kbd{C-x C-e} to evaluate @code{(fact1 4)} again, a GDS
stack window like the following appears:
evaluates the expression that the cursor is just after the end of).
The result should be that a GDS stack window like the following
appears:
@lisp
Calling procedure:
@ -1250,19 +1223,10 @@ Calling procedure:
--:** PID 28729 (Guile-Debug)--All------------
@end lisp
GDS's most compelling feature is its single-stepping. To get an
immediate feel for what this is like, make sure your Emacs is prepared
as described in @ref{GDS Getting Started}, then type the following code
into an interactive Guile session.
@lisp
(fact1 4)
@end lisp
@noindent
This will cause the GDS Guile-Debug window to pop up in Emacs, where
you can then press @kbd{i} once and @kbd{@key{SPC}} repeatedly to
single-step through the code from the point of the initial trap.
This stack tells you that Guile is about to call the @code{fact1}
procedure, with argument 4, and you can step through this call in
detail by pressing @kbd{i} once and then @kbd{@key{SPC}}
(@pxref{Continuing Execution}).
(@kbd{i} is needed as the first keystroke rather than @kbd{@key{SPC}},
because the aim here is to step through code in the @code{(ice-9