summaryrefslogtreecommitdiff
path: root/doc/ref/api-debug.texi
diff options
context:
space:
mode:
authorAndy Wingo <wingo@pobox.com>2010-10-07 22:15:35 +0200
committerAndy Wingo <wingo@pobox.com>2010-10-07 22:15:35 +0200
commit5db7c0bf4ae6266415b464f8e011209e7a7f55fd (patch)
tree714294da2f357f22e92f49092b172618e6742a9b /doc/ref/api-debug.texi
parent6e069bbfce57357ff279f19b09464b48de43fede (diff)
downloadguile-5db7c0bf4ae6266415b464f8e011209e7a7f55fd.tar.gz
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.
Diffstat (limited to 'doc/ref/api-debug.texi')
-rw-r--r--doc/ref/api-debug.texi219
1 files changed, 149 insertions, 70 deletions
diff --git a/doc/ref/api-debug.texi b/doc/ref/api-debug.texi
index 6cacce978..f6342b021 100644
--- a/doc/ref/api-debug.texi
+++ b/doc/ref/api-debug.texi
@@ -16,6 +16,7 @@ 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::
@@ -59,15 +60,13 @@ the program's state at that point by inspecting the stack and its
frames.
@menu
-* Capturing the Stack or Innermost Stack Frame::
-* Stacks::
-* 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
-@node Capturing the Stack or Innermost Stack Frame
-@subsubsection Capturing the Stack or Innermost Stack Frame
+@node Stack Capture
+@subsubsection Stack Capture
A Scheme program can use the @code{make-stack} primitive anywhere in its
code, with first arg @code{#t}, to construct a Scheme value that
@@ -79,6 +78,9 @@ describes the Scheme stack at that point.
#<stack 25205a0>
@end lisp
+Use @code{start-stack} to limit the stack extent captured by future
+@code{make-stack} calls.
+
@deffn {Scheme Procedure} make-stack obj . args
@deffnx {C Function} scm_make_stack (obj, args)
Create a new stack. If @var{obj} is @code{#t}, the current
@@ -115,6 +117,14 @@ If the @var{outer_cut_N} of the last pair is missing, it is
taken as 0.
@end deffn
+@deffn {Scheme Syntax} start-stack id exp
+Evaluate @var{exp} on a new calling stack with identity @var{id}. If
+@var{exp} is interrupted during evaluation, backtraces will not display
+frames farther back than @var{exp}'s top-level form. This macro is a
+way of artificially limiting backtraces and stack procedures, largely as
+a convenience to the user.
+@end deffn
+
@node Stacks
@subsubsection Stacks
@@ -178,6 +188,31 @@ procedure is associated with @var{frame}.
Return the arguments of @var{frame}.
@end deffn
+@deffn {Scheme Procedure} frame-address frame
+@deffnx {Scheme Procedure} frame-instruction-pointer frame
+@deffnx {Scheme Procedure} frame-stack-pointer frame
+Accessors for the three VM registers associated with this frame: the
+frame pointer (fp), instruction pointer (ip), and stack pointer (sp),
+respectively. @xref{VM Concepts}, for more information.
+@end deffn
+
+@deffn {Scheme Procedure} frame-dynamic-link frame
+@deffnx {Scheme Procedure} frame-return-address frame
+@deffnx {Scheme Procedure} frame-mv-return-address frame
+Accessors for the three saved VM registers in a frame: the previous
+frame pointer, the single-value return address, and the multiple-value
+return address. @xref{Stack Layout}, for more information.
+@end deffn
+
+@deffn {Scheme Procedure} frame-num-locals frame
+@deffnx {Scheme Procedure} frame-local-ref frame i
+@deffnx {Scheme Procedure} frame-local-set! frame i val
+Accessors for the temporary values corresponding to @var{frame}'s
+procedure application. The first local is the first argument given to
+the procedure. After the arguments, there are the local variables, and
+after that temporary values. @xref{Stack Layout}, for more information.
+@end deffn
+
@deffn {Scheme Procedure} display-application frame [port [indent]]
@deffnx {C Function} scm_display_application (frame, port, indent)
Display a procedure application @var{frame} to the output port
@@ -185,9 +220,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
-@subsubsection Source Properties
+@subsection Source Properties
@cindex source properties
As Guile reads in Scheme code from file or from standard input, it
@@ -265,18 +305,6 @@ with the new pair.
@end deffn
-@node Starting a New Stack
-@subsubsection Starting a New Stack
-
-@deffn {Scheme Syntax} start-stack id exp
-Evaluate @var{exp} on a new calling stack with identity @var{id}. If
-@var{exp} is interrupted during evaluation, backtraces will not display
-frames farther back than @var{exp}'s top-level form. This macro is a
-way of artificially limiting backtraces and stack procedures, largely as
-a convenience to the user.
-@end deffn
-
-
@node Programmatic Error Handling
@subsection Programmatic Error Handling
@@ -746,9 +774,9 @@ fired at different times, which may be accessed with the following
procedures.
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.
+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.
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
@@ -815,6 +843,11 @@ Guile exposes a single, heavy-handed knob to turn hooks on or off, the
@dfn{VM trace level}. If the trace level is positive, hooks run;
otherwise they don't.
+For convenience, when the VM fires a hook, it does so with the trap
+level temporarily set to 0. That way the hooks don't fire while you're
+handling a hook. The trace level is restored to whatever it was once the hook
+procedure finishes.
+
@deffn {Scheme Procedure} vm-trace-level 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.
@@ -884,86 +917,132 @@ made the current interface more than anything else.
@node Low-Level Traps
@subsubsection Low-Level Traps
+To summarize the last sections, traps are enabled or disabled, and when
+they are enabled, they add to various VM hooks.
+
+Note, however, that @emph{traps do not increase the VM trace level}. So
+if you create a trap, it will be enabled, but unless something else
+increases the VM's trace level (@pxref{VM Hooks}), the trap will not
+fire. It turns out that getting the VM trace level right is tricky
+without a global view of what traps are enabled. @xref{Trap States},
+for Guile's answer to this problem.
+
+Traps are created by calling procedures. Most of these procedures share
+a set of common keyword arguments, so rather than document them
+separately, we discuss them all together here:
+
+@table @code
+@item #:vm
+The VM to instrument. Defaults to the current thread's VM.
+@item #:closure?
+For traps that depend on the current frame's procedure, this argument
+specifies whether to trap on the only the specific procedure given, or
+on any closure that has the given procedure's code. Defaults to
+@code{#f}.
+@item #:current-frame
+For traps that enable more hooks depending on their dynamic context,
+this argument gives the current frame that the trap is running in.
+Defaults to @code{#f}.
+@end table
+
@deffn {Scheme Procedure} trap-at-procedure-call proc handler @
- [#:vm (the-vm)] [#:closure? #f]
+ [#:vm] [#:closure?]
+A trap that calls @var{handler} when @var{proc} is applied.
@end deffn
-
@deffn {Scheme Procedure} trap-in-procedure proc @
- enter-handler exit-handler @
- [#:current-frame = #f] [#:vm = (the-vm)] [#:closure? = #f]
-A more complicated trap, traps when control enters a procedure.
+ enter-handler exit-handler [#:current-frame] [#:vm] [#:closure?]
+A trap that calls @var{enter-handler} when control enters @var{proc},
+and @var{exit-handler} when control leaves @var{proc}.
Control can enter a procedure via:
- * A procedure call.
- * A return to a procedure's frame on the stack.
- * A continuation returning directly to an application of this
- procedure.
+@itemize
+@item
+A procedure call.
+@item
+A return to a procedure's frame on the stack.
+@item
+A continuation returning directly to an application of this procedure.
+@end itemize
Control can leave a procedure via:
- * A normal return from the procedure.
- * An application of another procedure.
- * An invocation of a continuation.
- * An abort.
-
+@itemize
+@item
+A normal return from the procedure.
+@item
+An application of another procedure.
+@item
+An invocation of a continuation.
+@item
+An abort.
+@end itemize
@end deffn
@deffn {Scheme Procedure} trap-instructions-in-procedure proc @
- next-handler exit-handler @
- [#:current-frame = #f] [#:vm = (the-vm)] [#:closure? = #f]
-Building on trap-in-procedure, we have trap-instructions-in-procedure
+ next-handler exit-handler [#:current-frame] [#:vm] [#:closure?]
+A trap that calls @var{next-handler} for every instruction executed in
+@var{proc}, and @var{exit-handler} when execution leaves @var{proc}.
@end deffn
@deffn {Scheme Procedure} trap-at-procedure-ip-in-range proc range @
- handler @
- [#:current-frame = #f] [#:vm = (the-vm)] [#:closure? = #f]
-Building on trap-instructions-in-procedure, we have
-trap-at-procedure-ip-in-range.
+ handler [#:current-frame] [#:vm] [#:closure?]
+A trap that calls @var{handler} when execution enters a range of
+instructions in @var{proc}. @var{range} is a simple of pairs,
+@code{((@var{start} . @var{end}) ...)}. The @var{start} addresses are
+inclusive, and @var{end} addresses are exclusive.
@end deffn
@deffn {Scheme Procedure} trap-at-source-location file user-line handler @
- [#:current-frame = #f] [#:vm = (the-vm)]
-Building on trap-on-instructions-in-procedure, we have
-trap-at-source-location. The parameter `user-line' is one-indexed, as
-a user counts lines, instead of zero-indexed, as Guile counts lines.
+ [#:current-frame] [#:vm]
+A trap that fires when control reaches a given source location. The
+@var{user-line} parameter is one-indexed, as a user counts lines,
+instead of zero-indexed, as Guile counts lines.
@end deffn
-@deffn {Scheme Procedure} trap-frame-finish frame return-handler abort-handler @
- [#:vm = (the-vm)]
-On a different tack, now we're going to build up a set of traps that
-do useful things during the dynamic extent of a procedure's
-application. First, a trap for when a frame returns.
+@deffn {Scheme Procedure} trap-frame-finish frame @
+ return-handler abort-handler [#:vm]
+A trap that fires when control leaves the given frame. @var{frame}
+should be a live frame in the current continuation. @var{return-handler}
+will be called on a normal return, and @var{abort-handler} on a nonlocal
+exit.
@end deffn
@deffn {Scheme Procedure} trap-in-dynamic-extent proc @
- enter-handler return-handler abort-handler @
- [#:vm = (the-vm)] [#:closure? = #f]
-A more traditional dynamic-wind trap. Perhaps this should not be
-based on the above trap-frame-finish?
+ enter-handler return-handler abort-handler [#:vm] [#:closure?]
+A more traditional dynamic-wind trap, which fires @var{enter-handler}
+when control enters @var{proc}, @var{return-handler} on a normal return,
+and @var{abort-handler} on a nonlocal exit.
+
+Note that rewinds are not handled, so there is no rewind handler.
@end deffn
@deffn {Scheme Procedure} trap-calls-in-dynamic-extent proc @
- apply-handler return-handler @
- [#:current-frame = #f] [#:vm = (the-vm)] [#:closure? = #f]
-Trapping all procedure calls within a dynamic extent, recording the
-depth of the call stack relative to the original procedure.
+ apply-handler return-handler [#:current-frame] [#:vm] [#:closure?]
+A trap that calls @var{apply-handler} every time a procedure is applied,
+and @var{return-handler} for returns, but only during the dynamic extent
+of an application of @var{proc}.
@end deffn
@deffn {Scheme Procedure} trap-instructions-in-dynamic-extent proc @
- next-handler @
- [#:current-frame = #f] [#:vm = (the-vm)] [#:closure? = #f]
-Trapping all retired intructions within a dynamic extent.
+ 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
@deffn {Scheme Procedure} trap-calls-to-procedure proc @
- apply-handler return-handler @
- [#:vm = (the-vm)]
-Traps calls and returns for a given procedure, keeping track of the call depth.
+ apply-handler return-handler [#:vm]
+A trap that calls @var{apply-handler} whenever @var{proc} is applied,
+and @var{return-handler} when it returns, but with an additional
+argument, the call depth.
+
+That is to say, the handlers will get two arguments: the frame in
+question, and the call depth (a non-negative integer).
@end deffn
-@deffn {Scheme Procedure} trap-matching-instructions frame-pred handler @
- [#:vm = (the-vm)]
-Trap when the source location changes.
+@deffn {Scheme Procedure} trap-matching-instructions frame-pred handler [#:vm]
+A trap that calls @var{frame-pred} at every instruction, and if
+@var{frame-pred} returns a true value, calls @var{handler} on the
+frame.
@end deffn
@node Tracing Traps