diff options
author | Andy Wingo <wingo@pobox.com> | 2010-10-07 22:15:35 +0200 |
---|---|---|
committer | Andy Wingo <wingo@pobox.com> | 2010-10-07 22:15:35 +0200 |
commit | 5db7c0bf4ae6266415b464f8e011209e7a7f55fd (patch) | |
tree | 714294da2f357f22e92f49092b172618e6742a9b /doc/ref/api-debug.texi | |
parent | 6e069bbfce57357ff279f19b09464b48de43fede (diff) | |
download | guile-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.texi | 219 |
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 |