guile-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Guile-commits] GNU Guile branch, master, updated. release_1-9-12-160-g6


From: Andy Wingo
Subject: [Guile-commits] GNU Guile branch, master, updated. release_1-9-12-160-g63e36ea
Date: Thu, 07 Oct 2010 21:57:00 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU Guile".

http://git.savannah.gnu.org/cgit/guile.git/commit/?id=63e36ea6da6e8e9599c18a6235617283c4c7832f

The branch, master has been updated
       via  63e36ea6da6e8e9599c18a6235617283c4c7832f (commit)
       via  3b541ca244459492592c65d94d46bf7489da1ce0 (commit)
       via  de03880abeb1e91c5d4dffaaa0d26a5ee4e94e8e (commit)
       via  90729e71055f5c763bbcef500a548bf1786b6743 (commit)
       via  5db7c0bf4ae6266415b464f8e011209e7a7f55fd (commit)
       via  6e069bbfce57357ff279f19b09464b48de43fede (commit)
       via  a43b4d6e1f10e857f3d0cc0af69ba7c29a53b05e (commit)
       via  e7544f39a42ef98126a9f5a65e2257539e1e1f2b (commit)
      from  90966af89581aa059707bc1cf47e034a2a81129a (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 63e36ea6da6e8e9599c18a6235617283c4c7832f
Author: Andy Wingo <address@hidden>
Date:   Fri Oct 8 00:00:16 2010 +0200

    finish traps documentation
    
    * doc/ref/api-debug.texi (Low-Level Traps, Tracing Traps, Trap States):
      Add notes on using modules.
      (High-Level Traps): Combine "Trap Handlers" and "Setting Traps"
      here. Flesh out docs.

commit 3b541ca244459492592c65d94d46bf7489da1ce0
Author: Andy Wingo <address@hidden>
Date:   Thu Oct 7 22:57:07 2010 +0200

    remove old debugging examples from api-debug
    
    * doc/ref/api-debug.texi (Debugging Examples): Remove section, as the
      tracing bits are adequately covered in tracing, and the breakpoints
      and such will get covered in the debugging meta-commands section.

commit de03880abeb1e91c5d4dffaaa0d26a5ee4e94e8e
Author: Andy Wingo <address@hidden>
Date:   Thu Oct 7 22:50:33 2010 +0200

    document trap states
    
    * module/system/vm/trap-state.scm: Export add-trap!.
    
    * doc/ref/api-debug.texi (Trap States): Document.

commit 90729e71055f5c763bbcef500a548bf1786b6743
Author: Andy Wingo <address@hidden>
Date:   Thu Oct 7 22:27:00 2010 +0200

    document tracing traps
    
    * doc/ref/api-debug.texi (Tracing Traps): Document the traps.

commit 5db7c0bf4ae6266415b464f8e011209e7a7f55fd
Author: Andy Wingo <address@hidden>
Date:   Thu Oct 7 22:15:35 2010 +0200

    finish documenting low-level traps, other api-debug.texi fixes
    
    * doc/ref/api-debug.texi (Stack Capture): Rename from "Capturing the
      Stack or Innermost Stack Frame". Move start-stack docs here.
      (Frames): Document accessors for fp, sp, ip, et al.
      (Source Properties): Raise to a subsection.
      (VM Hooks): Add notes about the VM trace level within hook firing.
      (Low-Level Traps): Flesh out.

commit 6e069bbfce57357ff279f19b09464b48de43fede
Author: Andy Wingo <address@hidden>
Date:   Thu Oct 7 13:06:57 2010 +0200

    update traps documentation (unfinished)
    
    * doc/ref/Makefile.am:
    * doc/ref/guile.texi:
    * doc/ref/scheme-debugging.texi: Remove scheme-debugging.texi, which
      only described tracing. Tracing documentation is now in
      api-debugging.
    
    * doc/ref/scheme-using.texi (Evaluating Scheme Code): Remove reference
      to source traps, as that section is going away.
    
    * doc/ref/api-modules.texi (Included Guile Modules): Remove reference to
      Tracing. This section is a little silly, anyway...
    
    * doc/ref/api-evaluation.texi (VM Behaviour): Remove section, it is in
      api-debugging now.
    
    * doc/ref/api-debug.texi (Stacks, Frames): Rename sections from
      "Examining the Stack" and "Examining Stack Frames", respectively.
      (Traps): Update for current API. A big and not-quite-finished update.

commit a43b4d6e1f10e857f3d0cc0af69ba7c29a53b05e
Author: Andy Wingo <address@hidden>
Date:   Thu Oct 7 12:56:43 2010 +0200

    update docs regarding --debug
    
    * doc/ref/scheme-scripts.texi (Invoking Guile): Update docs on --debug.

commit e7544f39a42ef98126a9f5a65e2257539e1e1f2b
Author: Andy Wingo <address@hidden>
Date:   Thu Oct 7 12:55:37 2010 +0200

    rename vm-trace to call-with-trace
    
    * module/system/vm/trace.scm (print-application, print-return): Change
      to add more whitespace, as (ice-9 debug) did.
      (call-with-trace): Rename from vm-trace, and make the vm a keyword
      argument.
    
    * module/system/repl/command.scm: Don't autoload (system vm profile).
      (trace): Update for call-with-trace name change.

-----------------------------------------------------------------------

Summary of changes:
 doc/ref/Makefile.am             |    1 -
 doc/ref/api-debug.texi          | 1662 ++++++++++++---------------------------
 doc/ref/api-evaluation.texi     |   33 -
 doc/ref/api-modules.texi        |    4 -
 doc/ref/guile.texi              |    2 -
 doc/ref/scheme-debugging.texi   |  123 ---
 doc/ref/scheme-scripts.texi     |   16 +-
 doc/ref/scheme-using.texi       |   12 +-
 module/system/repl/command.scm  |    6 +-
 module/system/vm/trace.scm      |   24 +-
 module/system/vm/trap-state.scm |    3 +-
 11 files changed, 548 insertions(+), 1338 deletions(-)
 delete mode 100644 doc/ref/scheme-debugging.texi

diff --git a/doc/ref/Makefile.am b/doc/ref/Makefile.am
index c4dd7e5..b018bc8 100644
--- a/doc/ref/Makefile.am
+++ b/doc/ref/Makefile.am
@@ -62,7 +62,6 @@ guile_TEXINFOS = preface.texi                 \
                 scheme-scripts.texi            \
                 api-overview.texi              \
                 api-deprecated.texi            \
-                scheme-debugging.texi          \
                 scheme-using.texi              \
                 indices.texi                   \
                 script-getopt.texi             \
diff --git a/doc/ref/api-debug.texi b/doc/ref/api-debug.texi
index e4bde0b..709da3f 100644
--- a/doc/ref/api-debug.texi
+++ b/doc/ref/api-debug.texi
@@ -16,9 +16,9 @@ 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::
-* Debugging Examples::
+* Traps::                       Breakpoints, tracepoints, oh my!
 @end menu
 
 @node Evaluation Model
@@ -59,15 +59,13 @@ 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.
-* Starting a New Stack::
+* Stack Capture::               Reifying a continuation.
+* Stacks::                      Accessors for the stack data type.
+* Frames::                      Likewise, accessors for stack frames.
 @end menu
 
address@hidden Capturing the Stack or Innermost Stack Frame
address@hidden Capturing the Stack or Innermost Stack Frame
address@hidden Stack Capture
address@hidden 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
@@ -79,6 +77,9 @@ describes the Scheme stack at that point.
 #<stack 25205a0>
 @end lisp
 
+Use @code{start-stack} to limit the stack extent captured by future
address@hidden calls.
+
 @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
@@ -115,9 +116,17 @@ If the @var{outer_cut_N} of the last pair is missing, it is
 taken as 0.
 @end deffn
 
address@hidden {Scheme Syntax} start-stack id exp
+Evaluate @var{exp} on a new calling stack with identity @var{id}.  If
address@hidden 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.
address@hidden deffn
+
 
address@hidden Examining the Stack
address@hidden Examining the Stack
address@hidden Stacks
address@hidden Stacks
 
 @deffn {Scheme Procedure} stack? obj
 @deffnx {C Function} scm_stack_p (obj)
@@ -153,8 +162,8 @@ backtrace.
 @end deffn
 
 
address@hidden Examining Stack Frames
address@hidden Examining Stack Frames
address@hidden Frames
address@hidden Frames
 
 @deffn {Scheme Procedure} frame? obj
 @deffnx {C Function} scm_frame_p (obj)
@@ -178,6 +187,31 @@ procedure is associated with @var{frame}.
 Return the arguments of @var{frame}.
 @end deffn
 
address@hidden {Scheme Procedure} frame-address frame
address@hidden {Scheme Procedure} frame-instruction-pointer frame
address@hidden {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.
address@hidden deffn
+
address@hidden {Scheme Procedure} frame-dynamic-link frame
address@hidden {Scheme Procedure} frame-return-address frame
address@hidden {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.
address@hidden deffn
+
address@hidden {Scheme Procedure} frame-num-locals frame
address@hidden {Scheme Procedure} frame-local-ref frame i
address@hidden {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.
address@hidden 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
@@ -185,9 +219,14 @@ Display a procedure application @var{frame} to the output 
port
 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
address@hidden Source Properties
address@hidden Source Properties
 
 @cindex source properties
 As Guile reads in Scheme code from file or from standard input, it
@@ -265,18 +304,6 @@ with the new pair.
 @end deffn
 
 
address@hidden Starting a New Stack
address@hidden Starting a New Stack
-
address@hidden {Scheme Syntax} start-stack id exp
-Evaluate @var{exp} on a new calling stack with identity @var{id}.  If
address@hidden 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.
address@hidden deffn
-
-
 @node Programmatic Error Handling
 @subsection Programmatic Error Handling
 
@@ -494,8 +521,8 @@ SCM my_preunwind_proc (void *handler_data,
 
 Once you have a captured stack, you can interrogate and display its
 details in any way that you want, using the @address@hidden and
address@hidden@dots{}} API described in @ref{Examining the Stack} and
address@hidden Stack Frames}.
address@hidden@dots{}} API described in @ref{Stacks} and
address@hidden
 
 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.
@@ -682,1285 +709,618 @@ resource consumption, avoiding loops through C 
trampolines.
 @subsection Traps
 
 @cindex Traps
address@hidden Evaluator trap calls
address@hidden 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. For more information on these
-hooks, and the circumstances under which the VM calls them, see @ref{VM
-Behaviour}.
-
-In principle, these 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. Possible
-applications of this feature include breakpoints, runtime tracing, code
-coverage, and profiling.
-
address@hidden Trap classes
address@hidden 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
address@hidden<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
address@hidden 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.
-
-
address@hidden Actually, this section is bitrotten
+arbitrary user-specified procedures.
 
-Dear reader: the following sections have some great ideas, and some code
-that just needs a few days of massaging to get it to work with the VM
-(as opposed to the old interpreter). Want to help? Yes? Yes!
address@hidden@@gnu.org}, that's where.
+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.
 
address@hidden A Quick Note on Terminology
-
address@hidden 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.
-
address@hidden @bullet
address@hidden
address@hidden Evaluator trap calls
address@hidden 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.
-
address@hidden
address@hidden Trap classes
-``Trap classes'' are self-explanatory.
-
address@hidden
address@hidden 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.
address@hidden itemize
+Finally, Guile also defines a third level of abstractions: per-thread
address@hidden 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.
 
-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''.
+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
-* 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::
+* 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
 
 
address@hidden How to Set a Trap
address@hidden How to Set a Trap
address@hidden VM Hooks
address@hidden VM Hooks
 
address@hidden Setting traps
address@hidden 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
address@hidden
+Everything that runs in Guile runs on its virtual machine, a C program
+that defines a number of operations that Scheme programs can
+perform.
 
-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.
+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).
 
address@hidden
-(install-trap (make <procedure-trap>
-                #:procedure facti
-                #:single-shot #t
-                #:behaviour debug-trap))
address@hidden lisp
-
address@hidden
-Briefly, the elements of this incantation are as follows.  (All of
-these are described more fully in the following subsubsections.)
+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
address@hidden  procedures to ensure that you are running in a VM
+with the @code{debug} engine.
 
address@hidden @bullet
address@hidden
address@hidden<procedure-trap>} is the trap class for trapping on invocation
-of a specific procedure.
+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.
 
address@hidden
address@hidden:procedure facti} says that the specific procedure to trap on for 
this
-trap object is @code{facti}.
+All hooks are called with one argument, the frame in
+question. @xref{Frames}.  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.
 
address@hidden
address@hidden:single-shot #t} says that this trap should only fire on the
address@hidden invocation of @code{facti}, not on all future invocations
-(which is the default if the @code{#:single-shot} option is not
-specified).
+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.
 
address@hidden
address@hidden:behaviour debug-trap} says that the trap infrastructure should
-call the procedure @code{debug-trap} when this trap fires.
+The interface to hooks is provided by the @code{(system vm vm)} module:
 
address@hidden
-Finally, the @code{install-trap} call installs the trap immediately.
address@hidden itemize
address@hidden
+(use-modules (system vm vm))
address@hidden example
 
 @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.
-
address@hidden {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.
address@hidden deffn
-
address@hidden {Generic Function} uninstall-trap trap
-Uninstall the trap object @var{trap}, so that its behaviour will
address@hidden be executed even if the conditions for the trap firing are
-met.
address@hidden deffn
-
-
address@hidden Specifying Trap Behaviour
address@hidden Specifying Trap Behaviour
+The result of calling @code{the-vm} is usually passed as the @var{vm}
+argument to all of these procedures.
 
address@hidden 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
address@hidden:behaviour} option when creating a trap object.
-
address@hidden {Procedure} debug-trap trap-context
-Enter Guile's command line debugger to explore the stack at
address@hidden, and to single-step or continue program execution
-from that point.
address@hidden deffn
-
address@hidden {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
address@hidden and to single-step or continue program execution
-from that point.
address@hidden deffn
-
address@hidden Trace
address@hidden Tracing
address@hidden {Procedure} trace-trap trap-context
-Display trace information to summarize the current @var{trap-context}.
address@hidden deffn
-
address@hidden {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.
address@hidden {Scheme Procedure} vm-next-hook vm
+The hook that will be fired before an instruction is retired (and
+executed).
 @end deffn
 
address@hidden {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''.
address@hidden {Scheme Procedure} vm-push-continuation-hook vm
+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
 
address@hidden
address@hidden and @code{gds-debug-trap} are provided by the modules
address@hidden(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.
-
address@hidden 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:
-
address@hidden
-(define (report-stack-depth trap-context)
-  (display "Stack depth at the trap is: ")
-  (display (tc:depth trap-context))
-  (newline))
address@hidden lisp
-
-
address@hidden Trap Context
address@hidden Trap Context
address@hidden {Scheme Procedure} vm-pop-continuation-hook vm
+The hook that will be fired before returning from a frame.
 
-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)} address@hidden of course any procedures that build on
-these, such as the @code{trace/@dots{}} procedures exported by
address@hidden(ice-9 debugging trace)} (@pxref{Tracing Configuration}).}; the
-most useful of these are as follows.
-
address@hidden {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
address@hidden:error}.
address@hidden deffn
-
address@hidden {Generic Function} tc:return-value trap-context
-When @code{tc:type} gives @code{#:return}, this provides the value
-that is being returned.
+This hook is a bit trickier than the rest, in that there is a particular
+interpretation of the values on the stack. Specifically, the top value
+on the stack is the number of values being returned, and the next
address@hidden values are the actual values being returned, with the last value
+highest on the stack.
 @end deffn
 
address@hidden {Generic Function} tc:stack trap-context
-Provides the stack at the point of the trap (as computed by
address@hidden, but cached so that the lengthy @code{make-stack}
-operation is not performed more than once for the same low level
-trap).
address@hidden deffn
address@hidden {Scheme Procedure} vm-apply-hook vm
+The hook that will be fired before a procedure is applied. The frame's
+procedure will have already been set to the new procedure.
 
address@hidden {Generic Function} tc:frame trap-context
-The innermost frame of the stack at the point of the trap.
+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
 
address@hidden {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.
address@hidden {Scheme Procedure} vm-abort-continuation-hook vm
+The hook that will be called after aborting to a
+prompt. @xref{Prompts}. The stack will be in the same state as for
address@hidden
 @end deffn
 
address@hidden {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.
address@hidden {Scheme Procedure} vm-restore-continuation-hook vm
+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
 
address@hidden 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
address@hidden 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.
+
address@hidden {Scheme Procedure} vm-trace-level vm
+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.
address@hidden deffn
+
address@hidden {Scheme Procedure} set-vm-trace-level! vm level
+Set the ``trace level'' of the VM.
address@hidden deffn
+
address@hidden Virtual Machine for Guile}, for more information on Guile's
+virtual machine.
+
address@hidden Trap Interface
address@hidden 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.
+
address@hidden Low-Level Traps
address@hidden 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:
+
address@hidden @code
address@hidden #:vm
+The VM to instrument. Defaults to the current thread's VM.
address@hidden #: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
address@hidden
address@hidden #: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}.
address@hidden table
 
address@hidden Tracing Examples
address@hidden 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.
-
address@hidden
-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)
address@hidden lisp
-
address@hidden
-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
address@hidden in more detail by using the @code{trace-until-exit}
-behaviour.
+To have access to these procedures, you'll need to have imported the
address@hidden(system vm traps)} module:
 
 @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)
+(use-modules (system vm traps))
 @end lisp
 
address@hidden
-The output in this case shows every step that the evaluator performs
-in evaluating @code{(rev '(a b))}.
-
-
address@hidden Tracing Configuration
address@hidden 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
address@hidden and @code{trace-port}, both exported by the
address@hidden(ice-9 debugging trace)} module.
address@hidden {Scheme Procedure} trap-at-procedure-call proc handler @
+       [#:vm] [#:closure?]
+A trap that calls @var{handler} when @var{proc} is applied.
address@hidden deffn                
 
address@hidden {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.
address@hidden deffn
-
address@hidden {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}.
address@hidden deffn
address@hidden {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}.
 
address@hidden
-The @code{(ice-9 debugging trace)} module exports a set of arg-proc
-procedures to cover most common needs, with names beginning
address@hidden/}.  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.
+Control can enter a procedure via:
address@hidden
address@hidden
+A procedure call.
address@hidden
+A return to a procedure's frame on the stack.
address@hidden
+A continuation returning directly to an application of this procedure.
address@hidden itemize
 
address@hidden {Procedure} trace/pid trap-context
-An arg-proc that returns the current process ID.
+Control can leave a procedure via:
address@hidden
address@hidden
+A normal return from the procedure.
address@hidden
+An application of another procedure.
address@hidden
+An invocation of a continuation.
address@hidden
+An abort.
address@hidden itemize
 @end deffn
 
address@hidden {Procedure} trace/stack-id trap-context
-An arg-proc that returns the stack ID of the stack in which the
-current trap occurred.
address@hidden {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
address@hidden, and @var{exit-handler} when execution leaves @var{proc}.
 @end deffn
 
address@hidden {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.
address@hidden {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,
address@hidden((@var{start} . @var{end}) ...)}. The @var{start} addresses are
+inclusive, and @var{end} addresses are exclusive.
 @end deffn
 
address@hidden {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.
address@hidden {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
address@hidden parameter is one-indexed, as a user counts lines,
+instead of zero-indexed, as Guile counts lines.
 @end deffn
 
address@hidden {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"}.
address@hidden {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
 
address@hidden {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.
address@hidden deffn
address@hidden {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.
 
address@hidden {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.
+Note that rewinds are not handled, so there is no rewind handler.
 @end deffn
 
address@hidden {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.
address@hidden {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
 
address@hidden {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.
address@hidden {Scheme Procedure} trap-instructions-in-dynamic-extent proc @
+       next-handler [#:current-frame] [#:vm] [#:closure?]
+A trap that calls @var{next-handler} for all retired intructions within
+the dynamic extent of a call to @var{proc}.
 @end deffn
 
address@hidden {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,
address@hidden"EVA"} for an evaluation, @code{"RET"} for an exit trap, or
address@hidden"ERR"} for an error (pseudo-)trap.
address@hidden deffn
address@hidden {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.
 
address@hidden {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.
+That is to say, the handlers will get two arguments: the frame in
+question, and the call depth (a non-negative integer).
 @end deffn
 
address@hidden {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.
address@hidden {Scheme Procedure} trap-matching-instructions frame-pred handler 
[#:vm]
+A trap that calls @var{frame-pred} at every instruction, and if
address@hidden returns a true value, calls @var{handler} on the
+frame.
 @end deffn
 
address@hidden
address@hidden/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:
-
address@hidden
-(set-trace-layout "|~3@@a: ~a\n" trace/stack-real-depth trace/info)
address@hidden lisp
-
address@hidden
-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:
-
address@hidden
-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)
address@hidden lisp
-
-
address@hidden Tracing and (ice-9 debug)
address@hidden 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.
address@hidden Tracing Traps
address@hidden Tracing Traps
 
address@hidden @bullet
address@hidden
-The @code{(ice-9 debug)} trace gives a nice pictorial view of changes
-in stack depth, by using indentation like this:
+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
-[fact1 4]
-|  [fact1 3]
-|  |  [fact1 2]
-|  |  |  [fact1 1]
-|  |  |  |  [fact1 0]
-|  |  |  |  1
-|  |  |  1
-|  |  2
-|  6
-24
+|  |  (@var{procedure} @var{args} @dots{})
 @end lisp
 
-However its output can @emph{only} show the information seen here,
-which corresponds to @code{(ice-9 debugging trace)}'s
address@hidden/info} procedure; it cannot be configured to show other
-pieces of information about the trap context in the way that the
address@hidden(ice-9 debugging trace)} implementation can.
-
address@hidden
-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.
address@hidden itemize
-
-It isn't currently possible to use both @code{(ice-9 debug)} trace and
address@hidden(ice-9 debugging trace)} in the same Guile session, because
-their settings of the low level trap options conflict with each other.
-
+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.
 
address@hidden Traps Installing More Traps
address@hidden 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 address@hidden 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.
+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
-(define (at-exit trap-context behaviour)
-  (install-trap (make <exit-trap>
-                 #:depth (tc:depth trap-context)
-                 #:single-shot #t
-                 #:behaviour behaviour)))
+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
 
-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.
+While a typical tail recursive implementation would look more like this:
 
 @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))
+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:
+
address@hidden @code
address@hidden #: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.
address@hidden #:vm
+The VM on which to add the traps. Defaults to the current thread's VM.
address@hidden #:prefix
+A string to print out before each trace line. As seen above in the
+examples, defaults to @code{"trace: "}.
address@hidden table
 
address@hidden Common Trap Options
address@hidden 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:
+To have access to these procedures, you'll need to have imported the
address@hidden(system vm trace)} module:
 
 @lisp
-(make <@var{trap-class}>
-  #:@var{option-keyword} @var{setting}
-  @dots{})
+(use-modules (system vm trace))
 @end lisp
 
-The following common options are provided by the base class
address@hidden<trap>}, and so can be specified for any kind of trap.
-
address@hidden {Class} <trap>
-Base class for trap objects.
address@hidden deffn
-
address@hidden {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}.)
address@hidden deffn
-
address@hidden {Trap Option} #:skip-count count
-A count of valid (after @code{#:condition} processing) firings of this
-trap to skip.  (Default value 0.)
address@hidden deffn
-
address@hidden {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}.)
address@hidden {Scheme Procedure} trace-calls-to-procedure proc @
+       [#:width] [#:vm] [#:prefix]
+Print a trace at applications of and returns from @var{proc}.
 @end deffn
 
address@hidden {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{'()}.)
address@hidden {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
 
address@hidden {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}.)
address@hidden {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.
 
address@hidden Procedure Traps
address@hidden Procedure Traps
address@hidden {Scheme Procedure} call-with-trace thunk  #:key (calls? #t) 
(instructions? #f) (width 80) (vm (the-vm))
+Call @var{thunk}, tracing all execution within its dynamic extent.
 
-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.
+If @var{calls?} is true, Guile will print a brief report at each
+procedure call and return, as given above.
 
address@hidden {Class} <procedure-trap>
-Class for traps triggered by application of a specified procedure.
address@hidden deffn
+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.
 
address@hidden {Trap Option} #:procedure procedure
-Specifies the procedure to trap on.
+Note that because this procedure manipulates the VM trace level
+directly, it doesn't compose well with traps at the REPL.
 @end deffn
 
address@hidden
-Example:
-
address@hidden
-(install-trap (make <procedure-trap>
-                #:procedure my-proc
-                #:behaviour (list trace-trap
-                                  trace-until-exit)))
address@hidden lisp
-
address@hidden Commands}, for more information on tracing at the REPL.
 
address@hidden Exit Traps
address@hidden Exit Traps
address@hidden Trap States
address@hidden Trap States
 
-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.
+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?
 
address@hidden {Class} <exit-trap>
-Class for traps triggered by exit past a specified stack depth.
address@hidden deffn
+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.
 
address@hidden {Trap Option} #:depth depth
-Specifies the reference depth for the trap.
address@hidden deffn
+Traps identified by integers. A trap can be enabled, disabled, or
+removed, and can have an associated user-visible name.
 
address@hidden
-Example:
+These procedures have their own module:
 
 @lisp
-(define (trace-at-exit trap-context)
-  (install-trap (make <exit-trap>
-                 #:depth (tc:depth trap-context)
-                 #:single-shot #t
-                 #:behaviour trace-trap)))
+(use-modules (system vm trap-state))
 @end lisp
 
address@hidden
-(This is the actual definition of the @code{trace-at-exit} behaviour.)
-
-
address@hidden Entry Traps
address@hidden Entry Traps
address@hidden {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).
 
-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
address@hidden next frame entry.
-
address@hidden {Class} <entry-trap>
-Class for traps triggered by any stack frame entry.
+Note that usually the more specific functions detailed in
address@hidden Traps} are used in preference to this one.
 @end deffn
 
address@hidden
-Example:
-
address@hidden
-(install-trap (make <entry-trap>
-               #:skip-count 5
-               #:behaviour gds-debug-trap))
address@hidden lisp
-
-
address@hidden Apply Traps
address@hidden 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.
-
address@hidden {Class} <apply-trap>
-Class for traps triggered by any procedure application.
address@hidden {Scheme Procedure} list-traps
+List the current set of traps, both enabled and disabled. Returns a list
+of integers.
 @end deffn
 
address@hidden
-Example:
-
address@hidden
-(install-trap (make <apply-trap>
-               #:condition my-condition
-               #:behaviour gds-debug-trap))
address@hidden lisp
-
-
address@hidden Step Traps
address@hidden 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
address@hidden 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
address@hidden<step-trap>} class are such as to require the introduction of
-the strange-looking @code{#:exit-depth} option, for the following
-reasons.
-
address@hidden @bullet
address@hidden
-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.
-
address@hidden
-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.
-
address@hidden
-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}.
address@hidden itemize
-
address@hidden
-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.
-
address@hidden {Class} <step-trap>
-Class for single-stepping traps.
address@hidden {Scheme Procedure} trap-name idx
+Returns the name associated with trap @var{idx}, or @code{#f} if there
+is no such trap.
 @end deffn
 
address@hidden {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}.)
address@hidden {Scheme Procedure} trap-enabled? idx
+Returns @code{#t} if trap @var{idx} is present and enabled, or @code{#f}
+otherwise.
 @end deffn
 
address@hidden {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}.)
address@hidden {Scheme Procedure} enable-trap! idx
+Enables trap @var{idx}.
 @end deffn
 
address@hidden
-Example:
-
address@hidden
-(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))
address@hidden lisp
-
-
address@hidden Source Traps
address@hidden 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.
-
address@hidden {Class} <source-trap>
-Class for traps triggered by evaluation of a specific Scheme
-expression.
address@hidden {Scheme Procedure} disable-trap! idx
+Disables trap @var{idx}.
 @end deffn
 
address@hidden {Trap Option} #:expression expr
-Specifies the Scheme expression to trap on.
address@hidden {Scheme Procedure} delete-trap! idx
+Removes trap @var{idx}, disabling it first, if necessary.
 @end deffn
 
address@hidden
-Example:
-
address@hidden
-(display "Enter an expression: ")
-(let ((x (read)))
-  (install-trap (make <source-trap>
-                  #:expression x
-                  #:behaviour (list trace-trap
-                                    trace-at-exit)))
-  (primitive-eval x))
address@hidden
-Enter an expression: (+ 1 2 3 4 5 6)
-|  3: (+ 1 2 3 4 5 6)
-|  3: =>21
-21
address@hidden lisp
address@hidden High-Level Traps
address@hidden High-Level Traps
 
-The key point here is that the expression specified by the
address@hidden: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 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?
 
-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:
+So for the common case in which you just want to install breakpoints,
+and then have them all result in calls one parameterizable procedure, we
+have the high-level trap interface.
 
address@hidden
-(define (fact1 n)
-  (if (= n 0)
-      1
-      (* n (fact1 (- n 1)))))
address@hidden lisp
+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 could be useful.
 
address@hidden
-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:
+These procedures share a module with trap states:
 
 @lisp
-(define (fact1 n)
-  (if (trap-here (= n 0) #:behaviour debug-trap)
-      1
-      (* n (fact1 (- n 1)))))
+(use-modules (system vm trap-state))
 @end lisp
 
address@hidden {Macro} trap-here expression . trap-options
-Install a source trap with options @var{trap-options} on
address@hidden, then return with the whole call transformed to
address@hidden(begin @var{expression})}.
address@hidden deffn
-
-Note that if the @code{trap-here} incantation is removed, and
address@hidden 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.
-
address@hidden {Scheme Procedure} with-default-trap-handler handler thunk
+Call @var{thunk} in a dynamic context in which @var{handler} is the
+current trap handler.
 
address@hidden Location Traps
address@hidden Location Traps
+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.
 
-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.
-
address@hidden {Class} <location-trap>
-Class for traps triggered by evaluation of code at a specific source
-location.
address@hidden deffn
-
address@hidden {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.
address@hidden 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
 
address@hidden {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.
address@hidden 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:
 
address@hidden {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.
address@hidden {Scheme Procedure} install-trap-handler! handler
+Set the current thread's trap handler to @var{handler}.
 @end deffn
 
address@hidden
-Here is an example, which matches the @code{(facti (- n 1) (* a n))}
-expression in @file{ice-9/debugging/example-fns.scm}:
-
address@hidden
-(install-trap (make <location-trap>
-                #:file-regexp "example-fns.scm"
-                #:line 11
-                #:column 6
-                #:behaviour gds-debug-trap))
address@hidden lisp
-
-
address@hidden Trap Shorthands
address@hidden 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.
-
address@hidden
-(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))))
address@hidden 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.
+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.
 
address@hidden Breakpoints
address@hidden Setting breakpoints
address@hidden {Scheme Procedure} add-trap-at-procedure-call! proc
+Install a trap that will fire when @var{proc} is called.
 
address@hidden Trap Utilities
address@hidden Trap Utilities
-
address@hidden 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}
address@hidden 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}.
-
address@hidden {Variable} all-traps
-Weak value hash table containing all known trap objects.
address@hidden deffn
-
address@hidden {Procedure} list-traps
-Print a description of all known trap objects.
+This is a breakpoint.
 @end deffn
 
-The following example shows a single trap that traces applications of
-the procedure @code{facti}.
-
address@hidden
-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)>
address@hidden 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.
-
address@hidden
-(slot-set! (get-trap 1) 'behaviour (list debug-trap))
address@hidden lisp
address@hidden Tracepoints
address@hidden Setting tracepoints
address@hidden {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.
 
address@hidden {Procedure} get-trap number
-Return the trap object with the specified @var{number}, or @code{#f}
-if there isn't one.
+This is a tracepoint.
 @end deffn
 
address@hidden {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.
 
address@hidden Debugging Examples
address@hidden Debugging Examples
-
-Here we present some examples of what you can do with the debugging
-facilities just described.
-
address@hidden
-* Single Stepping through a Procedure's Code::
-* Profiling or Tracing a Procedure's Code::
address@hidden menu
-
-
address@hidden Single Stepping through a Procedure's Code
address@hidden 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 debugger)}.
-
-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}.
-
address@hidden
-$ /usr/bin/guile -q
-guile> (use-modules (ice-9 debugger)
-                    (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 hi!))
-debug> info frame
-Stack frame: 3
-This frame is an evaluation.
-The expression being evaluated is:
-matrix.scm:4:3:
-  (let ((x 1)) (quote hi!))
-debug> next
-Frame 3 at matrix.scm:5:21
-        (quote hi!)
-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 hi!)
-debug> quit
-hi!
-guile> 
address@hidden lisp
-
-Or you can use Guile's Emacs interface (GDS), by using the module
address@hidden(ice-9 gds-client)} instead of @code{(ice-9 debugger)} 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.
-
-
address@hidden Profiling or Tracing a Procedure's Code
address@hidden 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
address@hidden and @code{trace-until-exit} behaviours provided by
-the @code{(ice-9 debugging trace)} module.
+This is a source breakpoint.
address@hidden deffn
 
address@hidden
-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 hi!)))
-|  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 hi!))
-|  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 hi!))
-hi!
-guile> (do-main 4)
-|  2: [mkmatrix]
-|  2: (letrec ((yy 23)) (let* ((x 1)) (quote hi!)))
-|  2: (let* ((x 1)) (quote hi!))
-|  2: (quote hi!)
-|  2: =>hi!
-hi!
-guile> 
address@hidden lisp
address@hidden {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 example shows the default configuration for how each line of trace
-output is formatted, which is:
+This is a finish trap, used to implement the ``finish'' REPL command.
address@hidden deffn
 
address@hidden
address@hidden
-the character @code{|}, a visual clue that the line is a line of trace
-output, followed by
address@hidden {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.
 
address@hidden
-a number indicating the real evaluator stack depth (where ``real'' means
-not counting tail-calls), followed by
+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.
 
address@hidden
-a summary of the expression being evaluated (@code{(@dots{})}), the
-procedure being called (@address@hidden), or the value being returned
-from an evaluation or procedure call (@code{=>@dots{}}).
address@hidden itemize
+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.
 
address@hidden
-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.
+This is a stepping trap, used to implement the ``step'', ``next'',
+``step-instruction'', and ``next-instruction'' REPL commands.
address@hidden deffn
 
address@hidden
-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 hi!)))
-|  matrix.scm:3:2: (let* ((x 1)) (quote hi!))
-|  matrix.scm:4:4: (quote hi!)
-|  matrix.scm:4:4: =>hi!
-hi!
-guile> 
address@hidden lisp
 
 @c Local Variables:
 @c TeX-master: "guile.texi"
diff --git a/doc/ref/api-evaluation.texi b/doc/ref/api-evaluation.texi
index a050a79..4087598 100644
--- a/doc/ref/api-evaluation.texi
+++ b/doc/ref/api-evaluation.texi
@@ -19,7 +19,6 @@ loading, evaluating, and compiling Scheme code at run time.
 * Loading::                     Loading Scheme code from file.
 * Character Encoding of Source Files:: Loading non-ASCII Scheme code from file.
 * Delayed Evaluation::          Postponing evaluation until it is needed.
-* VM Behaviour::                Modifying Guile's virtual machine.
 @end menu
 
 
@@ -868,38 +867,6 @@ value.
 @end deffn
 
 
address@hidden VM Behaviour
address@hidden VM Behaviour
-
-Like the procedures from the previous section that operate on the
-evaluator, there are also procedures to modify the behavior of a
-virtual machine.
-
-The most useful thing that a user can do is to add to one of the
-virtual machine's predefined hooks:
-
address@hidden {Scheme Procedure} vm-next-hook vm
address@hidden {Scheme Procedure} vm-apply-hook vm
address@hidden {Scheme Procedure} vm-push-continuation-hook vm
address@hidden {Scheme Procedure} vm-pop-continuation-hook vm
address@hidden {Scheme Procedure} vm-abort-continuation-hook vm
address@hidden {Scheme Procedure} vm-restore-continuation-hook vm
-Accessors to a virtual machine's hooks. Usually you pass @code{(the-vm)}
-as the @var{vm}.
address@hidden deffn
-
address@hidden {Scheme Procedure} vm-trace-level vm
-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.
address@hidden deffn
-
address@hidden {Scheme Procedure} set-vm-trace-level! vm level
-Set the ``trace level'' of the VM.
address@hidden deffn
-
address@hidden Virtual Machine for Guile}, for more information on Guile's
-virtual machine.
-
 @c Local Variables:
 @c TeX-master: "guile.texi"
 @c End:
diff --git a/doc/ref/api-modules.texi b/doc/ref/api-modules.texi
index b412dbe..790cca6 100644
--- a/doc/ref/api-modules.texi
+++ b/doc/ref/api-modules.texi
@@ -577,10 +577,6 @@ to the entries in this manual which describe them in more 
detail:
 boot-9 is Guile's initialization module, and it is always loaded when
 Guile starts up.
 
address@hidden (ice-9 debug)
-Mikael Djurfeldt's source-level debugging support for Guile
-(@pxref{Tracing}).
-
 @item (ice-9 expect)
 Actions based on matching input from a port (@pxref{Expect}).
 
diff --git a/doc/ref/guile.texi b/doc/ref/guile.texi
index 80854ce..31f3014 100644
--- a/doc/ref/guile.texi
+++ b/doc/ref/guile.texi
@@ -360,7 +360,6 @@ available through both Scheme and C interfaces.
 * Expect::                     Controlling interactive programs with Guile.
 * sxml-match::                  Pattern matching of SXML.
 * The Scheme shell (scsh)::     Using scsh interfaces in Guile.
-* Tracing::                     Tracing program execution.
 @end menu
 
 @include slib.texi
@@ -377,7 +376,6 @@ available through both Scheme and C interfaces.
 @include sxml-match.texi
 
 @include scsh.texi
address@hidden scheme-debugging.texi
 
 @node Standard Library
 @chapter Standard Library
diff --git a/doc/ref/scheme-debugging.texi b/doc/ref/scheme-debugging.texi
deleted file mode 100644
index dd49dd3..0000000
--- a/doc/ref/scheme-debugging.texi
+++ /dev/null
@@ -1,123 +0,0 @@
address@hidden -*-texinfo-*-
address@hidden This is part of the GNU Guile Reference Manual.
address@hidden Copyright (C)  1996, 1997, 2000, 2001, 2002, 2003, 2004, 2006
address@hidden   Free Software Foundation, Inc.
address@hidden See the file guile.texi for copying conditions.
-
address@hidden Tracing
address@hidden Tracing
-
-The @code{(ice-9 debug)} module implements 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
-
address@hidden
-|  |  address@hidden @var{args} @dots{}]
address@hidden 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:
-
address@hidden
-[fact1 4]
-|  [fact1 3]
-|  |  [fact1 2]
-|  |  |  [fact1 1]
-|  |  |  |  [fact1 0]
-|  |  |  |  1
-|  |  |  1
-|  |  2
-|  6
-24
address@hidden lisp
-
-While a typical tail recursive implementation would look more like this:
-
address@hidden
-[fact2 4]
-[facti 1 4]
-[facti 4 3]
-[facti 12 2]
-[facti 24 1]
-[facti 24 0]
-24
address@hidden lisp
-
address@hidden {Scheme Procedure} trace procedure
-Enable tracing for @code{procedure}.  While a program is being run,
-Guile will print a brief report at each call to a traced procedure,
-advising the user which procedure was called and the arguments that were
-passed to it.
address@hidden deffn
-
address@hidden {Scheme Procedure} untrace procedure
-Disable tracing for @code{procedure}.
address@hidden deffn
-
-Here is another example:
-
address@hidden
-(define (rev ls)
-  (if (null? ls)
-      '()
-      (append (rev (cdr ls))
-              (cons (car ls) '())))) @result{} rev
-
-(trace rev) @result{} (rev)
-
-(rev '(a b c d e))
address@hidden [rev (a b c d e)]
-   |  [rev (b c d e)]
-   |  |  [rev (c d e)]
-   |  |  |  [rev (d e)]
-   |  |  |  |  [rev (e)]
-   |  |  |  |  |  [rev ()]
-   |  |  |  |  |  ()
-   |  |  |  |  (e)
-   |  |  |  (e d)
-   |  |  (e d c)
-   |  (e d c b)
-   (e d c b a)
-   (e d c b a)
address@hidden lisp
-
-Note the way Guile indents the output, illustrating the depth of
-execution at each procedure call.  This can be used to demonstrate, for
-example, that Guile implements self-tail-recursion properly:
- 
address@hidden
-(define (rev ls sl)
-  (if (null? ls)
-      sl
-      (rev (cdr ls)
-           (cons (car ls) sl)))) @result{} rev
- 
-(trace rev) @result{} (rev)
- 
-(rev '(a b c d e) '())
address@hidden [rev (a b c d e) ()]
-   [rev (b c d e) (a)]
-   [rev (c d e) (b a)]
-   [rev (d e) (c b a)]
-   [rev (e) (d c b a)]
-   [rev () (e d c b a)]
-   (e d c b a)
-   (e d c b a)
address@hidden lisp
- 
-Since the tail call is effectively optimized to a @code{goto} statement,
-there is no need for Guile to create a new stack frame for each
-iteration.  Tracing reveals this optimization in operation.
-
-
address@hidden Local Variables:
address@hidden TeX-master: "guile.texi"
address@hidden End:
diff --git a/doc/ref/scheme-scripts.texi b/doc/ref/scheme-scripts.texi
index fcb22a6..8d47746 100644
--- a/doc/ref/scheme-scripts.texi
+++ b/doc/ref/scheme-scripts.texi
@@ -174,15 +174,19 @@ guile --use-srfi=8,13
 @end example
 
 @item --debug
-Start with the debugging evaluator and enable backtraces.  Using the
-debugging evaluator will give you better error messages but it will
-slow down execution.  By default, the debugging evaluator is only used
-when entering an interactive session.  When executing a script with
address@hidden or @code{-c}, the normal, faster evaluator is used by default.
+Start with the debugging virtual machine engine.  Using the debugging VM
+will enable support for VM hooks, which are needed for tracing,
+breakpoints, and accurate call counts when profiling.  The debugging VM
+is slower than the regular VM, though, by about 10 percent.  @xref{VM
+Hooks}, for more information.
+
+By default, the debugging VM engine is only used when entering an
+interactive session.  When executing a script with @code{-s} or
address@hidden, the normal, faster VM is used by default.
 
 @vnew{1.8}
 @item --no-debug
-Do not use the debugging evaluator, even when entering an interactive
+Do not use the debugging VM engine, even when entering an interactive
 session.
 
 @item address@hidden, }--help
diff --git a/doc/ref/scheme-using.texi b/doc/ref/scheme-using.texi
index f6c2136..e9cff76 100644
--- a/doc/ref/scheme-using.texi
+++ b/doc/ref/scheme-using.texi
@@ -1036,13 +1036,11 @@ region contains a balanced expression, or try to expand 
the region so
 that it does; it uses the region exactly as it is.
 @end table
 
-If you type @kbd{C-u} before one of these commands, GDS will
-immediately pop up a Scheme stack buffer, showing the requested
-evaluation, so that you can single step through it.  (This is achieved
-by setting a @code{<source-trap>} trap at the start of the requested
-evaluation; see @ref{Source Traps} for more on how those work.)  The
-Scheme stack display, and the options for continuing through the code,
-are described in the next two sections.
+If you type @kbd{C-u} before one of these commands, GDS will immediately
+pop up a Scheme stack buffer, showing the requested evaluation, so that
+you can single step through it.  The Scheme stack display, and the
+options for continuing through the code, are described in the next two
+sections.
 
 
 @node Displaying the Scheme Stack
diff --git a/module/system/repl/command.scm b/module/system/repl/command.scm
index fce2324..4441ef0 100644
--- a/module/system/repl/command.scm
+++ b/module/system/repl/command.scm
@@ -31,8 +31,7 @@
   #:use-module (system vm vm)
   #:use-module ((system vm frame) #:select (frame-return-values))
   #:autoload (system base language) (lookup-language language-reader)
-  #:autoload (system vm trace) (vm-trace)
-  #:autoload (system vm profile) (vm-profile)
+  #:autoload (system vm trace) (call-with-trace)
   #:use-module (ice-9 format)
   #:use-module (ice-9 session)
   #:use-module (ice-9 documentation)
@@ -451,8 +450,7 @@ Profile execution."
   "trace EXP
 Trace execution."
   ;; FIXME: doc options, or somehow deal with them better
-  (apply vm-trace
-         (the-vm)
+  (apply call-with-trace
          (repl-prepare-eval-thunk repl (repl-parse repl form))
          opts))
 
diff --git a/module/system/vm/trace.scm b/module/system/vm/trace.scm
index 138d364..9b91461 100644
--- a/module/system/vm/trace.scm
+++ b/module/system/vm/trace.scm
@@ -31,15 +31,19 @@
   #:export (trace-calls-in-procedure
             trace-calls-to-procedure
             trace-instructions-in-procedure
-            vm-trace))
+            call-with-trace))
 
 ;; FIXME: this constant needs to go in system vm objcode
 (define *objcode-header-len* 8)
 
 (define (print-application frame depth width prefix)
   (format (current-error-port) "~a~a~v:@y\n"
-          prefix (make-string depth #\|)
-          (max (- width depth) 1)
+          prefix
+          (let lp ((depth depth) (s ""))
+            (if (zero? depth)
+                s
+                (lp (1- depth) (string-append "|  " s))))
+          (max (- width (* 3 depth)) 1)
           (frame-call-representation frame)))
 
 (define (print-return frame depth width prefix)
@@ -48,13 +52,21 @@
     (cond
      ((= nvalues 1)
       (format (current-error-port) "~a~a~v:@y\n"
-              prefix (make-string depth #\|)
+              prefix
+              (let lp ((depth depth) (s ""))
+                (if (zero? depth)
+                    s
+                    (lp (1- depth) (string-append "|  " s))))
               width (frame-local-ref frame (- len 2))))
      (else
       ;; this should work, but there appears to be a bug
       ;; "~a~d values:~:{ ~v:@y~}\n"
       (format (current-error-port) "~a ~a~d values:~{ ~a~}\n"
-              prefix (make-string depth #\|)
+              prefix
+              (let lp ((depth depth) (s ""))
+                (if (zero? depth)
+                    s
+                    (lp (1- depth) (string-append "|  " s))))
               nvalues
               (map (lambda (val)
                      (format #f "~v:@y" width val))
@@ -92,7 +104,7 @@
 ;; Note that because this procedure manipulates the VM trace level
 ;; directly, it doesn't compose well with traps at the REPL.
 ;;
-(define* (vm-trace vm thunk #:key (calls? #t) (instructions? #f) (width 80))
+(define* (call-with-trace thunk #:key (calls? #t) (instructions? #f) (width 
80) (vm (the-vm)))
   (let ((call-trap #f)
         (inst-trap #f))
     (dynamic-wind
diff --git a/module/system/vm/trap-state.scm b/module/system/vm/trap-state.scm
index e9a2ad8..435039a 100644
--- a/module/system/vm/trap-state.scm
+++ b/module/system/vm/trap-state.scm
@@ -28,7 +28,8 @@
   #:use-module (system vm trace)
   #:use-module (system vm frame)
   #:use-module (system vm program)
-  #:export (list-traps
+  #:export (add-trap!
+            list-traps
             trap-enabled?
             trap-name
             enable-trap!


hooks/post-receive
-- 
GNU Guile



reply via email to

[Prev in Thread] Current Thread [Next in Thread]