Fix cross-references in api-macros.texi
[bpt/guile.git] / doc / ref / api-debug.texi
dissimilarity index 82%
index 7886366..32f32ca 100644 (file)
-@c -*-texinfo-*-
-@c This is part of the GNU Guile Reference Manual.
-@c Copyright (C)  1996, 1997, 2000, 2001, 2002, 2003, 2004, 2007
-@c   Free Software Foundation, Inc.
-@c See the file guile.texi for copying conditions.
-
-@page
-@node Debugging
-@section Debugging Infrastructure
-
-@cindex Debugging
-In order to understand Guile's debugging facilities, you first need to
-understand a little about how the evaluator works and what the Scheme
-stack is.  With that in place we explain the low level trap calls that
-the evaluator can be configured to make, and the trap and breakpoint
-infrastructure that builds on top of those calls.
-
-@menu
-* Evaluation Model::            Evaluation and the Scheme stack.
-* Debug on Error::              Debugging when an error occurs.
-* Traps::
-* Debugging Examples::
-@end menu
-
-@node Evaluation Model
-@subsection Evaluation and the Scheme Stack
-
-The idea of the Scheme stack is central to a lot of debugging.  It
-always exists implicitly, as a result of the way that the Guile
-evaluator works, and can be summoned into concrete existence as a
-first-class Scheme value by the @code{make-stack} call, so that an
-introspective Scheme program -- such as a debugger -- can present it in
-some way and allow the user to query its details.  The first thing to
-understand, therefore, is how the workings of the evaluator build up the
-stack.
-
-@cindex Evaluations
-@cindex Applications
-Broadly speaking, the evaluator performs @dfn{evaluations} and
-@dfn{applications}.  An evaluation means that it is looking at a source
-code expression like @code{(+ x 5)} or @code{(if msg (loop))}, deciding
-whether the top level of the expression is a procedure call, macro,
-builtin syntax, or whatever, and doing some appropriate processing in
-each case.  (In the examples here, @code{(+ x 5)} would normally be a
-procedure call, and @code{(if msg (loop))} builtin syntax.)  For a
-procedure call, ``appropriate processing'' includes evaluating the
-procedure's arguments, as that must happen before the procedure itself
-can be called.  An application means calling a procedure once its
-arguments have been calculated.
-
-@cindex Stack
-@cindex Frames
-@cindex Stack frames
-Typically evaluations and applications alternate with each other, and
-together they form a @dfn{stack} of operations pending completion.  This
-is because, on the one hand, evaluation of an expression like @code{(+ x
-5)} requires --- once its arguments have been calculated --- an
-application (in this case, of the procedure @code{+}) before it can
-complete and return a result, and, on the other hand, the application of
-a procedure written in Scheme involves evaluating the sequence of
-expressions that constitute that procedure's code.  Each level on this
-stack is called a @dfn{frame}.
-
-Therefore, when an error occurs in a running program, or the program
-hits a breakpoint, or in fact at any point that the programmer chooses,
-its state at that point can be represented by a @dfn{stack} of all the
-evaluations and procedure applications that are logically in progress at
-that time, each of which is known as a @dfn{frame}.  The programmer can
-learn more about the program's state at that point by inspecting the
-stack and its frames.
-
-@menu
-* Capturing the Stack or Innermost Stack Frame::
-* Examining the Stack::
-* Examining Stack Frames::
-* Source Properties::           Remembering the source of an expression.
-* Decoding Memoized Source Expressions::
-* Starting a New Stack::
-@end menu
-
-@node Capturing the Stack or Innermost Stack Frame
-@subsubsection Capturing the Stack or Innermost Stack Frame
-
-A Scheme program can use the @code{make-stack} primitive anywhere in its
-code, with first arg @code{#t}, to construct a Scheme value that
-describes the Scheme stack at that point.
-
-@lisp
-(make-stack #t)
-@result{}
-#<stack 805c840:808d250>
-@end lisp
-
-@deffn {Scheme Procedure} make-stack obj . args
-@deffnx {C Function} scm_make_stack (obj, args)
-Create a new stack. If @var{obj} is @code{#t}, the current
-evaluation stack is used for creating the stack frames,
-otherwise the frames are taken from @var{obj} (which must be
-either a debug object or a continuation).
-
-@var{args} should be a list containing any combination of
-integer, procedure and @code{#t} values.
-
-These values specify various ways of cutting away uninteresting
-stack frames from the top and bottom of the stack that
-@code{make-stack} returns.  They come in pairs like this:
-@code{(@var{inner_cut_1} @var{outer_cut_1} @var{inner_cut_2}
-@var{outer_cut_2} @dots{})}.
-
-Each @var{inner_cut_N} can be @code{#t}, an integer, or a
-procedure.  @code{#t} means to cut away all frames up to but
-excluding the first user module frame.  An integer means to cut
-away exactly that number of frames.  A procedure means to cut
-away all frames up to but excluding the application frame whose
-procedure matches the specified one.
-
-Each @var{outer_cut_N} can be an integer or a procedure.  An
-integer means to cut away that number of frames.  A procedure
-means to cut away frames down to but excluding the application
-frame whose procedure matches the specified one.
-
-If the @var{outer_cut_N} of the last pair is missing, it is
-taken as 0.
-@end deffn
-
-@deffn {Scheme Procedure} last-stack-frame obj
-@deffnx {C Function} scm_last_stack_frame (obj)
-Return the last (innermost) frame of @var{obj}, which must be
-either a debug object or a continuation.
-@end deffn
-
-
-@node Examining the Stack
-@subsubsection Examining the Stack
-
-@deffn {Scheme Procedure} stack? obj
-@deffnx {C Function} scm_stack_p (obj)
-Return @code{#t} if @var{obj} is a calling stack.
-@end deffn
-
-@deffn {Scheme Procedure} stack-id stack
-@deffnx {C Function} scm_stack_id (stack)
-Return the identifier given to @var{stack} by @code{start-stack}.
-@end deffn
-
-@deffn {Scheme Procedure} stack-length stack
-@deffnx {C Function} scm_stack_length (stack)
-Return the length of @var{stack}.
-@end deffn
-
-@deffn {Scheme Procedure} stack-ref stack index
-@deffnx {C Function} scm_stack_ref (stack, index)
-Return the @var{index}'th frame from @var{stack}.
-@end deffn
-
-@deffn {Scheme Procedure} display-backtrace stack port [first [depth [highlights]]]
-@deffnx {C Function} scm_display_backtrace_with_highlights (stack, port, first, depth, highlights)
-@deffnx {C Function} scm_display_backtrace (stack, port, first, depth)
-Display a backtrace to the output port @var{port}.  @var{stack}
-is the stack to take the backtrace from, @var{first} specifies
-where in the stack to start and @var{depth} how many frames
-to display.  @var{first} and @var{depth} can be @code{#f},
-which means that default values will be used.
-If @var{highlights} is given it should be a list; the elements
-of this list will be highlighted wherever they appear in the
-backtrace.
-@end deffn
-
-
-@node Examining Stack Frames
-@subsubsection Examining Stack Frames
-
-@deffn {Scheme Procedure} frame? obj
-@deffnx {C Function} scm_frame_p (obj)
-Return @code{#t} if @var{obj} is a stack frame.
-@end deffn
-
-@deffn {Scheme Procedure} frame-number frame
-@deffnx {C Function} scm_frame_number (frame)
-Return the frame number of @var{frame}.
-@end deffn
-
-@deffn {Scheme Procedure} frame-previous frame
-@deffnx {C Function} scm_frame_previous (frame)
-Return the previous frame of @var{frame}, or @code{#f} if
-@var{frame} is the first frame in its stack.
-@end deffn
-
-@deffn {Scheme Procedure} frame-next frame
-@deffnx {C Function} scm_frame_next (frame)
-Return the next frame of @var{frame}, or @code{#f} if
-@var{frame} is the last frame in its stack.
-@end deffn
-
-@deffn {Scheme Procedure} frame-source frame
-@deffnx {C Function} scm_frame_source (frame)
-Return the source of @var{frame}.
-@end deffn
-
-@deffn {Scheme Procedure} frame-procedure? frame
-@deffnx {C Function} scm_frame_procedure_p (frame)
-Return @code{#t} if a procedure is associated with @var{frame}.
-@end deffn
-
-@deffn {Scheme Procedure} frame-procedure frame
-@deffnx {C Function} scm_frame_procedure (frame)
-Return the procedure for @var{frame}, or @code{#f} if no
-procedure is associated with @var{frame}.
-@end deffn
-
-@deffn {Scheme Procedure} frame-arguments frame
-@deffnx {C Function} scm_frame_arguments (frame)
-Return the arguments of @var{frame}.
-@end deffn
-
-@deffn {Scheme Procedure} frame-evaluating-args? frame
-@deffnx {C Function} scm_frame_evaluating_args_p (frame)
-Return @code{#t} if @var{frame} contains evaluated arguments.
-@end deffn
-
-@deffn {Scheme Procedure} frame-overflow? frame
-@deffnx {C Function} scm_frame_overflow_p (frame)
-Return @code{#t} if @var{frame} is an overflow frame.
-@end deffn
-
-@deffn {Scheme Procedure} frame-real? frame
-@deffnx {C Function} scm_frame_real_p (frame)
-Return @code{#t} if @var{frame} is a real frame.
-@end deffn
-
-@deffn {Scheme Procedure} display-application frame [port [indent]]
-@deffnx {C Function} scm_display_application (frame, port, indent)
-Display a procedure application @var{frame} to the output port
-@var{port}. @var{indent} specifies the indentation of the
-output.
-@end deffn
-
-
-@node Source Properties
-@subsubsection Source Properties
-
-@cindex source properties
-As Guile reads in Scheme code from file or from standard input, it
-remembers the file name, line number and column number where each
-expression begins.  These pieces of information are known as the
-@dfn{source properties} of the expression.  If an expression undergoes
-transformation --- for example, if there is a syntax transformer in
-effect, or the expression is a macro call --- the source properties are
-copied from the untransformed to the transformed expression so that, if
-an error occurs when evaluating the transformed expression, Guile's
-debugger can point back to the file and location where the expression
-originated.
-
-The way that source properties are stored means that Guile can only
-associate source properties with parenthesized expressions, and not, for
-example, with individual symbols, numbers or strings.  The difference
-can be seen by typing @code{(xxx)} and @code{xxx} at the Guile prompt
-(where the variable @code{xxx} has not been defined):
-
-@example
-guile> (xxx)
-standard input:2:1: In expression (xxx):
-standard input:2:1: Unbound variable: xxx
-ABORT: (unbound-variable)
-guile> xxx
-<unnamed port>: In expression xxx:
-<unnamed port>: Unbound variable: xxx
-ABORT: (unbound-variable)
-@end example
-
-@noindent
-In the latter case, no source properties were stored, so the best that
-Guile could say regarding the location of the problem was ``<unnamed
-port>''.
-
-The recording of source properties is controlled by the read option
-named ``positions'' (@pxref{Reader options}).  This option is switched
-@emph{on} by default, together with the debug options ``debug'' and
-``backtrace'' (@pxref{Debugger options}), when Guile is run
-interactively; all these options are @emph{off} by default when Guile
-runs a script non-interactively.
-
-The following procedures can be used to access and set the source
-properties of read expressions.
-
-@deffn {Scheme Procedure} set-source-properties! obj plist
-@deffnx {C Function} scm_set_source_properties_x (obj, plist)
-Install the association list @var{plist} as the source property
-list for @var{obj}.
-@end deffn
-
-@deffn {Scheme Procedure} set-source-property! obj key datum
-@deffnx {C Function} scm_set_source_property_x (obj, key, datum)
-Set the source property of object @var{obj}, which is specified by
-@var{key} to @var{datum}.  Normally, the key will be a symbol.
-@end deffn
-
-@deffn {Scheme Procedure} source-properties obj
-@deffnx {C Function} scm_source_properties (obj)
-Return the source property association list of @var{obj}.
-@end deffn
-
-@deffn {Scheme Procedure} source-property obj key
-@deffnx {C Function} scm_source_property (obj, key)
-Return the source property specified by @var{key} from
-@var{obj}'s source property list.
-@end deffn
-
-In practice there are only two ways that you should use the ability to
-set an expression's source breakpoints.
-
-@itemize
-@item
-To set a breakpoint on an expression, use @code{(set-source-property!
-@var{expr} 'breakpoint #t)}.  If you do this, you should also set the
-@code{traps} and @code{enter-frame-handler} trap options
-(@pxref{Evaluator trap options}) and @code{breakpoints} debug option
-(@pxref{Debugger options}) appropriately, and the evaluator will then
-call your enter frame handler whenever it is about to evaluate that
-expression.
-
-@item
-To make a read or constructed expression appear to have come from a
-different source than what the expression's source properties already
-say, you can use @code{set-source-property!} to set the expression's
-@code{filename}, @code{line} and @code{column} properties.  The
-properties that you set will then show up later if that expression is
-involved in a backtrace or error report.
-@end itemize
-
-If you are looking for a way to attach arbitrary information to an
-expression other than these properties, you should use
-@code{make-object-property} instead (@pxref{Object Properties}), because
-that will avoid bloating the source property hash table, which is really
-only intended for the specific purposes described in this section.
-
-
-@node Decoding Memoized Source Expressions
-@subsubsection Decoding Memoized Source Expressions
-
-@deffn {Scheme Procedure} memoized? obj
-@deffnx {C Function} scm_memoized_p (obj)
-Return @code{#t} if @var{obj} is memoized.
-@end deffn
-
-@deffn {Scheme Procedure} unmemoize m
-@deffnx {C Function} scm_unmemoize (m)
-Unmemoize the memoized expression @var{m},
-@end deffn
-
-@deffn {Scheme Procedure} memoized-environment m
-@deffnx {C Function} scm_memoized_environment (m)
-Return the environment of the memoized expression @var{m}.
-@end deffn
-
-
-@node Starting a New Stack
-@subsubsection Starting a New Stack
-
-@deffn {Scheme Syntax} start-stack id exp
-Evaluate @var{exp} on a new calling stack with identity @var{id}.  If
-@var{exp} is interrupted during evaluation, backtraces will not display
-frames farther back than @var{exp}'s top-level form.  This macro is a
-way of artificially limiting backtraces and stack procedures, largely as
-a convenience to the user.
-@end deffn
-
-
-@node Debug on Error
-@subsection Debugging when an error occurs
-
-A common requirement is to be able to show as much useful context as
-possible when a Scheme program hits an error.  The most immediate
-information about an error is the kind of error that it is -- such as
-``division by zero'' -- and any parameters that the code which signalled
-the error chose explicitly to provide.  This information originates with
-the @code{error} or @code{throw} call (or their C code equivalents, if
-the error is detected by C code) that signals the error, and is passed
-automatically to the handler procedure of the innermost applicable
-@code{catch}, @code{lazy-catch} or @code{with-throw-handler} expression.
-
-@subsubsection Intercepting basic error information
-
-Therefore, to catch errors that occur within a chunk of Scheme code, and
-to intercept basic information about those errors, you need to execute
-that code inside the dynamic context of a @code{catch},
-@code{lazy-catch} or @code{with-throw-handler} expression, or the
-equivalent in C.  In Scheme, this means you need something like this:
-
-@lisp
-(catch #t
-       (lambda ()
-         ;; Execute the code in which
-         ;; you want to catch errors here.
-         ...)
-       (lambda (key . parameters)
-         ;; Put the code which you want
-         ;; to handle an error here.
-         ...))
-@end lisp
-
-@noindent
-The @code{catch} here can also be @code{lazy-catch} or
-@code{with-throw-handler}; see @ref{Throw Handlers} and @ref{Lazy Catch}
-for the details of how these differ from @code{catch}.  The @code{#t}
-means that the catch is applicable to all kinds of error; if you want to
-restrict your catch to just one kind of error, you can put the symbol
-for that kind of error instead of @code{#t}.  The equivalent to this in
-C would be something like this:
-
-@lisp
-SCM my_body_proc (void *body_data)
-@{
-  /* Execute the code in which
-     you want to catch errors here. */
-  ...
-@}
-
-SCM my_handler_proc (void *handler_data,
-                     SCM key,
-                     SCM parameters)
-@{
-  /* Put the code which you want
-     to handle an error here. */
-  ...
-@}
-
-@{
-  ...
-  scm_c_catch (SCM_BOOL_T,
-               my_body_proc, body_data,
-               my_handler_proc, handler_data,
-               NULL, NULL);
-  ...
-@}
-@end lisp
-
-@noindent
-Again, as with the Scheme version, @code{scm_c_catch} could be replaced
-by @code{scm_internal_lazy_catch} or @code{scm_c_with_throw_handler},
-and @code{SCM_BOOL_T} could instead be the symbol for a particular kind
-of error.
-
-@subsubsection Capturing the full error stack
-
-The other interesting information about an error is the full Scheme
-stack at the point where the error occurred; in other words what
-innermost expression was being evaluated, what was the expression that
-called that one, and so on.  If you want to write your code so that it
-captures and can display this information as well, there are three
-important things to understand.
-
-Firstly, the code in question must be executed using the debugging
-version of the evaluator, because information about the Scheme stack is
-only available at all from the debugging evaluator.  Using the debugging
-evaluator means that the debugger option (@pxref{Debugger options})
-called @code{debug} must be enabled; this can be done by running
-@code{(debug-enable 'debug)} or @code{(turn-on-debugging)} at the top
-level of your program; or by running guile with the @code{--debug}
-command line option, if your program begins life as a Scheme script.
-
-Secondly, the stack at the point of the error needs to be explicitly
-captured by a @code{make-stack} call (or the C equivalent
-@code{scm_make_stack}).  The Guile library does not do this
-``automatically'' for you, so you will need to write code with a
-@code{make-stack} or @code{scm_make_stack} call yourself.  (We emphasise
-this point because some people are misled by the fact that the Guile
-interactive REPL code @emph{does} capture and display the stack
-automatically.  But the Guile interactive REPL is itself a Scheme
-program@footnote{In effect, it is the default program which is run when
-no commands or script file are specified on the Guile command line.}
-running on top of the Guile library, and which uses @code{catch} and
-@code{make-stack} in the way we are about to describe to capture the
-stack when an error occurs.)
-
-Thirdly, in order to capture the stack effectively at the point where
-the error occurred, the @code{make-stack} call must be made before Guile
-unwinds the stack back to the location of the prevailing catch
-expression.  This means that the @code{make-stack} call must be made
-within the handler of a @code{lazy-catch} or @code{with-throw-handler}
-expression, or the optional "pre-unwind" handler of a @code{catch}.
-(For the full story of how these alternatives differ from each other,
-see @ref{Exceptions}.  The main difference is that @code{catch}
-terminates the error, whereas @code{lazy-catch} and
-@code{with-throw-handler} only intercept it temporarily and then allow
-it to continue propagating up to the next innermost handler.)
-
-So, here are some examples of how to do all this in Scheme and in C.
-For the purpose of these examples we assume that the captured stack
-should be stored in a variable, so that it can be displayed or
-arbitrarily processed later on.  In Scheme:
-
-@lisp
-(let ((captured-stack #f))
-  (catch #t
-         (lambda ()
-           ;; Execute the code in which
-           ;; you want to catch errors here.
-           ...)
-         (lambda (key . parameters)
-           ;; Put the code which you want
-           ;; to handle an error after the
-           ;; stack has been unwound here.
-           ...)
-         (lambda (key . parameters)
-           ;; Capture the stack here:
-           (set! captured-stack (make-stack #t))))
-  ...
-  (if captured-stack
-      (begin
-        ;; Display or process the captured stack.
-        ...))
-  ...)
-@end lisp
-
-@noindent
-And in C:
-
-@lisp
-SCM my_body_proc (void *body_data)
-@{
-  /* Execute the code in which
-     you want to catch errors here. */
-  ...
-@}
-
-SCM my_handler_proc (void *handler_data,
-                     SCM key,
-                     SCM parameters)
-@{
-  /* Put the code which you want
-     to handle an error after the
-     stack has been unwound here. */
-  ...
-@}
-
-SCM my_preunwind_proc (void *handler_data,
-                       SCM key,
-                       SCM parameters)
-@{
-  /* Capture the stack here: */
-  *(SCM *)handler_data = scm_make_stack (SCM_BOOL_T, SCM_EOL);
-@}
-
-@{
-  SCM captured_stack = SCM_BOOL_F;
-  ...
-  scm_c_catch (SCM_BOOL_T,
-               my_body_proc, body_data,
-               my_handler_proc, handler_data,
-               my_preunwind_proc, &captured_stack);
-  ...
-  if (captured_stack != SCM_BOOL_F)
-  @{
-    /* Display or process the captured stack. */
-    ...
-  @}
-  ...
-@}
-@end lisp
-
-@noindent
-Note that you don't have to wait until after the @code{catch} or
-@code{scm_c_catch} has returned.  You can also do whatever you like with
-the stack immediately after it has been captured in the pre-unwind
-handler, or in the normal (post-unwind) handler.  (Except that for the
-latter case in C you will need to change @code{handler_data} in the
-@code{scm_c_catch(@dots{})} call to @code{&captured_stack}, so that
-@code{my_handler_proc} has access to the captured stack.)
-
-@subsubsection Displaying or interrogating the captured stack
-
-Once you have a captured stack, you can interrogate and display its
-details in any way that you want, using the @code{stack-@dots{}} and
-@code{frame-@dots{}} API described in @ref{Examining the Stack} and
-@ref{Examining Stack Frames}.
-
-If you want to print out a backtrace in the same format that the Guile
-REPL does, you can use the @code{display-backtrace} procedure to do so.
-You can also use @code{display-application} to display an individual
-application frame -- that is, a frame that satisfies the
-@code{frame-procedure?} predicate -- in the Guile REPL format.
-
-@subsubsection What the Guile REPL does
-
-The Guile REPL code (in @file{ice-9/boot-9.scm}) uses a @code{catch}
-with a pre-unwind handler to capture the stack when an error occurs in
-an expression that was typed into the REPL, and saves the captured stack
-in a fluid (@pxref{Fluids and Dynamic States}) called
-@code{the-last-stack}.  You can then use the @code{(backtrace)} command,
-which is basically equivalent to @code{(display-backtrace (fluid-ref
-the-last-stack))}, to print out this stack at any time until it is
-overwritten by the next error that occurs.
-
-@deffn {Scheme Procedure} backtrace [highlights]
-@deffnx {C Function} scm_backtrace_with_highlights (highlights)
-@deffnx {C Function} scm_backtrace ()
-Display a backtrace of the stack saved by the last error
-to the current output port.  If @var{highlights} is given
-it should be a list; the elements of this list will be
-highlighted wherever they appear in the backtrace.
-@end deffn
-
-You can also use the @code{(debug)} command to explore the saved stack
-using an interactive command-line-driven debugger.  See @ref{Interactive
-Debugger} for more information about this.
-
-@deffn {Scheme Procedure} debug
-Invoke the Guile debugger to explore the context of the last error.
-@end deffn
-
-
-@node Traps
-@subsection Traps
-
-@cindex Traps
-@cindex Evaluator trap calls
-@cindex Breakpoints
-@cindex Trace
-@cindex Tracing
-@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 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, 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 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.
-
-
-@subsubsection A Quick Note on Terminology
-
-@cindex Trap terminology
-It feels natural to use the word ``trap'' in some form for all levels
-of the structure just described, so we need to be clear on the
-terminology we use to describe each particular level.  The terminology
-used in this subsection is as follows.
-
-@itemize @bullet
-@item
-@cindex Evaluator trap calls
-@cindex Low level trap calls
-``Low level trap calls'', or ``low level traps'', are the calls made
-directly from the C code of the Guile evaluator.
-
-@item
-@cindex Trap classes
-``Trap classes'' are self-explanatory.
-
-@item
-@cindex Trap objects
-``Trap objects'', ``trap instances'', or just ``traps'', are instances
-of a trap class, and each describe a single logical trap condition
-plus behaviour as specified by the user of this interface.
-@end itemize
-
-A good example of when it is important to be clear, is when we talk
-below of behaviours that should only happen once per low level trap.
-A single low level trap call will typically map onto the processing of
-several trap objects, so ``once per low level trap'' is significantly
-different from ``once per trap''.
-
-
-@menu
-* How to Set a Trap::
-* Specifying Trap Behaviour::
-* Trap Context::
-* Tracing Examples::
-* Tracing Configuration::
-* Tracing and (ice-9 debug)::
-* Traps Installing More Traps::
-* Common Trap Options::
-* Procedure Traps::
-* Exit Traps::
-* Entry Traps::
-* Apply Traps::
-* Step Traps::
-* Source Traps::
-* Location Traps::
-* Trap Shorthands::
-* Trap Utilities::
-@end menu
-
-
-@node How to Set a Trap
-@subsubsection How to Set a Trap
-
-@cindex Setting traps
-@cindex Installing and uninstalling traps
-Setting a trap is done in two parts.  First the trap is defined by
-creating an instance of the appropriate trap class, with slot values
-specifying the condition under which the trap will fire and the action
-to take when it fires.  Secondly the trap object thus created must be
-@dfn{installed}.
-
-To make this immediately concrete, here is an example that sets a trap
-to fire on the next application of the @code{facti} procedure, and to
-handle the trap by entering the command line debugger.
-
-@lisp
-(install-trap (make <procedure-trap>
-                #:procedure facti
-                #:single-shot #t
-                #:behaviour debug-trap))
-@end lisp
-
-@noindent
-Briefly, the elements of this incantation are as follows.  (All of
-these are described more fully in the following subsubsections.)
-
-@itemize @bullet
-@item
-@code{<procedure-trap>} is the trap class for trapping on invocation
-of a specific procedure.
-
-@item
-@code{#:procedure facti} says that the specific procedure to trap on for this
-trap object is @code{facti}.
-
-@item
-@code{#:single-shot #t} says that this trap should only fire on the
-@emph{next} invocation of @code{facti}, not on all future invocations
-(which is the default if the @code{#:single-shot} option is not
-specified).
-
-@item
-@code{#:behaviour debug-trap} says that the trap infrastructure should
-call the procedure @code{debug-trap} when this trap fires.
-
-@item
-Finally, the @code{install-trap} call installs the trap immediately.
-@end itemize
-
-@noindent
-It is of course possible for the user to define more convenient
-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 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
-executed when the conditions for the trap firing are met.
-@end deffn
-
-@deffn {Generic Function} uninstall-trap trap
-Uninstall the trap object @var{trap}, so that its behaviour will
-@emph{not} be executed even if the conditions for the trap firing are
-met.
-@end deffn
-
-
-@node Specifying Trap Behaviour
-@subsubsection Specifying Trap Behaviour
-
-@cindex Trap behaviour
-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
-@var{trap-context}, and to single-step or continue program execution
-from that point.
-@end deffn
-
-@deffn {Procedure} gds-debug-trap trap-context
-Use the GDS debugging interface, which displays the stack and
-corresponding source code via Emacs, to explore the stack at
-@var{trap-context} and to single-step or continue program execution
-from that point.
-@end deffn
-
-@cindex Trace
-@cindex Tracing
-@deffn {Procedure} trace-trap trap-context
-Display trace information to summarize the current @var{trap-context}.
-@end deffn
-
-@deffn {Procedure} trace-at-exit trap-context
-Install a further trap to cause the return value of the application or
-evaluation just starting (as described by @var{trap-context}) to be
-traced using @code{trace-trap}, when this application or evaluation
-completes.  The extra trap is automatically uninstalled after the
-return value has been traced.
-@end deffn
-
-@deffn {Procedure} trace-until-exit trap-context
-Install a further trap so that every step that the evaluator performs
-as part of the application or evaluation just starting (as described
-by @var{trap-context}) is traced using @code{trace-trap}.  The extra
-trap is automatically uninstalled when the application or evaluation
-is complete.  @code{trace-until-exit} can be very useful as a first
-step when all you know is that there is a bug ``somewhere in XXX or in
-something that XXX calls''.
-@end deffn
-
-@noindent
-@code{debug-trap} and @code{gds-debug-trap} are provided by the modules
-@code{(ice-9 debugger)} and @code{(ice-9 gds-client)} respectively, and
-their behaviours are fairly self-explanatory.  For more information on
-the operation of the GDS interface via Emacs, see @ref{Using Guile in
-Emacs}.  The tracing behaviours are explained more fully below.
-
-@cindex Trap context
-More generally, the @dfn{behaviour} specified for a trap can be any
-procedure that expects to be called with one @dfn{trap context}
-argument.  A trivial example would be:
-
-@lisp
-(define (report-stack-depth trap-context)
-  (display "Stack depth at the trap is: ")
-  (display (tc:depth trap-context))
-  (newline))
-@end lisp
-
-
-@node Trap Context
-@subsubsection Trap Context
-
-The @dfn{trap context} is an object that caches information about the
-low level trap call and the stack at the point of the trap, and is
-passed as the only argument to all behaviour procedures.  The
-information in the trap context can be accessed through the procedures
-beginning @code{tc:} that are exported by the @code{(ice-9 debugging
-traps)} module@footnote{Plus of course any procedures that build on
-these, such as the @code{trace/@dots{}} procedures exported by
-@code{(ice-9 debugging trace)} (@pxref{Tracing Configuration}).}; the
-most useful of these are as follows.
-
-@deffn {Generic Function} tc:type trap-context
-Indicates the type of the low level trap by returning one of the
-keywords @code{#:application}, @code{#:evaluation}, @code{#:return} or
-@code{#:error}.
-@end deffn
-
-@deffn {Generic Function} tc:return-value trap-context
-When @code{tc:type} gives @code{#:return}, this provides the value
-that is being returned.
-@end deffn
-
-@deffn {Generic Function} tc:stack trap-context
-Provides the stack at the point of the trap (as computed by
-@code{make-stack}, but cached so that the lengthy @code{make-stack}
-operation is not performed more than once for the same low level
-trap).
-@end deffn
-
-@deffn {Generic Function} tc:frame trap-context
-The innermost frame of the stack at the point of the trap.
-@end deffn
-
-@deffn {Generic Function} tc:depth trap-context
-The number of frames (including tail recursive non-real frames) in the
-stack at the point of the trap.
-@end deffn
-
-@deffn {Generic Function} tc:real-depth trap-context
-The number of real frames (that is, excluding the non-real frames that
-describe tail recursive calls) in the stack at the point of the trap.
-@end deffn
-
-
-@node Tracing Examples
-@subsubsection Tracing Examples
-
-The following examples show what tracing is and the kind of output that
-it generates.  In the first example, we define a recursive function for
-reversing a list, then watch the effect of the recursive calls by
-tracing each call and return value.
-
-@lisp
-guile> (define (rev ls)
-         (if (null? ls)
-             ls
-             (append (rev (cdr ls))
-                     (list (car ls)))))
-guile> (use-modules (ice-9 debugging traps) (ice-9 debugging trace))
-guile> (define t1 (make <procedure-trap>
-                    #:procedure rev
-                    #:behaviour (list trace-trap
-                                      trace-at-exit)))
-guile> (install-trap t1)
-guile> (rev '(a b c))
-|  2: [rev (a b c)]
-|  3: [rev (b c)]
-|  4: [rev (c)]
-|  5: [rev ()]
-|  5: =>()
-|  4: =>(c)
-|  3: =>(c b)
-|  2: =>(c b a)
-(c b a)
-@end lisp
-
-@noindent
-The number before the colon in this output (which follows @code{(ice-9
-debugging trace)}'s default output format) is the number of real frames
-on the stack.  The fact that this number increases for each recursive
-call confirms that the implementation above of @code{rev} is not
-tail-recursive.
-
-In the next example, we probe the @emph{internal} workings of
-@code{rev} in more detail by using the @code{trace-until-exit}
-behaviour.
-
-@lisp
-guile> (uninstall-trap t1)
-guile> (define t2 (make <procedure-trap>
-                    #:procedure rev
-                    #:behaviour (list trace-trap
-                                      trace-until-exit)))
-guile> (install-trap t2)
-guile> (rev '(a b))
-|  2: [rev (a b)]
-|  2: (if (null? ls) ls (append (rev (cdr ls)) (list (car ls))))
-|  3: (null? ls)
-|  3: [null? (a b)]
-|  3: =>#f
-|  2: (append (rev (cdr ls)) (list (car ls)))
-|  3: (rev (cdr ls))
-|  4: (cdr ls)
-|  4: [cdr (a b)]
-|  4: =>(b)
-|  3: [rev (b)]
-|  3: (if (null? ls) ls (append (rev (cdr ls)) (list (car ls))))
-|  4: (null? ls)
-|  4: [null? (b)]
-|  4: =>#f
-|  3: (append (rev (cdr ls)) (list (car ls)))
-|  4: (rev (cdr ls))
-|  5: (cdr ls)
-|  5: [cdr (b)]
-|  5: =>()
-|  4: [rev ()]
-|  4: (if (null? ls) ls (append (rev (cdr ls)) (list (car ls))))
-|  5: (null? ls)
-|  5: [null? ()]
-|  5: =>#t
-|  4: (list (car ls))
-|  5: (car ls)
-|  5: [car (b)]
-|  5: =>b
-|  4: [list b]
-|  4: =>(b)
-|  3: [append () (b)]
-|  3: =>(b)
-|  3: (list (car ls))
-|  4: (car ls)
-|  4: [car (a b)]
-|  4: =>a
-|  3: [list a]
-|  3: =>(a)
-|  2: [append (b) (a)]
-|  2: =>(b a)
-(b a)
-@end lisp
-
-@noindent
-The output in this case shows every step that the evaluator performs
-in evaluating @code{(rev '(a b))}.
-
-
-@node Tracing Configuration
-@subsubsection Tracing Configuration
-
-The detail of what gets printed in each trace line, and the port to
-which tracing is written, can be configured by the procedures
-@code{set-trace-layout} and @code{trace-port}, both exported by the
-@code{(ice-9 debugging trace)} module.
-
-@deffn {Procedure with Setter} trace-port
-Get or set the port to which tracing is printed.  The default is the
-value of @code{(current-output-port)} when the @code{(ice-9 debugging
-trace)} module is first loaded.
-@end deffn
-
-@deffn {Procedure} set-trace-layout format-string . arg-procs
-Layout each trace line using @var{format-string} and @var{arg-procs}.
-For each trace line, the list of values to be printed is obtained by
-calling all the @var{arg-procs}, passing the trap context as the only
-parameter to each one.  This list of values is then formatted using
-the specified @var{format-string}.
-@end deffn
-
-@noindent
-The @code{(ice-9 debugging trace)} module exports a set of arg-proc
-procedures to cover most common needs, with names beginning
-@code{trace/}.  These are all implemented on top of the @code{tc:} trap
-context accessor procedures documented in @ref{Trap Context}, and if any
-trace output not provided by the following is needed, it should be
-possible to implement based on a combination of the @code{tc:}
-procedures.
-
-@deffn {Procedure} trace/pid trap-context
-An arg-proc that returns the current process ID.
-@end deffn
-
-@deffn {Procedure} trace/stack-id trap-context
-An arg-proc that returns the stack ID of the stack in which the
-current trap occurred.
-@end deffn
-
-@deffn {Procedure} trace/stack-depth trap-context
-An arg-proc that returns the length (including non-real frames) of the
-stack at the point of the current trap.
-@end deffn
-
-@deffn {Procedure} trace/stack-real-depth trap-context
-An arg-proc that returns the length excluding non-real frames of the
-stack at the point of the current trap.
-@end deffn
-
-@deffn {Procedure} trace/stack trap-context
-An arg-proc that returns a string summarizing stack information.  This
-string includes the stack ID, real depth, and count of additional
-non-real frames, with the format @code{"~a:~a+~a"}.
-@end deffn
-
-@deffn {Procedure} trace/source-file-name trap-context
-An arg-proc that returns the name of the source file for the innermost
-stack frame, or an empty string if source is not available for the
-innermost frame.
-@end deffn
-
-@deffn {Procedure} trace/source-line trap-context
-An arg-proc that returns the line number of the source code for the
-innermost stack frame, or zero if source is not available for the
-innermost frame.
-@end deffn
-
-@deffn {Procedure} trace/source-column trap-context
-An arg-proc that returns the column number of the start of the source
-code for the innermost stack frame, or zero if source is not available
-for the innermost frame.
-@end deffn
-
-@deffn {Procedure} trace/source trap-context
-An arg-proc that returns the source location for the innermost stack
-frame.  This is a string composed of file name, line and column number
-with the format @code{"~a:~a:~a"}, or an empty string if source is not
-available for the innermost frame.
-@end deffn
-
-@deffn {Procedure} trace/type trap-context
-An arg-proc that returns a three letter abbreviation indicating the
-type of the current trap: @code{"APP"} for an application frame,
-@code{"EVA"} for an evaluation, @code{"RET"} for an exit trap, or
-@code{"ERR"} for an error (pseudo-)trap.
-@end deffn
-
-@deffn {Procedure} trace/real? trap-context
-An arg-proc that returns @code{" "} if the innermost stack frame is a
-real frame, or @code{"t"} if it is not.
-@end deffn
-
-@deffn {Procedure} trace/info trap-context
-An arg-proc that returns a string describing the expression being
-evaluated, application being performed, or return value, according to
-the current trap type.
-@end deffn
-
-@noindent
-@code{trace/stack-depth} and @code{trace/stack-real-depth} are identical
-to the trap context methods @code{tc:depth} and @code{tc:real-depth}
-described before (@pxref{Trap Context}), but renamed here for
-convenience.
-
-The default trace layout, as exhibited by the examples of the previous
-subsubsubsection, is set by this line of code from the @code{(ice-9 debugging
-traps)} module:
-
-@lisp
-(set-trace-layout "|~3@@a: ~a\n" trace/stack-real-depth trace/info)
-@end lisp
-
-@noindent
-If we rerun the first of those examples, but with trace layout
-configured to show source location and trap type in addition, the
-output looks like this:
-
-@lisp
-guile> (set-trace-layout "| ~25a ~3@@a: ~a ~a\n"
-                         trace/source
-                         trace/stack-real-depth
-                         trace/type
-                         trace/info)
-guile> (rev '(a b c))
-| standard input:29:0         2: APP [rev (a b c)]
-| standard input:4:21         3: APP [rev (b c)]
-| standard input:4:21         4: APP [rev (c)]
-| standard input:4:21         5: APP [rev ()]
-| standard input:2:9          5: RET =>()
-| standard input:4:13         4: RET =>(c)
-| standard input:4:13         3: RET =>(c b)
-| standard input:4:13         2: RET =>(c b a)
-(c b a)
-@end lisp
-
-
-@node Tracing and (ice-9 debug)
-@subsubsection Tracing and (ice-9 debug)
-
-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
-The @code{(ice-9 debug)} trace gives a nice pictorial view of changes
-in stack depth, by using indentation like this:
-
-@lisp
-[fact1 4]
-|  [fact1 3]
-|  |  [fact1 2]
-|  |  |  [fact1 1]
-|  |  |  |  [fact1 0]
-|  |  |  |  1
-|  |  |  1
-|  |  2
-|  6
-24
-@end lisp
-
-However its output can @emph{only} show the information seen here,
-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 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.  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{(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
-@subsubsection Traps Installing More Traps
-
-Sometimes it is desirable for the behaviour at one trap to install
-further traps.  In other words, the behaviour is something like
-``Don't do much right now, but set things up to stop after two or
-three more steps'', or ``@dots{} when this frame completes''.  This is
-absolutely fine.  For example, it is easy to code a generic ``do
-so-and-so when the current frame exits'' procedure, which can be used
-wherever a trap context is available, as follows.
-
-@lisp
-(define (at-exit trap-context behaviour)
-  (install-trap (make <exit-trap>
-                 #:depth (tc:depth trap-context)
-                 #:single-shot #t
-                 #:behaviour behaviour)))
-@end lisp
-
-To continue and pin down the example, this could then be used as part
-of a behaviour whose purpose was to measure the accumulated time spent
-in and below a specified procedure.
-
-@lisp
-(define calls 0)
-(define total 0)
-
-(define accumulate-time
-  (lambda (trap-context)
-    (set! calls (+ calls 1))
-    (let ((entry (current-time)))
-      (at-exit trap-context
-        (lambda (ignored)
-          (set! total
-                (+ total (- (current-time)
-                            entry))))))))
-
-(install-trap (make <procedure-trap>
-                #:procedure my-proc
-                #:behaviour accumulate-time))
-@end lisp
-
-
-@node Common Trap Options
-@subsubsection Common Trap Options
-
-When creating any kind of trap object, settings for the trap being
-created are specified as options on the @code{make} call using syntax
-like this:
-
-@lisp
-(make <@var{trap-class}>
-  #:@var{option-keyword} @var{setting}
-  @dots{})
-@end lisp
-
-The following common options are provided by the base class
-@code{<trap>}, and so can be specified for any kind of trap.
-
-@deffn {Class} <trap>
-Base class for trap objects.
-@end deffn
-
-@deffn {Trap Option} #:condition thunk
-If not @code{#f}, this is a thunk which is called when the trap fires,
-to determine whether trap processing should proceed any further.  If
-the thunk returns @code{#f}, the trap is basically suppressed.
-Otherwise processing continues normally.  (Default value @code{#f}.)
-@end deffn
-
-@deffn {Trap Option} #:skip-count count
-A count of valid (after @code{#:condition} processing) firings of this
-trap to skip.  (Default value 0.)
-@end deffn
-
-@deffn {Trap Option} #:single-shot boolean
-If not @code{#f}, this indicates that the trap should be automatically
-uninstalled after it has successfully fired (after @code{#:condition}
-and @code{#:skip-count} processing) for the first time.  (Default
-value @code{#f}.)
-@end deffn
-
-@deffn {Trap Option} #:behaviour behaviour-proc
-A trap behaviour procedure --- as discussed in the preceding subsubsection
---- or a list of such procedures, in which case each procedure is
-called in turn when the trap fires.  (Default value @code{'()}.)
-@end deffn
-
-@deffn {Trap Option} #:repeat-identical-behaviour boolean
-Normally, if multiple trap objects are triggered by the same low level
-trap, and they request the same behaviour, it's only actually useful
-to do that behaviour once (per low level trap); so by default multiple
-requests for the same behaviour are coalesced.  If this option is set
-other than @code{#f}, the contents of the @code{#:behaviour} option
-are uniquified so that they avoid being coalesced in this way.
-(Default value @code{#f}.)
-@end deffn
-
-
-@node Procedure Traps
-@subsubsection Procedure Traps
-
-The @code{<procedure-trap>} class implements traps that are triggered
-upon application of a specified procedure.  Instances of this class
-should use the @code{#:procedure} option to specify the procedure to
-trap on.
-
-@deffn {Class} <procedure-trap>
-Class for traps triggered by application of a specified procedure.
-@end deffn
-
-@deffn {Trap Option} #:procedure procedure
-Specifies the procedure to trap on.
-@end deffn
-
-@noindent
-Example:
-
-@lisp
-(install-trap (make <procedure-trap>
-                #:procedure my-proc
-                #:behaviour (list trace-trap
-                                  trace-until-exit)))
-@end lisp
-
-
-@node Exit Traps
-@subsubsection Exit Traps
-
-The @code{<exit-trap>} class implements traps that are triggered upon
-stack frame exit past a specified stack depth.  Instances of this
-class should use the @code{#:depth} option to specify the target stack
-depth.
-
-@deffn {Class} <exit-trap>
-Class for traps triggered by exit past a specified stack depth.
-@end deffn
-
-@deffn {Trap Option} #:depth depth
-Specifies the reference depth for the trap.
-@end deffn
-
-@noindent
-Example:
-
-@lisp
-(define (trace-at-exit trap-context)
-  (install-trap (make <exit-trap>
-                 #:depth (tc:depth trap-context)
-                 #:single-shot #t
-                 #:behaviour trace-trap)))
-@end lisp
-
-@noindent
-(This is the actual definition of the @code{trace-at-exit} behaviour.)
-
-
-@node Entry Traps
-@subsubsection Entry Traps
-
-The @code{<entry-trap>} class implements traps that are triggered upon
-any stack frame entry.  No further parameters are needed to specify an
-instance of this class, so there are no class-specific trap options.
-Note that it remains possible to use the common trap options
-(@pxref{Common Trap Options}), for example to set a trap for the
-@var{n}th next frame entry.
-
-@deffn {Class} <entry-trap>
-Class for traps triggered by any stack frame entry.
-@end deffn
-
-@noindent
-Example:
-
-@lisp
-(install-trap (make <entry-trap>
-               #:skip-count 5
-               #:behaviour gds-debug-trap))
-@end lisp
-
-
-@node Apply Traps
-@subsubsection Apply Traps
-
-The @code{<apply-trap>} class implements traps that are triggered upon
-any procedure application.  No further parameters are needed to
-specify an instance of this class, so there are no class-specific trap
-options.  Note that it remains possible to use the common trap options
-(@pxref{Common Trap Options}), for example to set a trap for the next
-application where some condition is true.
-
-@deffn {Class} <apply-trap>
-Class for traps triggered by any procedure application.
-@end deffn
-
-@noindent
-Example:
-
-@lisp
-(install-trap (make <apply-trap>
-               #:condition my-condition
-               #:behaviour gds-debug-trap))
-@end lisp
-
-
-@node Step Traps
-@subsubsection Step Traps
-
-The @code{<step-trap>} class implements traps that do single-stepping
-through a program's execution.  They come in two flavours, with and
-without a specified file name.  If a file name is specified, the trap
-is triggered by the next evaluation, application or frame exit
-pertaining to source code from the specified file.  If a file name is
-not specified, the trap is triggered by the next evaluation,
-application or frame exit from any file (or for code whose source
-location was not recorded), in other words by the next evaluator step
-of any kind.
-
-The design goal of the @code{<step-trap>} class is to match what a
-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 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
-low level frame exit trap is applicable to a specified file by
-examining the details of the reported frame.  This is a consequence of
-tail recursion, which has the effect that many frames can be removed
-from the stack at once, with only the outermost frame being reported
-by the low level trap call.  The effects of this on the
-@code{<step-trap>} class are such as to require the introduction of
-the strange-looking @code{#:exit-depth} option, for the following
-reasons.
-
-@itemize @bullet
-@item
-When stopped at the start of an application or evaluation frame, and
-it is desired to continue execution until the next ``step'' in the same
-source file, that next step could be the start of a nested application
-or evaluation frame, or --- if the procedure definition is in a
-different file, for example --- it could be the exit from the current
-frame.
-
-@item
-Because of the effects of tail recursion noted above, the current
-frame exit possibility must be expressed as frame exit past a
-specified stack depth.  When an instance of the @code{<step-trap>}
-class is installed from the context of an application or evaluation
-frame entry, the @code{#:exit-depth} option should be used to specify
-this stack depth.
-
-@item
-When stopped at a frame exit, on the other hand, we know that the next
-step must be an application or evaluation frame entry.  In this
-context the @code{#:exit-depth} option is not needed and should be
-omitted or set to @code{#f}.
-@end itemize
-
-@noindent
-When a step trap is installed without @code{#:single-shot #t}, such
-that it keeps firing, the @code{<step-trap>} code automatically
-updates its idea of the @code{#:exit-depth} setting each time, so that
-the trap always fires correctly for the following step.
-
-@deffn {Class} <step-trap>
-Class for single-stepping traps.
-@end deffn
-
-@deffn {Trap Option} #:file-name name
-If not @code{#f}, this is a string containing the name of a source
-file, and restricts the step trap to evaluation steps within that
-source file.  (Default value @code{#f}.)
-@end deffn
-
-@deffn {Trap Option} #:exit-depth depth
-If not @code{#f}, this is a positive integer implying that the next
-step may be frame exit past the stack depth @var{depth}.  See the
-discussion above for more details.  (Default value @code{#f}.)
-@end deffn
-
-@noindent
-Example:
-
-@lisp
-(install-trap (make <step-trap>
-                #:file-name (frame-file-name
-                              (stack-ref stack index))
-                #:exit-depth (- (stack-length stack)
-                                (stack-ref stack index))
-                #:single-shot #t
-                #:behaviour debug-trap))
-@end lisp
-
-
-@node Source Traps
-@subsubsection Source Traps
-
-The @code{<source-trap>} class implements traps that are attached to a
-precise source code expression, as read by the reader, and which fire
-each time that that expression is evaluated.  These traps use a low
-level Guile feature which can mark individual expressions for
-trapping, and are relatively efficient.  But it can be tricky to get
-at the source expression in the first place, and these traps are
-liable to become irrelevant if the procedure containing the expression
-is reevaluated; these issues are discussed further below.
-
-@deffn {Class} <source-trap>
-Class for traps triggered by evaluation of a specific Scheme
-expression.
-@end deffn
-
-@deffn {Trap Option} #:expression expr
-Specifies the Scheme expression to trap on.
-@end deffn
-
-@noindent
-Example:
-
-@lisp
-(display "Enter an expression: ")
-(let ((x (read)))
-  (install-trap (make <source-trap>
-                  #:expression x
-                  #:behaviour (list trace-trap
-                                    trace-at-exit)))
-  (primitive-eval x))
-@print{}
-Enter an expression: (+ 1 2 3 4 5 6)
-|  3: (+ 1 2 3 4 5 6)
-|  3: =>21
-21
-@end lisp
-
-The key point here is that the expression specified by the
-@code{#:expression} option must be @emph{exactly} (i.e. @code{eq?} to)
-what is going to be evaluated later.  It doesn't work, for example, to
-say @code{#:expression '(+ x 3)}, with the expectation that the trap
-will fire whenever evaluating any expression @code{(+ x 3)}.
-
-The @code{trap-here} macro can be used in source code to create and
-install a source trap correctly.  Take for example the factorial
-function defined in the @code{(ice-9 debugging example-fns)} module:
-
-@lisp
-(define (fact1 n)
-  (if (= n 0)
-      1
-      (* n (fact1 (- n 1)))))
-@end lisp
-
-@noindent
-To set a source trap on a particular expression --- let's say the
-expression @code{(= n 0)} --- edit the code so that the expression is
-enclosed in a @code{trap-here} macro call like this:
-
-@lisp
-(define (fact1 n)
-  (if (trap-here (= n 0) #:behaviour debug-trap)
-      1
-      (* n (fact1 (- n 1)))))
-@end lisp
-
-@deffn {Macro} trap-here expression . trap-options
-Install a source trap with options @var{trap-options} on
-@var{expression}, then return with the whole call transformed to
-@code{(begin @var{expression})}.
-@end deffn
-
-Note that if the @code{trap-here} incantation is removed, and
-@code{fact1} then redefined by reloading its source file, the effect
-of the source trap is lost, because the text ``(= n 0)'' is read again
-from scratch and becomes a new expression @code{(= n 0)} which does
-not have the ``trap here'' mark on it.
-
-If the semantics and setting of source traps seem unwieldy, location
-traps may meet your need more closely; these are described in the
-following subsubsection.
-
-
-@node Location Traps
-@subsubsection Location Traps
-
-The @code{<location-trap>} class implements traps that are triggered
-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.
-@end deffn
-
-@deffn {Trap Option} #:file-regexp regexp
-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
-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
-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
-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
-                #:column 6
-                #:behaviour gds-debug-trap))
-@end lisp
-
-
-@node Trap Shorthands
-@subsubsection Trap Shorthands
-
-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.  Here are some examples.
-
-@lisp
-(define (break! proc)
-  (install-trap (make <procedure-trap>
-                  #:procedure proc
-                  #:behaviour gds-debug-trap)))
-
-(define (trace! proc)
-  (install-trap (make <procedure-trap>
-                  #:procedure proc
-                  #:behaviour (list trace-trap
-                                    trace-at-exit))))
-
-(define (trace-subtree! proc)
-  (install-trap (make <procedure-trap>
-                  #:procedure proc
-                  #:behaviour (list trace-trap
-                                    trace-until-exit))))
-@end lisp
-
-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
-@subsubsection Trap Utilities
-
-@code{list-traps} can be used to print a description of all known trap
-objects.  This uses a weak value hash table, keyed by a trap index
-number.  Each trap object has its index number assigned, and is added
-to the hash table, when it is created by a @code{make @var{trap-class}
-@dots{}} call.  When a trap object is GC'd, it is automatically
-removed from the hash table, and so no longer appears in the output
-from @code{list-traps}.
-
-@deffn {Variable} all-traps
-Weak value hash table containing all known trap objects.
-@end deffn
-
-@deffn {Procedure} list-traps
-Print a description of all known trap objects.
-@end deffn
-
-The following example shows a single trap that traces applications of
-the procedure @code{facti}.
-
-@lisp
-guile> (list-traps)
-#<<procedure-trap> 100d2e30> is an instance of class <procedure-trap>
-Slots are:
-     number = 1
-     installed = #t
-     condition = #f
-     skip-count = 0
-     single-shot = #f
-     behaviour = (#<procedure trace-trap (trap-context)>)
-     repeat-identical-behaviour = #f
-     procedure = #<procedure facti (n a)>
-@end lisp
-
-When @code{all-traps} or @code{list-traps} reveals a trap that you
-want to modify but no longer have a reference to, you can retrieve the
-trap object by calling @code{get-trap} with the trap's number.  For
-example, here's how you could change the behaviour of the trap listed
-just above.
-
-@lisp
-(slot-set! (get-trap 1) 'behaviour (list debug-trap))
-@end lisp
-
-@deffn {Procedure} get-trap number
-Return the trap object with the specified @var{number}, or @code{#f}
-if there isn't one.
-@end deffn
-
-
-@node Debugging Examples
-@subsection Debugging Examples
-
-Here we present some examples of what you can do with the debugging
-facilities just described.
-
-@menu
-* Single Stepping through a Procedure's Code::
-* Profiling or Tracing a Procedure's Code::
-@end menu
-
-
-@node Single Stepping through a Procedure's Code
-@subsubsection Single Stepping through a Procedure's Code
-
-A good way to explore in detail what a Scheme procedure does is to set
-a trap on it and then single step through what it does.  To do this,
-make and install a @code{<procedure-trap>} with the @code{debug-trap}
-behaviour from @code{(ice-9 debugging ice-9-debugger-extensions)}.
-
-The following sample session illustrates this.  It assumes that the
-file @file{matrix.scm} defines a procedure @code{mkmatrix}, which is
-the one we want to explore, and another procedure @code{do-main} which
-calls @code{mkmatrix}.
-
-@lisp
-$ /usr/bin/guile -q
-guile> (use-modules (ice-9 debugger)
-                    (ice-9 debugging ice-9-debugger-extensions)
-                    (ice-9 debugging traps))
-guile> (load "matrix.scm")
-guile> (install-trap (make <procedure-trap>
-                       #:procedure mkmatrix
-                       #:behaviour debug-trap))
-guile> (do-main 4)
-This is the Guile debugger -- for help, type `help'.
-There are 3 frames on the stack.
-
-Frame 2 at matrix.scm:8:3
-        [mkmatrix]
-debug> next
-Frame 3 at matrix.scm:4:3
-        (let ((x 1)) (quote this-is-a-matric))
-debug> info frame
-Stack frame: 3
-This frame is an evaluation.
-The expression being evaluated is:
-matrix.scm:4:3:
-  (let ((x 1)) (quote this-is-a-matric))
-debug> next
-Frame 3 at matrix.scm:5:21
-        (quote this-is-a-matric)
-debug> bt
-In unknown file:
-   ?: 0* [primitive-eval (do-main 4)]
-In standard input:
-   4: 1* [do-main 4]
-In matrix.scm:
-   8: 2  [mkmatrix]
-   ...
-   5: 3  (quote this-is-a-matric)
-debug> quit
-this-is-a-matric
-guile> 
-@end lisp
-
-Or you can use Guile's Emacs interface (GDS), by using the module
-@code{(ice-9 gds-client)} instead of @code{(ice-9 debugger)} and
-@code{(ice-9 debugging ice-9-debugger-extensions)}, and changing
-@code{debug-trap} to @code{gds-debug-trap}.  Then the stack and
-corresponding source locations are displayed in Emacs instead of on
-the Guile command line.
-
-
-@node Profiling or Tracing a Procedure's Code
-@subsubsection Profiling or Tracing a Procedure's Code
-
-What if you wanted to get a trace of everything that the Guile
-evaluator does within a given procedure, but without Guile stopping
-and waiting for your input at every step?  For this requirement you
-can install a trap on the procedure, as in the previous example, but
-instead of @code{debug-trap} or @code{gds-debug-trap}, use the
-@code{trace-trap} and @code{trace-until-exit} behaviours provided by
-the @code{(ice-9 debugging trace)} module.
-
-@lisp
-guile> (use-modules (ice-9 debugging traps) (ice-9 debugging trace))
-guile> (load "matrix.scm")
-guile> (install-trap (make <procedure-trap>
-                       #:procedure mkmatrix
-                       #:behaviour (list trace-trap trace-until-exit)))
-guile> (do-main 4)
-|  2: [mkmatrix]
-|  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> define #f]
-|  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> define #f]
-|  4: (and (memq sym bindings) (let ...))
-|  5: (memq sym bindings)
-|  5: [memq define (debug)]
-|  5: =>#f
-|  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> define #f]
-|  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> define #f]
-|  4: (and (memq sym bindings) (let ...))
-|  5: (memq sym bindings)
-|  5: [memq define (debug)]
-|  5: =>#f
-|  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
-|  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
-|  4: (and (memq sym bindings) (let ...))
-|  5: (memq sym bindings)
-|  5: [memq let (debug)]
-|  5: =>#f
-|  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
-|  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
-|  4: (and (memq sym bindings) (let ...))
-|  5: (memq sym bindings)
-|  5: [memq let (debug)]
-|  5: =>#f
-|  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
-|  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
-|  4: (and (memq sym bindings) (let ...))
-|  5: (memq sym bindings)
-|  5: [memq let (debug)]
-|  5: =>#f
-|  2: (letrec ((yy 23)) (let ((x 1)) (quote this-is-a-matric)))
-|  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
-|  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
-|  4: (and (memq sym bindings) (let ...))
-|  5: (memq sym bindings)
-|  5: [memq let (debug)]
-|  5: =>#f
-|  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
-|  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
-|  4: (and (memq sym bindings) (let ...))
-|  5: (memq sym bindings)
-|  5: [memq let (debug)]
-|  5: =>#f
-|  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
-|  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
-|  4: (and (memq sym bindings) (let ...))
-|  5: (memq sym bindings)
-|  5: [memq let (debug)]
-|  5: =>#f
-|  2: (let ((x 1)) (quote this-is-a-matric))
-|  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
-|  3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f]
-|  4: (and (memq sym bindings) (let ...))
-|  5: (memq sym bindings)
-|  5: [memq let (debug)]
-|  5: =>#f
-|  2: [let (let # #) (# # #)]
-|  2: [let (let # #) (# # #)]
-|  2: =>(#@@let* (x 1) #@@let (quote this-is-a-matric))
-this-is-a-matric
-guile> (do-main 4)
-|  2: [mkmatrix]
-|  2: (letrec ((yy 23)) (let* ((x 1)) (quote this-is-a-matric)))
-|  2: (let* ((x 1)) (quote this-is-a-matric))
-|  2: (quote this-is-a-matric)
-|  2: =>this-is-a-matric
-this-is-a-matric
-guile> 
-@end lisp
-
-This example shows the default configuration for how each line of trace
-output is formatted, which is:
-
-@itemize
-@item
-the character @code{|}, a visual clue that the line is a line of trace
-output, followed by
-
-@item
-a number indicating the real evaluator stack depth (where ``real'' means
-not counting tail-calls), followed by
-
-@item
-a summary of the expression being evaluated (@code{(@dots{})}), the
-procedure being called (@code{[@dots{}]}), or the value being returned
-from an evaluation or procedure call (@code{=>@dots{}}).
-@end itemize
-
-@noindent
-You can customize @code{(ice-9 debugging trace)} to show different
-information in each trace line using the @code{set-trace-layout}
-procedure.  The next example shows how to get the source location in
-each trace line instead of the stack depth.
-
-@lisp
-guile> (set-trace-layout "|~16@@a: ~a\n" trace/source trace/info)
-guile> (do-main 4)
-|  matrix.scm:7:2: [mkmatrix]
-|                : (letrec ((yy 23)) (let* ((x 1)) (quote this-is-a-matric)))
-|  matrix.scm:3:2: (let* ((x 1)) (quote this-is-a-matric))
-|  matrix.scm:4:4: (quote this-is-a-matric)
-|  matrix.scm:4:4: =>this-is-a-matric
-this-is-a-matric
-guile> 
-@end lisp
-
-@anchor{Memoization}
-@cindex Memoization
-(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:
+@c -*-texinfo-*-
+@c This is part of the GNU Guile Reference Manual.
+@c Copyright (C)  1996, 1997, 2000, 2001, 2002, 2003, 2004, 2007, 2010, 2011, 2012, 2013
+@c   Free Software Foundation, Inc.
+@c See the file guile.texi for copying conditions.
+
+@node Debugging
+@section Debugging Infrastructure
+
+@cindex Debugging
+In order to understand Guile's debugging facilities, you first need to
+understand a little about how Guile represent the Scheme control stack.
+With that in place we explain the low level trap calls that the virtual
+machine can be configured to make, and the trap and breakpoint
+infrastructure that builds on top of those calls.
+
+@menu
+* Evaluation Model::            Evaluation and the Scheme stack.
+* Source Properties::           From expressions to source locations.
+* Programmatic Error Handling:: Debugging when an error occurs.
+* Traps::                       Breakpoints, tracepoints, oh my!
+@end menu
+
+@node Evaluation Model
+@subsection Evaluation and the Scheme Stack
+
+The idea of the Scheme stack is central to a lot of debugging.  The
+Scheme stack is a reified representation of the pending function returns
+in an expression's continuation.  As Guile implements function calls
+using a stack, this reification takes the form of a number of nested
+stack frames, each of which corresponds to the application of a
+procedure to a set of arguments.
+
+A Scheme stack always exists implicitly, and can be summoned into
+concrete existence as a first-class Scheme value by the
+@code{make-stack} call, so that an introspective Scheme program -- such
+as a debugger -- can present it in some way and allow the user to query
+its details. The first thing to understand, therefore, is how Guile's
+function call convention creates the stack.
+
+Broadly speaking, Guile represents all control flow on a stack. Calling
+a function involves pushing an empty frame on the stack, then evaluating
+the procedure and its arguments, then fixing up the new frame so that it
+points to the old one. Frames on the stack are thus linked together. A
+tail call is the same, except it reuses the existing frame instead of
+pushing on a new one.
+
+In this way, the only frames that are on the stack are ``active''
+frames, frames which need to do some work before the computation is
+complete. On the other hand, a function that has tail-called another
+function will not be on the stack, as it has no work left to do.
+
+Therefore, when an error occurs in a running program, or the program
+hits a breakpoint, or in fact at any point that the programmer chooses,
+its state at that point can be represented by a @dfn{stack} of all the
+procedure applications that are logically in progress at that time, each
+of which is known as a @dfn{frame}.  The programmer can learn more about
+the program's state at that point by inspecting the stack and its
+frames.
+
+@menu
+* Stack Capture::               Reifying a continuation.
+* Stacks::                      Accessors for the stack data type.
+* Frames::                      Likewise, accessors for stack frames.
+@end menu
+
+@node Stack Capture
+@subsubsection Stack Capture
+
+A Scheme program can use the @code{make-stack} primitive anywhere in its
+code, with first arg @code{#t}, to construct a Scheme value that
+describes the Scheme stack at that point.
+
+@lisp
+(make-stack #t)
+@result{}
+#<stack 25205a0>
+@end lisp
+
+Use @code{start-stack} to limit the stack extent captured by future
+@code{make-stack} calls.
+
+@deffn {Scheme Procedure} make-stack obj arg @dots{}
+@deffnx {C Function} scm_make_stack (obj, args)
+Create a new stack. If @var{obj} is @code{#t}, the current
+evaluation stack is used for creating the stack frames,
+otherwise the frames are taken from @var{obj} (which must be
+a continuation or a frame object).
+
+@var{arg} @dots{} can be any combination of integer, procedure, prompt
+tag and @code{#t} values.
+
+These values specify various ways of cutting away uninteresting
+stack frames from the top and bottom of the stack that
+@code{make-stack} returns.  They come in pairs like this:
+@code{(@var{inner_cut_1} @var{outer_cut_1} @var{inner_cut_2}
+@var{outer_cut_2} @dots{})}.
+
+Each @var{inner_cut_i} can be @code{#t}, an integer, a prompt
+tag, or a procedure.  @code{#t} means to cut away all frames up
+to but excluding the first user module frame.  An integer means
+to cut away exactly that number of frames.  A prompt tag means
+to cut away all frames that are inside a prompt with the given
+tag. A procedure means to cut away all frames up to but
+excluding the application frame whose procedure matches the
+specified one.
+
+Each @var{outer_cut_i} can be an integer, a prompt tag, or a
+procedure.  An integer means to cut away that number of frames.
+A prompt tag means to cut away all frames that are outside a
+prompt with the given tag. A procedure means to cut away
+frames down to but excluding the application frame whose
+procedure matches the specified one.
+
+If the @var{outer_cut_i} of the last pair is missing, it is
+taken as 0.
+@end deffn
+
+@deffn {Scheme Syntax} start-stack id exp
+Evaluate @var{exp} on a new calling stack with identity @var{id}.  If
+@var{exp} is interrupted during evaluation, backtraces will not display
+frames farther back than @var{exp}'s top-level form.  This macro is a
+way of artificially limiting backtraces and stack procedures, largely as
+a convenience to the user.
+@end deffn
+
+
+@node Stacks
+@subsubsection Stacks
+
+@deffn {Scheme Procedure} stack? obj
+@deffnx {C Function} scm_stack_p (obj)
+Return @code{#t} if @var{obj} is a calling stack.
+@end deffn
+
+@deffn {Scheme Procedure} stack-id stack
+@deffnx {C Function} scm_stack_id (stack)
+Return the identifier given to @var{stack} by @code{start-stack}.
+@end deffn
+
+@deffn {Scheme Procedure} stack-length stack
+@deffnx {C Function} scm_stack_length (stack)
+Return the length of @var{stack}.
+@end deffn
+
+@deffn {Scheme Procedure} stack-ref stack index
+@deffnx {C Function} scm_stack_ref (stack, index)
+Return the @var{index}'th frame from @var{stack}.
+@end deffn
+
+@deffn {Scheme Procedure} display-backtrace stack port [first [depth [highlights]]]
+@deffnx {C Function} scm_display_backtrace_with_highlights (stack, port, first, depth, highlights)
+@deffnx {C Function} scm_display_backtrace (stack, port, first, depth)
+Display a backtrace to the output port @var{port}.  @var{stack}
+is the stack to take the backtrace from, @var{first} specifies
+where in the stack to start and @var{depth} how many frames
+to display.  @var{first} and @var{depth} can be @code{#f},
+which means that default values will be used.
+If @var{highlights} is given it should be a list; the elements
+of this list will be highlighted wherever they appear in the
+backtrace.
+@end deffn
+
+
+@node Frames
+@subsubsection Frames
+
+@deffn {Scheme Procedure} frame? obj
+@deffnx {C Function} scm_frame_p (obj)
+Return @code{#t} if @var{obj} is a stack frame.
+@end deffn
+
+@deffn {Scheme Procedure} frame-previous frame
+@deffnx {C Function} scm_frame_previous (frame)
+Return the previous frame of @var{frame}, or @code{#f} if
+@var{frame} is the first frame in its stack.
+@end deffn
+
+@deffn {Scheme Procedure} frame-procedure frame
+@deffnx {C Function} scm_frame_procedure (frame)
+Return the procedure for @var{frame}, or @code{#f} if no
+procedure is associated with @var{frame}.
+@end deffn
+
+@deffn {Scheme Procedure} frame-arguments frame
+@deffnx {C Function} scm_frame_arguments (frame)
+Return the arguments of @var{frame}.
+@end deffn
+
+@deffn {Scheme Procedure} frame-address frame
+@deffnx {Scheme Procedure} frame-instruction-pointer frame
+@deffnx {Scheme Procedure} frame-stack-pointer frame
+Accessors for the three VM registers associated with this frame: the
+frame pointer (fp), instruction pointer (ip), and stack pointer (sp),
+respectively. @xref{VM Concepts}, for more information.
+@end deffn
+
+@deffn {Scheme Procedure} frame-dynamic-link frame
+@deffnx {Scheme Procedure} frame-return-address frame
+@deffnx {Scheme Procedure} frame-mv-return-address frame
+Accessors for the three saved VM registers in a frame: the previous
+frame pointer, the single-value return address, and the multiple-value
+return address. @xref{Stack Layout}, for more information.
+@end deffn
+
+@deffn {Scheme Procedure} frame-num-locals frame
+@deffnx {Scheme Procedure} frame-local-ref frame i
+@deffnx {Scheme Procedure} frame-local-set! frame i val
+Accessors for the temporary values corresponding to @var{frame}'s
+procedure application. The first local is the first argument given to
+the procedure. After the arguments, there are the local variables, and
+after that temporary values. @xref{Stack Layout}, for more information.
+@end deffn
+
+@deffn {Scheme Procedure} display-application frame [port [indent]]
+@deffnx {C Function} scm_display_application (frame, port, indent)
+Display a procedure application @var{frame} to the output port
+@var{port}. @var{indent} specifies the indentation of the
+output.
+@end deffn
+
+Additionally, the @code{(system vm frame)} module defines a number of
+higher-level introspective procedures, for example to retrieve the names
+of local variables, and the source location to correspond to a
+frame. See its source code for more details.
+
+
+@node Source Properties
+@subsection Source Properties
+
+@cindex source properties
+As Guile reads in Scheme code from file or from standard input, it
+remembers the file name, line number and column number where each
+expression begins. These pieces of information are known as the
+@dfn{source properties} of the expression. Syntax expanders and the
+compiler propagate these source properties to compiled procedures, so
+that, if an error occurs when evaluating the transformed expression,
+Guile's debugger can point back to the file and location where the
+expression originated.
+
+The way that source properties are stored means that Guile cannot
+associate source properties with individual symbols, keywords,
+characters, booleans, or small integers.  This can be seen by typing
+@code{(xxx)} and @code{xxx} at the Guile prompt (where the variable
+@code{xxx} has not been defined):
+
+@example
+scheme@@(guile-user)> (xxx)
+<unnamed port>:4:1: In procedure module-lookup:
+<unnamed port>:4:1: Unbound variable: xxx
+
+scheme@@(guile-user)> xxx
+ERROR: In procedure module-lookup:
+ERROR: Unbound variable: xxx
+@end example
+
+@noindent
+In the latter case, no source properties were stored, so the error
+doesn't have any source information.
+
+@deffn {Scheme Procedure} supports-source-properties? obj
+@deffnx {C Function} scm_supports_source_properties_p (obj)
+Return #t if source properties can be associated with @var{obj},
+otherwise return #f.
+@end deffn
+
+The recording of source properties is controlled by the read option
+named ``positions'' (@pxref{Scheme Read}).  This option is switched
+@emph{on} by default.
+
+The following procedures can be used to access and set the source
+properties of read expressions.
+
+@deffn {Scheme Procedure} set-source-properties! obj alist
+@deffnx {C Function} scm_set_source_properties_x (obj, alist)
+Install the association list @var{alist} as the source property
+list for @var{obj}.
+@end deffn
+
+@deffn {Scheme Procedure} set-source-property! obj key datum
+@deffnx {C Function} scm_set_source_property_x (obj, key, datum)
+Set the source property of object @var{obj}, which is specified by
+@var{key} to @var{datum}.  Normally, the key will be a symbol.
+@end deffn
+
+@deffn {Scheme Procedure} source-properties obj
+@deffnx {C Function} scm_source_properties (obj)
+Return the source property association list of @var{obj}.
+@end deffn
+
+@deffn {Scheme Procedure} source-property obj key
+@deffnx {C Function} scm_source_property (obj, key)
+Return the property specified by @var{key} from @var{obj}'s source
+properties.
+@end deffn
+
+If the @code{positions} reader option is enabled, supported expressions
+will have values set for the @code{filename}, @code{line} and
+@code{column} properties.
+
+Source properties are also associated with syntax objects.  Procedural
+macros can get at the source location of their input using the
+@code{syntax-source} accessor.  @xref{Syntax Transformer Helpers}, for
+more.
+
+Guile also defines a couple of convenience macros built on
+@code{syntax-source}:
+
+@deffn {Scheme Syntax} current-source-location
+Expands to the source properties corresponding to the location of the
+@code{(current-source-location)} form.
+@end deffn
+
+@deffn {Scheme Syntax} current-filename
+Expands to the current filename: the filename that the
+@code{(current-filename)} form appears in.  Expands to @code{#f} if this
+information is unavailable.
+@end deffn
+
+If you're stuck with defmacros (@pxref{Defmacros}), and want to preserve
+source information, the following helper function might be useful to
+you:
+
+@deffn {Scheme Procedure} cons-source xorig x y
+@deffnx {C Function} scm_cons_source (xorig, x, y)
+Create and return a new pair whose car and cdr are @var{x} and @var{y}.
+Any source properties associated with @var{xorig} are also associated
+with the new pair.
+@end deffn
+
+
+@node Programmatic Error Handling
+@subsection Programmatic Error Handling
+
+For better or for worse, all programs have bugs, and dealing with bugs
+is part of programming. This section deals with that class of bugs that
+causes an exception to be raised -- from your own code, from within a
+library, or from Guile itself.
+
+@menu
+* Catching Exceptions::    Handling errors after the stack is unwound.
+* Capturing Stacks::       Capturing the stack at the time of error.
+* Pre-Unwind Debugging::   Debugging before the exception is thrown.
+* Debug Options::          A historical interface to debugging.
+@end menu
+
+@node Catching Exceptions
+@subsubsection Catching Exceptions
+
+A common requirement is to be able to show as much useful context as
+possible when a Scheme program hits an error.  The most immediate
+information about an error is the kind of error that it is -- such as
+``division by zero'' -- and any parameters that the code which signalled
+the error chose explicitly to provide.  This information originates with
+the @code{error} or @code{throw} call (or their C code equivalents, if
+the error is detected by C code) that signals the error, and is passed
+automatically to the handler procedure of the innermost applicable
+@code{catch} or @code{with-throw-handler} expression.
+
+Therefore, to catch errors that occur within a chunk of Scheme code, and
+to intercept basic information about those errors, you need to execute
+that code inside the dynamic context of a @code{catch} or
+@code{with-throw-handler} expression, or the equivalent in C. In Scheme,
+this means you need something like this:
+
+@lisp
+(catch #t
+       (lambda ()
+         ;; Execute the code in which
+         ;; you want to catch errors here.
+         ...)
+       (lambda (key . parameters)
+         ;; Put the code which you want
+         ;; to handle an error here.
+         ...))
+@end lisp
+
+@noindent
+The @code{catch} here can also be @code{with-throw-handler}; see
+@ref{Throw Handlers} for information on the when you might want to use
+@code{with-throw-handler} instead of @code{catch}.
+
+For example, to print out a message and return #f when an error occurs,
+you might use:
+
+@smalllisp
+(define (catch-all thunk)
+  (catch #t
+    thunk
+    (lambda (key . parameters)
+      (format (current-error-port)
+              "Uncaught throw to '~a: ~a\n" key parameters)
+      #f)))
+
+(catch-all
+ (lambda () (error "Not a vegetable: tomato")))
+@print{} Uncaught throw to 'misc-error: (#f ~A (Not a vegetable: tomato) #f)
+@result{} #f
+@end smalllisp
+
+The @code{#t} means that the catch is applicable to all kinds of error.
+If you want to restrict your catch to just one kind of error, you can
+put the symbol for that kind of error instead of @code{#t}. The
+equivalent to this in C would be something like this:
+
+@lisp
+SCM my_body_proc (void *body_data)
+@{
+  /* Execute the code in which
+     you want to catch errors here. */
+  ...
+@}
+
+SCM my_handler_proc (void *handler_data,
+                     SCM key,
+                     SCM parameters)
+@{
+  /* Put the code which you want
+     to handle an error here. */
+  ...
+@}
+
+@{
+  ...
+  scm_c_catch (SCM_BOOL_T,
+               my_body_proc, body_data,
+               my_handler_proc, handler_data,
+               NULL, NULL);
+  ...
+@}
+@end lisp
+
+@noindent
+Again, as with the Scheme version, @code{scm_c_catch} could be replaced
+by @code{scm_c_with_throw_handler}, and @code{SCM_BOOL_T} could instead
+be the symbol for a particular kind of error.
+
+@node Capturing Stacks
+@subsubsection Capturing the full error stack
+
+The other interesting information about an error is the full Scheme
+stack at the point where the error occurred; in other words what
+innermost expression was being evaluated, what was the expression that
+called that one, and so on.  If you want to write your code so that it
+captures and can display this information as well, there are a couple
+important things to understand.
+
+Firstly, the stack at the point of the error needs to be explicitly
+captured by a @code{make-stack} call (or the C equivalent
+@code{scm_make_stack}).  The Guile library does not do this
+``automatically'' for you, so you will need to write code with a
+@code{make-stack} or @code{scm_make_stack} call yourself.  (We emphasise
+this point because some people are misled by the fact that the Guile
+interactive REPL code @emph{does} capture and display the stack
+automatically.  But the Guile interactive REPL is itself a Scheme
+program@footnote{In effect, it is the default program which is run when
+no commands or script file are specified on the Guile command line.}
+running on top of the Guile library, and which uses @code{catch} and
+@code{make-stack} in the way we are about to describe to capture the
+stack when an error occurs.)
+
+And secondly, in order to capture the stack effectively at the point
+where the error occurred, the @code{make-stack} call must be made before
+Guile unwinds the stack back to the location of the prevailing catch
+expression. This means that the @code{make-stack} call must be made
+within the handler of a @code{with-throw-handler} expression, or the
+optional "pre-unwind" handler of a @code{catch}. (For the full story of
+how these alternatives differ from each other, see @ref{Exceptions}. The
+main difference is that @code{catch} terminates the error, whereas
+@code{with-throw-handler} only intercepts it temporarily and then allow
+it to continue propagating up to the next innermost handler.)
+
+So, here are some examples of how to do all this in Scheme and in C.
+For the purpose of these examples we assume that the captured stack
+should be stored in a variable, so that it can be displayed or
+arbitrarily processed later on.  In Scheme:
+
+@lisp
+(let ((captured-stack #f))
+  (catch #t
+         (lambda ()
+           ;; Execute the code in which
+           ;; you want to catch errors here.
+           ...)
+         (lambda (key . parameters)
+           ;; Put the code which you want
+           ;; to handle an error after the
+           ;; stack has been unwound here.
+           ...)
+         (lambda (key . parameters)
+           ;; Capture the stack here:
+           (set! captured-stack (make-stack #t))))
+  ...
+  (if captured-stack
+      (begin
+        ;; Display or process the captured stack.
+        ...))
+  ...)
+@end lisp
+
+@noindent
+And in C:
+
+@lisp
+SCM my_body_proc (void *body_data)
+@{
+  /* Execute the code in which
+     you want to catch errors here. */
+  ...
+@}
+
+SCM my_handler_proc (void *handler_data,
+                     SCM key,
+                     SCM parameters)
+@{
+  /* Put the code which you want
+     to handle an error after the
+     stack has been unwound here. */
+  ...
+@}
+
+SCM my_preunwind_proc (void *handler_data,
+                       SCM key,
+                       SCM parameters)
+@{
+  /* Capture the stack here: */
+  *(SCM *)handler_data = scm_make_stack (SCM_BOOL_T, SCM_EOL);
+@}
+
+@{
+  SCM captured_stack = SCM_BOOL_F;
+  ...
+  scm_c_catch (SCM_BOOL_T,
+               my_body_proc, body_data,
+               my_handler_proc, handler_data,
+               my_preunwind_proc, &captured_stack);
+  ...
+  if (captured_stack != SCM_BOOL_F)
+  @{
+    /* Display or process the captured stack. */
+    ...
+  @}
+  ...
+@}
+@end lisp
+
+Once you have a captured stack, you can interrogate and display its
+details in any way that you want, using the @code{stack-@dots{}} and
+@code{frame-@dots{}} API described in @ref{Stacks} and
+@ref{Frames}.
+
+If you want to print out a backtrace in the same format that the Guile
+REPL does, you can use the @code{display-backtrace} procedure to do so.
+You can also use @code{display-application} to display an individual
+frame in the Guile REPL format.
+
+@node Pre-Unwind Debugging
+@subsubsection Pre-Unwind Debugging
+
+Instead of saving a stack away and waiting for the @code{catch} to
+return, you can handle errors directly, from within the pre-unwind
+handler.
+
+For example, to show a backtrace when an error is thrown, you might want
+to use a procedure like this:
+
+@lisp
+(define (with-backtrace thunk)
+  (with-throw-handler #t
+                      thunk
+                      (lambda args (backtrace))))
+(with-backtrace (lambda () (error "Not a vegetable: tomato")))
+@end lisp
+
+Since we used @code{with-throw-handler} here, we didn't actually catch
+the error. @xref{Throw Handlers}, for more information. However, we did
+print out a context at the time of the error, using the built-in
+procedure, @code{backtrace}.
+
+@deffn {Scheme Procedure} backtrace [highlights]
+@deffnx {C Function} scm_backtrace_with_highlights (highlights)
+@deffnx {C Function} scm_backtrace ()
+Display a backtrace of the current stack to the current output port.  If
+@var{highlights} is given it should be a list; the elements of this list
+will be highlighted wherever they appear in the backtrace.
+@end deffn
+
+The Guile REPL code (in @file{system/repl/repl.scm} and related files)
+uses a @code{catch} with a pre-unwind handler to capture the stack when
+an error occurs in an expression that was typed into the REPL, and debug
+that stack interactively in the context of the error.
+
+These procedures are available for use by user programs, in the
+@code{(system repl error-handling)} module.
+
+@lisp
+(use-modules (system repl error-handling))
+@end lisp
+
+@deffn {Scheme Procedure} call-with-error-handling thunk @
+       [#:on-error on-error='debug] [#:post-error post-error='catch] @
+       [#:pass-keys pass-keys='(quit)] [#:trap-handler trap-handler='debug]
+Call a thunk in a context in which errors are handled.
+
+There are four keyword arguments:
+
+@table @var
+@item on-error
+Specifies what to do before the stack is unwound.
+
+Valid options are @code{debug} (the default), which will enter a
+debugger; @code{pass}, in which case nothing is done, and the exception
+is rethrown; or a procedure, which will be the pre-unwind handler.
+
+@item post-error
+Specifies what to do after the stack is unwound.
+
+Valid options are @code{catch} (the default), which will silently catch
+errors, returning the unspecified value; @code{report}, which prints out
+a description of the error (via @code{display-error}), and then returns
+the unspecified value; or a procedure, which will be the catch handler.
+
+@item trap-handler
+Specifies a trap handler: what to do when a breakpoint is hit.
+
+Valid options are @code{debug}, which will enter the debugger;
+@code{pass}, which does nothing; or @code{disabled}, which disables
+traps entirely.  @xref{Traps}, for more information.
+
+@item pass-keys
+A set of keys to ignore, as a list.
+@end table
+@end deffn
+
+@node Debug Options
+@subsubsection Debug options
+
+The behavior of the @code{backtrace} procedure and of the default error
+handler can be parameterized via the debug options.
+
+@cindex options - debug
+@cindex debug options
+@deffn {Scheme Procedure} debug-options [setting]
+Display the current settings of the debug options.  If @var{setting} is
+omitted, only a short form of the current read options is printed.
+Otherwise if @var{setting} is the symbol @code{help}, a complete options
+description is displayed.
+@end deffn
+
+The set of available options, and their default values, may be had by
+invoking @code{debug-options} at the prompt.
+
+@smallexample
+scheme@@(guile-user)>
+backwards       no      Display backtrace in anti-chronological order.
+width           79      Maximal width of backtrace.
+depth           20      Maximal length of printed backtrace.
+backtrace       yes     Show backtrace on error.
+stack           1048576 Stack size limit (measured in words;
+                        0 = no check). 
+show-file-name  #t      Show file names and line numbers in backtraces
+                        when not `#f'.  A value of `base' displays only
+                        base names, while `#t' displays full names. 
+warn-deprecated no      Warn when deprecated features are used.
+@end smallexample
+
+The boolean options may be toggled with @code{debug-enable} and
+@code{debug-disable}. The non-boolean @code{keywords} option must be set
+using @code{debug-set!}.
+
+@deffn {Scheme Procedure} debug-enable option-name
+@deffnx {Scheme Procedure} debug-disable option-name
+@deffnx {Scheme Syntax} debug-set! option-name value
+Modify the debug options.  @code{debug-enable} should be used with boolean
+options and switches them on, @code{debug-disable} switches them off.
+
+@code{debug-set!} can be used to set an option to a specific value.  Due
+to historical oddities, it is a macro that expects an unquoted option
+name.
+@end deffn
+
+@subsubheading Stack overflow
+
+@cindex overflow, stack
+@cindex stack overflow
+Stack overflow errors are caused by a computation trying to use more
+stack space than has been enabled by the @code{stack} option.  There are
+actually two kinds of stack that can overflow, the C stack and the
+Scheme stack.
+
+Scheme stack overflows can occur if Scheme procedures recurse too far
+deeply. An example would be the following recursive loop:
+
+@lisp
+scheme@@(guile-user)> (let lp () (+ 1 (lp)))
+<unnamed port>:8:17: In procedure vm-run:
+<unnamed port>:8:17: VM: Stack overflow
+@end lisp
+
+The default stack size should allow for about 10000 frames or so, so one
+usually doesn't hit this level of recursion. Unfortunately there is no
+way currently to make a VM with a bigger stack. If you are in this
+unfortunate situation, please file a bug, and in the meantime, rewrite
+your code to be tail-recursive (@pxref{Tail Calls}).
+
+The other limit you might hit would be C stack overflows. If you call a
+primitive procedure which then calls a Scheme procedure in a loop, you
+will consume C stack space. Guile tries to detect excessive consumption
+of C stack space, throwing an error when you have hit 80% of the
+process' available stack (as allocated by the operating system), or 160
+kilowords in the absence of a strict limit.
+
+For example, looping through @code{call-with-vm}, a primitive that calls
+a thunk, gives us the following:
+
+@lisp
+scheme@@(guile-user)> (use-modules (system vm vm))
+scheme@@(guile-user)> (debug-set! stack 10000)
+scheme@@(guile-user)> (let lp () (call-with-vm lp))
+ERROR: In procedure call-with-vm:
+ERROR: Stack overflow
+@end lisp
+
+If you get an error like this, you can either try rewriting your code to
+use less stack space, or increase the maximum stack size.  To increase
+the maximum stack size, use @code{debug-set!}, for example:
+
+@lisp
+(debug-set! stack 200000)
+@end lisp
+
+But of course it's better to have your code operate without so much
+resource consumption, avoiding loops through C trampolines.
+
+
+@node Traps
+@subsection Traps
+
+@cindex Traps
+@cindex VM hooks
+@cindex Breakpoints
+@cindex Trace
+@cindex Tracing
+@cindex Code coverage
+@cindex Profiling
+Guile's virtual machine can be configured to call out at key points to
+arbitrary user-specified procedures.
+
+In principle, these @dfn{hooks} allow 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.
+
+VM hooks are very low-level, though, and so Guile also has a library of
+higher-level @dfn{traps} on top of the VM hooks. A trap is an execution
+condition that, when fulfilled, will fire a handler. For example, Guile
+defines a trap that fires when control reaches a certain source
+location.
+
+Finally, Guile also defines a third level of abstractions: per-thread
+@dfn{trap states}. A trap state exists to give names to traps, and to
+hold on to the set of traps so that they can be enabled, disabled, or
+removed. The trap state infrastructure defines the most useful
+abstractions for most cases. For example, Guile's REPL uses trap state
+functions to set breakpoints and tracepoints.
+
+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.
+
+
+@menu
+* VM Hooks::                Modifying Guile's virtual machine.
+* Trap Interface::          Traps are on or off.
+* Low-Level Traps::         The various kinds of low-level traps.
+* Tracing Traps::           Traps to trace procedure calls and returns.
+* Trap States::             One state (per thread) to bind them.
+* High-Level Traps::        The highest-level trap interface. Use this.
+@end menu
+
+
+@node VM Hooks
+@subsubsection VM Hooks
+
+Everything that runs in Guile runs on its virtual machine, a C program
+that defines a number of operations that Scheme programs can
+perform.
+
+Note that there are multiple VM ``engines'' for Guile. Only some of them
+have support for hooks compiled in. Normally the deal is that you get
+hooks if you are running interactively, and otherwise they are disabled,
+as they do have some overhead (about 10 or 20 percent).
+
+To ensure that you are running with hooks, pass @code{--debug} to Guile
+when running your program, or otherwise use the @code{call-with-vm} and
+@code{set-vm-engine!}  procedures to ensure that you are running in a VM
+with the @code{debug} engine.
+
+To digress, Guile's VM has 6 different hooks (@pxref{Hooks}) that can be
+fired at different times, which may be accessed with the following
+procedures.
+
+The first argument of calls to these hooks is the frame in question.
+@xref{Frames}.  Some hooks may call their procedures with more
+arguments.  Since these hooks may be fired very frequently, Guile does a
+terrible thing: it allocates the frames on the C stack instead of the
+garbage-collected heap.
+
+The upshot here is that the frames are only valid within the dynamic
+extent of the call to the hook. If a hook procedure keeps a reference to
+the frame outside the extent of the hook, bad things will happen.
+
+The interface to hooks is provided by the @code{(system vm vm)} module:
+
+@example
+(use-modules (system vm vm))
+@end example
+
+@noindent
+All of these functions implicitly act on the VM for the current thread
+only.
+
+@deffn {Scheme Procedure} vm-next-hook
+The hook that will be fired before an instruction is retired (and
+executed).
+@end deffn
+
+@deffn {Scheme Procedure} vm-push-continuation-hook
+The hook that will be fired after preparing a new frame. Fires just
+before applying a procedure in a non-tail context, just before the
+corresponding apply-hook.
+@end deffn
+
+@deffn {Scheme Procedure} vm-pop-continuation-hook
+The hook that will be fired before returning from a frame.
+
+This hook fires with a variable number of arguments, corresponding to
+the values that the frame returns to its continuation.
+@end deffn
+
+@deffn {Scheme Procedure} vm-apply-hook
+The hook that will be fired before a procedure is applied. The frame's
+procedure will have already been set to the new procedure.
+
+Note that procedure application is somewhat orthogonal to continuation
+pushes and pops. A non-tail call to a procedure will result first in a
+firing of the push-continuation hook, then this application hook,
+whereas a tail call will run without having fired a push-continuation
+hook.
+@end deffn
+
+@deffn {Scheme Procedure} vm-abort-continuation-hook
+The hook that will be called after aborting to a
+prompt.  @xref{Prompts}.
+
+Like the pop-continuation hook, this hook fires with a variable number
+of arguments, corresponding to the values that returned to the
+continuation.
+@end deffn
+
+@deffn {Scheme Procedure} vm-restore-continuation-hook
+The hook that will be called after restoring an undelimited
+continuation. Unfortunately it's not currently possible to introspect on
+the values that were given to the continuation.
+@end deffn
+
+@cindex VM trace level
+These hooks do impose a performance penalty, if they are on. Obviously,
+the @code{vm-next-hook} has quite an impact, performance-wise. Therefore
+Guile exposes a single, heavy-handed knob to turn hooks on or off, the
+@dfn{VM trace level}. If the trace level is positive, hooks run;
+otherwise they don't.
+
+For convenience, when the VM fires a hook, it does so with the trap
+level temporarily set to 0.  That way the hooks don't fire while you're
+handling a hook.  The trace level is restored to whatever it was once the hook
+procedure finishes.
+
+@deffn {Scheme Procedure} vm-trace-level
+Retrieve the ``trace level'' of the VM. If positive, the trace hooks
+associated with @var{vm} will be run. The initial trace level is 0.
+@end deffn
+
+@deffn {Scheme Procedure} set-vm-trace-level! level
+Set the ``trace level'' of the VM.
+@end deffn
+
+@xref{A Virtual Machine for Guile}, for more information on Guile's
+virtual machine.
+
+@node Trap Interface
+@subsubsection Trap Interface
+
+The capabilities provided by hooks are great, but hooks alone rarely
+correspond to what users want to do.
+
+For example, if a user wants to break when and if control reaches a
+certain source location, how do you do it?  If you install a ``next''
+hook, you get unacceptable overhead for the execution of the entire
+program. It would be possible to install an ``apply'' hook, then if the
+procedure encompasses those source locations, install a ``next'' hook,
+but already you're talking about one concept that might be implemented
+by a varying number of lower-level concepts.
+
+It's best to be clear about things and define one abstraction for all
+such conditions: the @dfn{trap}.
+
+Considering the myriad capabilities offered by the hooks though, there
+is only a minimum of functionality shared by all traps. Guile's current
+take is to reduce this to the absolute minimum, and have the only
+standard interface of a trap be ``turn yourself on'' or ``turn yourself
+off''.
+
+This interface sounds a bit strange, but it is useful to procedurally
+compose higher-level traps from lower-level building blocks. For
+example, Guile defines a trap that calls one handler when control enters
+a procedure, and another when control leaves the procedure. Given that
+trap, one can define a trap that adds to the next-hook only when within
+a given procedure. Building further, one can define a trap that fires
+when control reaches particular instructions within a procedure.
+
+Or of course you can stop at any of these intermediate levels. For
+example, one might only be interested in calls to a given procedure. But
+the point is that a simple enable/disable interface is all the
+commonality that exists between the various kinds of traps, and
+furthermore that such an interface serves to allow ``higher-level''
+traps to be composed from more primitive ones.
+
+Specifically, a trap, in Guile, is a procedure. When a trap is created,
+by convention the trap is enabled; therefore, the procedure that is the
+trap will, when called, disable the trap, and return a procedure that
+will enable the trap, and so on.
+
+Trap procedures take one optional argument: the current frame. (A trap
+may want to add to different sets of hooks depending on the frame that
+is current at enable-time.)
+
+If this all sounds very complicated, it's because it is. Some of it is
+essential, but probably most of it is not. The advantage of using this
+minimal interface is that composability is more lexically apparent than
+when, for example, using a stateful interface based on GOOPS. But
+perhaps this reflects the cognitive limitations of the programmer who
+made the current interface more than anything else.
+
+@node Low-Level Traps
+@subsubsection Low-Level Traps
+
+To summarize the last sections, traps are enabled or disabled, and when
+they are enabled, they add to various VM hooks.
+
+Note, however, that @emph{traps do not increase the VM trace level}. So
+if you create a trap, it will be enabled, but unless something else
+increases the VM's trace level (@pxref{VM Hooks}), the trap will not
+fire.  It turns out that getting the VM trace level right is tricky
+without a global view of what traps are enabled.  @xref{Trap States},
+for Guile's answer to this problem.
+
+Traps are created by calling procedures. Most of these procedures share
+a set of common keyword arguments, so rather than document them
+separately, we discuss them all together here:
+
+@table @code
+@item #:vm
+The VM to instrument. Defaults to the current thread's VM.
+@item #:closure?
+For traps that depend on the current frame's procedure, this argument
+specifies whether to trap on the only the specific procedure given, or
+on any closure that has the given procedure's code. Defaults to
+@code{#f}.
+@item #:current-frame
+For traps that enable more hooks depending on their dynamic context,
+this argument gives the current frame that the trap is running in.
+Defaults to @code{#f}.
+@end table
+
+To have access to these procedures, you'll need to have imported the
+@code{(system vm traps)} module:
+
+@lisp
+(use-modules (system vm traps))
+@end lisp
+
+@deffn {Scheme Procedure} trap-at-procedure-call proc handler @
+       [#:vm] [#:closure?]
+A trap that calls @var{handler} when @var{proc} is applied.
+@end deffn                
+
+@deffn {Scheme Procedure} trap-in-procedure proc @
+       enter-handler exit-handler [#:current-frame] [#:vm] [#:closure?]
+A trap that calls @var{enter-handler} when control enters @var{proc},
+and @var{exit-handler} when control leaves @var{proc}.
+
+Control can enter a procedure via:
+@itemize
+@item
+A procedure call.
+@item
+A return to a procedure's frame on the stack.
+@item
+A continuation returning directly to an application of this procedure.
+@end itemize
+
+Control can leave a procedure via:
+@itemize
+@item
+A normal return from the procedure.
+@item
+An application of another procedure.
+@item
+An invocation of a continuation.
+@item
+An abort.
+@end itemize
+@end deffn
+
+@deffn {Scheme Procedure} trap-instructions-in-procedure proc @
+       next-handler exit-handler [#:current-frame] [#:vm] [#:closure?]
+A trap that calls @var{next-handler} for every instruction executed in
+@var{proc}, and @var{exit-handler} when execution leaves @var{proc}.
+@end deffn
+
+@deffn {Scheme Procedure} trap-at-procedure-ip-in-range proc range @
+       handler [#:current-frame] [#:vm] [#:closure?]
+A trap that calls @var{handler} when execution enters a range of
+instructions in @var{proc}. @var{range} is a simple of pairs,
+@code{((@var{start} . @var{end}) ...)}. The @var{start} addresses are
+inclusive, and @var{end} addresses are exclusive.
+@end deffn
+
+@deffn {Scheme Procedure} trap-at-source-location file user-line handler @
+       [#:current-frame] [#:vm]
+A trap that fires when control reaches a given source location.  The
+@var{user-line} parameter is one-indexed, as a user counts lines,
+instead of zero-indexed, as Guile counts lines.
+@end deffn
+
+@deffn {Scheme Procedure} trap-frame-finish frame @
+       return-handler abort-handler [#:vm]
+A trap that fires when control leaves the given frame. @var{frame}
+should be a live frame in the current continuation. @var{return-handler}
+will be called on a normal return, and @var{abort-handler} on a nonlocal
+exit.
+@end deffn
+
+@deffn {Scheme Procedure} trap-in-dynamic-extent proc @
+       enter-handler return-handler abort-handler [#:vm] [#:closure?]
+A more traditional dynamic-wind trap, which fires @var{enter-handler}
+when control enters @var{proc}, @var{return-handler} on a normal return,
+and @var{abort-handler} on a nonlocal exit.
+
+Note that rewinds are not handled, so there is no rewind handler.
+@end deffn
+
+@deffn {Scheme Procedure} trap-calls-in-dynamic-extent proc @
+       apply-handler return-handler [#:current-frame] [#:vm] [#:closure?]
+A trap that calls @var{apply-handler} every time a procedure is applied,
+and @var{return-handler} for returns, but only during the dynamic extent
+of an application of @var{proc}.
+@end deffn
+
+@deffn {Scheme Procedure} trap-instructions-in-dynamic-extent proc @
+       next-handler [#:current-frame] [#:vm] [#:closure?]
+A trap that calls @var{next-handler} for all retired instructions within
+the dynamic extent of a call to @var{proc}.
+@end deffn
+
+@deffn {Scheme Procedure} trap-calls-to-procedure proc @
+       apply-handler return-handler [#:vm]
+A trap that calls @var{apply-handler} whenever @var{proc} is applied,
+and @var{return-handler} when it returns, but with an additional
+argument, the call depth.
+
+That is to say, the handlers will get two arguments: the frame in
+question, and the call depth (a non-negative integer).
+@end deffn
+
+@deffn {Scheme Procedure} trap-matching-instructions frame-pred handler [#:vm]
+A trap that calls @var{frame-pred} at every instruction, and if
+@var{frame-pred} returns a true value, calls @var{handler} on the
+frame.
+@end deffn
+
+@node Tracing Traps
+@subsubsection Tracing Traps
+
+The @code{(system vm trace)} module defines a number of traps for
+tracing of procedure applications.  When a procedure is @dfn{traced}, it
+means that every call to that procedure is reported to the user during a
+program run.  The idea is that you can mark a collection of procedures
+for tracing, and Guile will subsequently print out a line of the form
+
+@lisp
+|  |  (@var{procedure} @var{args} @dots{})
+@end lisp
+
+whenever a marked procedure is about to be applied to its arguments.
+This can help a programmer determine whether a function is being called
+at the wrong time or with the wrong set of arguments.
+
+In addition, the indentation of the output is useful for demonstrating
+how the traced applications are or are not tail recursive with respect
+to each other.  Thus, a trace of a non-tail recursive factorial
+implementation looks like this:
+
+@lisp
+scheme@@(guile-user)> (define (fact1 n) 
+                       (if (zero? n) 1
+                           (* n (fact1 (1- n)))))
+scheme@@(guile-user)> ,trace (fact1 4)
+trace: (fact1 4)
+trace: |  (fact1 3)
+trace: |  |  (fact1 2)
+trace: |  |  |  (fact1 1)
+trace: |  |  |  |  (fact1 0)
+trace: |  |  |  |  1
+trace: |  |  |  1
+trace: |  |  2
+trace: |  6
+trace: 24
+@end lisp
+
+While a typical tail recursive implementation would look more like this:
+
+@lisp
+scheme@@(guile-user)> (define (facti acc n)
+                       (if (zero? n) acc
+                           (facti (* n acc) (1- n))))
+scheme@@(guile-user)> (define (fact2 n) (facti 1 n))
+scheme@@(guile-user)> ,trace (fact2 4)
+trace: (fact2 4)
+trace: (facti 1 4)
+trace: (facti 4 3)
+trace: (facti 12 2)
+trace: (facti 24 1)
+trace: (facti 24 0)
+trace: 24
+@end lisp
+
+The low-level traps below (@pxref{Low-Level Traps}) share some common
+options:
+
+@table @code
+@item #:width
+The maximum width of trace output. Trace printouts will try not to
+exceed this column, but for highly nested procedure calls, it may be
+unavoidable. Defaults to 80.
+@item #:vm
+The VM on which to add the traps. Defaults to the current thread's VM.
+@item #:prefix
+A string to print out before each trace line. As seen above in the
+examples, defaults to @code{"trace: "}.
+@end table
+
+To have access to these procedures, you'll need to have imported the
+@code{(system vm trace)} module:
+
+@lisp
+(use-modules (system vm trace))
+@end lisp
+
+@deffn {Scheme Procedure} trace-calls-to-procedure proc @
+       [#:width] [#:vm] [#:prefix]
+Print a trace at applications of and returns from @var{proc}.
+@end deffn
+
+@deffn {Scheme Procedure} trace-calls-in-procedure proc @
+       [#:width] [#:vm] [#:prefix]
+Print a trace at all applications and returns within the dynamic extent
+of calls to @var{proc}.
+@end deffn
+
+@deffn {Scheme Procedure} trace-instructions-in-procedure proc [#:width] [#:vm]
+Print a trace at all instructions executed in the dynamic extent of
+calls to @var{proc}.
+@end deffn
+
+In addition, Guile defines a procedure to call a thunk, tracing all
+procedure calls and returns within the thunk.
+
+@deffn {Scheme Procedure} call-with-trace thunk [#:calls?=#t] @
+                          [#:instructions?=#f] @
+                          [#:width=80]
+Call @var{thunk}, tracing all execution within its dynamic extent.
+
+If @var{calls?} is true, Guile will print a brief report at each
+procedure call and return, as given above.
+
+If @var{instructions?} is true, Guile will also print a message each
+time an instruction is executed.  This is a lot of output, but it is
+sometimes useful when doing low-level optimization.
+
+Note that because this procedure manipulates the VM trace level
+directly, it doesn't compose well with traps at the REPL.
+@end deffn
+
+@xref{Profile Commands}, for more information on tracing at the REPL.
+
+@node Trap States
+@subsubsection Trap States
+
+When multiple traps are present in a system, we begin to have a
+bookkeeping problem. How are they named? How does one disable, enable,
+or delete them?
+
+Guile's answer to this is to keep an implicit per-thread @dfn{trap
+state}. The trap state object is not exposed to the user; rather, API
+that works on trap states fetches the current trap state from the
+dynamic environment.
+
+Traps are identified by integers. A trap can be enabled, disabled, or
+removed, and can have an associated user-visible name.
+
+These procedures have their own module:
+
+@lisp
+(use-modules (system vm trap-state))
+@end lisp
+
+@deffn {Scheme Procedure} add-trap! trap name
+Add a trap to the current trap state, associating the given @var{name}
+with it. Returns a fresh trap identifier (an integer).
+
+Note that usually the more specific functions detailed in
+@ref{High-Level Traps} are used in preference to this one.
+@end deffn
+
+@deffn {Scheme Procedure} list-traps
+List the current set of traps, both enabled and disabled. Returns a list
+of integers.
+@end deffn
+
+@deffn {Scheme Procedure} trap-name idx
+Returns the name associated with trap @var{idx}, or @code{#f} if there
+is no such trap.
+@end deffn
+
+@deffn {Scheme Procedure} trap-enabled? idx
+Returns @code{#t} if trap @var{idx} is present and enabled, or @code{#f}
+otherwise.
+@end deffn
+
+@deffn {Scheme Procedure} enable-trap! idx
+Enables trap @var{idx}.
+@end deffn
+
+@deffn {Scheme Procedure} disable-trap! idx
+Disables trap @var{idx}.
+@end deffn
+
+@deffn {Scheme Procedure} delete-trap! idx
+Removes trap @var{idx}, disabling it first, if necessary.
+@end deffn
+
+@node High-Level Traps
+@subsubsection High-Level Traps
+
+The low-level trap API allows one to make traps that call procedures,
+and the trap state API allows one to keep track of what traps are
+there.  But neither of these APIs directly helps you when you want to
+set a breakpoint, because it's unclear what to do when the trap fires.
+Do you enter a debugger, or mail a summary of the situation to your
+great-aunt, or what?
+
+So for the common case in which you just want to install breakpoints,
+and then have them all result in calls to one parameterizable procedure,
+we have the high-level trap interface.
+
+Perhaps we should have started this section with this interface, as it's
+clearly the one most people should use.  But as its capabilities and
+limitations proceed from the lower layers, we felt that the
+character-building exercise of building a mental model might be helpful.
+
+These procedures share a module with trap states:
+
+@lisp
+(use-modules (system vm trap-state))
+@end lisp
+
+@deffn {Scheme Procedure} with-default-trap-handler handler thunk
+Call @var{thunk} in a dynamic context in which @var{handler} is the
+current trap handler.
+
+Additionally, during the execution of @var{thunk}, the VM trace level
+(@pxref{VM Hooks}) is set to the number of enabled traps. This ensures
+that traps will in fact fire.
+
+@var{handler} may be @code{#f}, in which case VM hooks are not enabled
+as they otherwise would be, as there is nothing to handle the traps.
+@end deffn
+
+The trace-level-setting behavior of @code{with-default-trap-handler} is
+one of its more useful aspects, but if you are willing to forgo that,
+and just want to install a global trap handler, there's a function for
+that too:
+
+@deffn {Scheme Procedure} install-trap-handler! handler
+Set the current thread's trap handler to @var{handler}.
+@end deffn
+
+Trap handlers are called when traps installed by procedures from this
+module fire.  The current ``consumer'' of this API is Guile's REPL, but
+one might easily imagine other trap handlers being used to integrate
+with other debugging tools.
+
+@cindex Breakpoints
+@cindex Setting breakpoints
+@deffn {Scheme Procedure} add-trap-at-procedure-call! proc
+Install a trap that will fire when @var{proc} is called.
+
+This is a breakpoint.
+@end deffn
+
+@cindex Tracepoints
+@cindex Setting tracepoints
+@deffn {Scheme Procedure} add-trace-at-procedure-call! proc
+Install a trap that will print a tracing message when @var{proc} is
+called. @xref{Tracing Traps}, for more information.
+
+This is a tracepoint.
+@end deffn
+
+@deffn {Scheme Procedure} add-trap-at-source-location! file user-line
+Install a trap that will fire when control reaches the given source
+location. @var{user-line} is one-indexed, as users count lines, instead
+of zero-indexed, as Guile counts lines.
+
+This is a source breakpoint.
+@end deffn
+
+@deffn {Scheme Procedure} add-ephemeral-trap-at-frame-finish! frame handler
+Install a trap that will call @var{handler} when @var{frame} finishes
+executing. The trap will be removed from the trap state after firing, or
+on nonlocal exit.
+
+This is a finish trap, used to implement the ``finish'' REPL command.
+@end deffn
+
+@deffn {Scheme Procedure} add-ephemeral-stepping-trap! frame handler [#:into?] [#:instruction?]
+Install a trap that will call @var{handler} after stepping to a
+different source line or instruction.  The trap will be removed from the
+trap state after firing, or on nonlocal exit.
+
+If @var{instruction?} is false (the default), the trap will fire when
+control reaches a new source line. Otherwise it will fire when control
+reaches a new instruction.
+
+Additionally, if @var{into?} is false (not the default), the trap will
+only fire for frames at or prior to the given frame. If @var{into?} is
+true (the default), the trap may step into nested procedure
+invocations.
+
+This is a stepping trap, used to implement the ``step'', ``next'',
+``step-instruction'', and ``next-instruction'' REPL commands.
+@end deffn
+
+
+@c Local Variables:
+@c TeX-master: "guile.texi"
+@c End: