Update api-debug.texi; there is a ways to go.
authorAndy Wingo <wingo@pobox.com>
Sun, 14 Mar 2010 22:05:42 +0000 (23:05 +0100)
committerAndy Wingo <wingo@pobox.com>
Sun, 14 Mar 2010 22:05:42 +0000 (23:05 +0100)
* doc/ref/api-debug.texi: Update a bit.

doc/ref/api-debug.texi

index 3c9ec11..747ac45 100644 (file)
@@ -10,9 +10,9 @@
 
 @cindex Debugging
 In order to understand Guile's debugging facilities, you first need to
-understand a little about how the evaluator works and what the Scheme
-stack is.  With that in place we explain the low level trap calls that
-the evaluator can be configured to make, and the trap and breakpoint
+understand a little about how Guile represent the Scheme control stack.
+With that in place we explain the low level trap calls that the
+evaluator can be configured to make, and the trap and breakpoint
 infrastructure that builds on top of those calls.
 
 @menu
@@ -25,41 +25,31 @@ infrastructure that builds on top of those calls.
 @node Evaluation Model
 @subsection Evaluation and the Scheme Stack
 
-The idea of the Scheme stack is central to a lot of debugging.  It
-always exists implicitly, as a result of the way that the Guile
-evaluator works, and can be summoned into concrete existence as a
-first-class Scheme value by the @code{make-stack} call, so that an
-introspective Scheme program -- such as a debugger -- can present it in
-some way and allow the user to query its details.  The first thing to
-understand, therefore, is how the workings of the evaluator build up the
-stack.
-
-@cindex Evaluations
-@cindex Applications
-Broadly speaking, the evaluator performs @dfn{evaluations} and
-@dfn{applications}.  An evaluation means that it is looking at a source
-code expression like @code{(+ x 5)} or @code{(if msg (loop))}, deciding
-whether the top level of the expression is a procedure call, macro,
-builtin syntax, or whatever, and doing some appropriate processing in
-each case.  (In the examples here, @code{(+ x 5)} would normally be a
-procedure call, and @code{(if msg (loop))} builtin syntax.)  For a
-procedure call, ``appropriate processing'' includes evaluating the
-procedure's arguments, as that must happen before the procedure itself
-can be called.  An application means calling a procedure once its
-arguments have been calculated.
-
-@cindex Stack
-@cindex Frames
-@cindex Stack frames
-Typically evaluations and applications alternate with each other, and
-together they form a @dfn{stack} of operations pending completion.  This
-is because, on the one hand, evaluation of an expression like @code{(+ x
-5)} requires --- once its arguments have been calculated --- an
-application (in this case, of the procedure @code{+}) before it can
-complete and return a result, and, on the other hand, the application of
-a procedure written in Scheme involves evaluating the sequence of
-expressions that constitute that procedure's code.  Each level on this
-stack is called a @dfn{frame}.
+The idea of the Scheme stack is central to a lot of debugging.  The
+Scheme stack is a reified representation of the pending function returns
+in an expression's continuation. As Guile implements function calls
+using a stack, this reification takes the form of a number of nested
+stack frames, each of which has the procedure and its arguments, along
+with local variables and temporary values.
+
+A Scheme stack always exists implicitly, and can be summoned into
+concrete existence as a first-class Scheme value by the
+@code{make-stack} call, so that an introspective Scheme program -- such
+as a debugger -- can present it in some way and allow the user to query
+its details. The first thing to understand, therefore, is how Guile's
+function call convention creates the stack.
+
+Broadly speaking, Guile represents all control flow on a stack. Calling
+a function involves pushing an empty frame on the stack, then evaluating
+the procedure and its arguments, then fixing up the new frame so that it
+points to the old one. Frames on the stack are thus linked together. A
+tail call is the same, except it reuses the existing frame instead of
+pushing on a new one.
+
+In this way, the only frames that are on the stack are ``active''
+frames, frames which need to do some work before the computation is
+complete. On the other hand, a function that has tail-called another
+function will not be on the stack, as it has no work left to do.
 
 Therefore, when an error occurs in a running program, or the program
 hits a breakpoint, or in fact at any point that the programmer chooses,
@@ -74,7 +64,6 @@ stack and its frames.
 * Examining the Stack::
 * Examining Stack Frames::
 * Source Properties::           Remembering the source of an expression.
-* Decoding Memoized Source Expressions::
 * Starting a New Stack::
 @end menu
 
@@ -96,10 +85,10 @@ describes the Scheme stack at that point.
 Create a new stack. If @var{obj} is @code{#t}, the current
 evaluation stack is used for creating the stack frames,
 otherwise the frames are taken from @var{obj} (which must be
-either a debug object or a continuation).
+a continuation or a frame object).
 
 @var{args} should be a list containing any combination of
-integer, procedure and @code{#t} values.
+integer, procedure, prompt tag and @code{#t} values.
 
 These values specify various ways of cutting away uninteresting
 stack frames from the top and bottom of the stack that
@@ -107,28 +96,26 @@ stack frames from the top and bottom of the stack that
 @code{(@var{inner_cut_1} @var{outer_cut_1} @var{inner_cut_2}
 @var{outer_cut_2} @dots{})}.
 
-Each @var{inner_cut_N} can be @code{#t}, an integer, or a
-procedure.  @code{#t} means to cut away all frames up to but
-excluding the first user module frame.  An integer means to cut
-away exactly that number of frames.  A procedure means to cut
-away all frames up to but excluding the application frame whose
+Each @var{inner_cut_N} can be @code{#t}, an integer, a prompt
+tag, or a procedure.  @code{#t} means to cut away all frames up
+to but excluding the first user module frame.  An integer means
+to cut away exactly that number of frames.  A prompt tag means
+to cut away all frames that are inside a prompt with the given
+tag. A procedure means to cut away all frames up to but
+excluding the application frame whose procedure matches the
+specified one.
+
+Each @var{outer_cut_N} can be an integer, a prompt tag, or a
+procedure.  An integer means to cut away that number of frames.
+A prompt tag means to cut away all frames that are outside a
+prompt with the given tag. A procedure means to cut away
+frames down to but excluding the application frame whose
 procedure matches the specified one.
 
-Each @var{outer_cut_N} can be an integer or a procedure.  An
-integer means to cut away that number of frames.  A procedure
-means to cut away frames down to but excluding the application
-frame whose procedure matches the specified one.
-
 If the @var{outer_cut_N} of the last pair is missing, it is
 taken as 0.
 @end deffn
 
-@deffn {Scheme Procedure} last-stack-frame obj
-@deffnx {C Function} scm_last_stack_frame (obj)
-Return the last (innermost) frame of @var{obj}, which must be
-either a debug object or a continuation.
-@end deffn
-
 
 @node Examining the Stack
 @subsubsection Examining the Stack
@@ -175,33 +162,12 @@ backtrace.
 Return @code{#t} if @var{obj} is a stack frame.
 @end deffn
 
-@deffn {Scheme Procedure} frame-number frame
-@deffnx {C Function} scm_frame_number (frame)
-Return the frame number of @var{frame}.
-@end deffn
-
 @deffn {Scheme Procedure} frame-previous frame
 @deffnx {C Function} scm_frame_previous (frame)
 Return the previous frame of @var{frame}, or @code{#f} if
 @var{frame} is the first frame in its stack.
 @end deffn
 
-@deffn {Scheme Procedure} frame-next frame
-@deffnx {C Function} scm_frame_next (frame)
-Return the next frame of @var{frame}, or @code{#f} if
-@var{frame} is the last frame in its stack.
-@end deffn
-
-@deffn {Scheme Procedure} frame-source frame
-@deffnx {C Function} scm_frame_source (frame)
-Return the source of @var{frame}.
-@end deffn
-
-@deffn {Scheme Procedure} frame-procedure? frame
-@deffnx {C Function} scm_frame_procedure_p (frame)
-Return @code{#t} if a procedure is associated with @var{frame}.
-@end deffn
-
 @deffn {Scheme Procedure} frame-procedure frame
 @deffnx {C Function} scm_frame_procedure (frame)
 Return the procedure for @var{frame}, or @code{#f} if no
@@ -213,21 +179,6 @@ procedure is associated with @var{frame}.
 Return the arguments of @var{frame}.
 @end deffn
 
-@deffn {Scheme Procedure} frame-evaluating-args? frame
-@deffnx {C Function} scm_frame_evaluating_args_p (frame)
-Return @code{#t} if @var{frame} contains evaluated arguments.
-@end deffn
-
-@deffn {Scheme Procedure} frame-overflow? frame
-@deffnx {C Function} scm_frame_overflow_p (frame)
-Return @code{#t} if @var{frame} is an overflow frame.
-@end deffn
-
-@deffn {Scheme Procedure} frame-real? frame
-@deffnx {C Function} scm_frame_real_p (frame)
-Return @code{#t} if @var{frame} is a real frame.
-@end deffn
-
 @deffn {Scheme Procedure} display-application frame [port [indent]]
 @deffnx {C Function} scm_display_application (frame, port, indent)
 Display a procedure application @var{frame} to the output port
@@ -242,14 +193,12 @@ output.
 @cindex source properties
 As Guile reads in Scheme code from file or from standard input, it
 remembers the file name, line number and column number where each
-expression begins.  These pieces of information are known as the
-@dfn{source properties} of the expression.  If an expression undergoes
-transformation --- for example, if there is a syntax transformer in
-effect, or the expression is a macro call --- the source properties are
-copied from the untransformed to the transformed expression so that, if
-an error occurs when evaluating the transformed expression, Guile's
-debugger can point back to the file and location where the expression
-originated.
+expression begins. These pieces of information are known as the
+@dfn{source properties} of the expression. Syntax expanders and the
+compiler propagate these source properties to compiled procedures, so
+that, if an error occurs when evaluating the transformed expression,
+Guile's debugger can point back to the file and location where the
+expression originated.
 
 The way that source properties are stored means that Guile can only
 associate source properties with parenthesized expressions, and not, for
@@ -275,10 +224,7 @@ port>''.
 
 The recording of source properties is controlled by the read option
 named ``positions'' (@pxref{Reader options}).  This option is switched
-@emph{on} by default, together with the debug options ``debug'' and
-``backtrace'' (@pxref{Debugger options}), when Guile is run
-interactively; all these options are @emph{off} by default when Guile
-runs a script non-interactively.
+@emph{on} by default.
 
 The following procedures can be used to access and set the source
 properties of read expressions.
@@ -306,52 +252,9 @@ Return the property specified by @var{key} from @var{obj}'s source
 properties.
 @end deffn
 
-In practice there are only two ways that you should use the ability to
-set an expression's source properties.
-
-@itemize
-@item
-To set a breakpoint on an expression, use @code{(set-source-property!
-@var{expr} 'breakpoint #t)}.  If you do this, you should also set the
-@code{traps} and @code{enter-frame-handler} trap options
-(@pxref{Evaluator trap options}) and @code{breakpoints} debug option
-(@pxref{Debugger options}) appropriately, and the evaluator will then
-call your enter frame handler whenever it is about to evaluate that
-expression.
-
-@item
-To make a read or constructed expression appear to have come from a
-different source than what the expression's source properties already
-say, you can use @code{set-source-property!} to set the expression's
-@code{filename}, @code{line} and @code{column} properties.  The
-properties that you set will then show up later if that expression is
-involved in a backtrace or error report.
-@end itemize
-
-If you are looking for a way to attach arbitrary information to an
-expression other than these properties, you should use
-@code{make-object-property} instead (@pxref{Object Properties}).  That
-will avoid bloating the source property hash table, which is really
-only intended for the debugging purposes just described.
-
-
-@node Decoding Memoized Source Expressions
-@subsubsection Decoding Memoized Source Expressions
-
-@deffn {Scheme Procedure} memoized? obj
-@deffnx {C Function} scm_memoized_p (obj)
-Return @code{#t} if @var{obj} is memoized.
-@end deffn
-
-@deffn {Scheme Procedure} unmemoize m
-@deffnx {C Function} scm_unmemoize (m)
-Unmemoize the memoized expression @var{m},
-@end deffn
-
-@deffn {Scheme Procedure} memoized-environment m
-@deffnx {C Function} scm_memoized_environment (m)
-Return the environment of the memoized expression @var{m}.
-@end deffn
+If the @code{positions} reader option is enabled, each parenthesized
+expression will have values set for the @code{filename}, @code{line} and
+@code{column} properties.
 
 
 @node Starting a New Stack
@@ -377,15 +280,15 @@ the error chose explicitly to provide.  This information originates with
 the @code{error} or @code{throw} call (or their C code equivalents, if
 the error is detected by C code) that signals the error, and is passed
 automatically to the handler procedure of the innermost applicable
-@code{catch}, @code{lazy-catch} or @code{with-throw-handler} expression.
+@code{catch} or @code{with-throw-handler} expression.
 
 @subsubsection Intercepting basic error information
 
 Therefore, to catch errors that occur within a chunk of Scheme code, and
 to intercept basic information about those errors, you need to execute
-that code inside the dynamic context of a @code{catch},
-@code{lazy-catch} or @code{with-throw-handler} expression, or the
-equivalent in C.  In Scheme, this means you need something like this:
+that code inside the dynamic context of a @code{catch} or
+@code{with-throw-handler} expression, or the equivalent in C. In Scheme,
+this means you need something like this:
 
 @lisp
 (catch #t
@@ -436,9 +339,8 @@ SCM my_handler_proc (void *handler_data,
 
 @noindent
 Again, as with the Scheme version, @code{scm_c_catch} could be replaced
-by @code{scm_internal_lazy_catch} or @code{scm_c_with_throw_handler},
-and @code{SCM_BOOL_T} could instead be the symbol for a particular kind
-of error.
+by @code{scm_c_with_throw_handler}, and @code{SCM_BOOL_T} could instead
+be the symbol for a particular kind of error.
 
 @subsubsection Capturing the full error stack
 
@@ -446,19 +348,10 @@ The other interesting information about an error is the full Scheme
 stack at the point where the error occurred; in other words what
 innermost expression was being evaluated, what was the expression that
 called that one, and so on.  If you want to write your code so that it
-captures and can display this information as well, there are three
+captures and can display this information as well, there are a couple
 important things to understand.
 
-Firstly, the code in question must be executed using the debugging
-version of the evaluator, because information about the Scheme stack is
-only available at all from the debugging evaluator.  Using the debugging
-evaluator means that the debugger option (@pxref{Debugger options})
-called @code{debug} must be enabled; this can be done by running
-@code{(debug-enable 'debug)} or @code{(turn-on-debugging)} at the top
-level of your program; or by running guile with the @code{--debug}
-command line option, if your program begins life as a Scheme script.
-
-Secondly, the stack at the point of the error needs to be explicitly
+Firstly, the stack at the point of the error needs to be explicitly
 captured by a @code{make-stack} call (or the C equivalent
 @code{scm_make_stack}).  The Guile library does not do this
 ``automatically'' for you, so you will need to write code with a
@@ -472,16 +365,15 @@ running on top of the Guile library, and which uses @code{catch} and
 @code{make-stack} in the way we are about to describe to capture the
 stack when an error occurs.)
 
-Thirdly, in order to capture the stack effectively at the point where
-the error occurred, the @code{make-stack} call must be made before Guile
-unwinds the stack back to the location of the prevailing catch
-expression.  This means that the @code{make-stack} call must be made
-within the handler of a @code{lazy-catch} or @code{with-throw-handler}
-expression, or the optional "pre-unwind" handler of a @code{catch}.
-(For the full story of how these alternatives differ from each other,
-see @ref{Exceptions}.  The main difference is that @code{catch}
-terminates the error, whereas @code{lazy-catch} and
-@code{with-throw-handler} only intercept it temporarily and then allow
+And secondly, in order to capture the stack effectively at the point
+where the error occurred, the @code{make-stack} call must be made before
+Guile unwinds the stack back to the location of the prevailing catch
+expression. This means that the @code{make-stack} call must be made
+within the handler of a @code{with-throw-handler} expression, or the
+optional "pre-unwind" handler of a @code{catch}. (For the full story of
+how these alternatives differ from each other, see @ref{Exceptions}. The
+main difference is that @code{catch} terminates the error, whereas
+@code{with-throw-handler} only intercepts it temporarily and then allow
 it to continue propagating up to the next innermost handler.)
 
 So, here are some examples of how to do all this in Scheme and in C.
@@ -582,11 +474,11 @@ application frame -- that is, a frame that satisfies the
 
 @subsubsection What the Guile REPL does
 
-The Guile REPL code (in @file{ice-9/boot-9.scm}) uses a @code{catch}
-with a pre-unwind handler to capture the stack when an error occurs in
-an expression that was typed into the REPL, and saves the captured stack
-in a fluid (@pxref{Fluids and Dynamic States}) called
-@code{the-last-stack}.  You can then use the @code{(backtrace)} command,
+The Guile REPL code (in @file{system/repl/repl.scm} and related files)
+uses a @code{catch} with a pre-unwind handler to capture the stack when
+an error occurs in an expression that was typed into the REPL, and saves
+the captured stack in a fluid (@pxref{Fluids and Dynamic States}) called
+@code{the-last-stack}. You can then use the @code{(backtrace)} command,
 which is basically equivalent to @code{(display-backtrace (fluid-ref
 the-last-stack))}, to print out this stack at any time until it is
 overwritten by the next error that occurs.
@@ -619,17 +511,16 @@ Invoke the Guile debugger to explore the context of the last error.
 @cindex Tracing
 @cindex Code coverage
 @cindex Profiling
-The low level C code of Guile's evaluator can be configured to call
-out at key points to arbitrary user-specified procedures.  These
-procedures, and the circumstances under which the evaluator calls
-them, are configured by the ``evaluator trap options'' interface
-(@pxref{Evaluator trap options}), and by the @code{trace} and
-@code{breakpoints} fields of the ``debug options'' interface
-(@pxref{Debugger options}).  In principle this allows Scheme code to
-implement any model it chooses for examining the evaluation stack as
-program execution proceeds, and for suspending execution to be resumed
-later.  Possible applications of this feature include breakpoints,
-runtime tracing, code coverage, and profiling.
+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.
 
 @cindex Trap classes
 @cindex Trap objects
@@ -650,6 +541,14 @@ user wanting to use traps, and the developer interested in
 understanding how the interface hangs together.
 
 
+@subsubsection Actually, this section is bitrotten
+
+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!
+@code{guile-devel@@gnu.org}, that's where.
+
+
 @subsubsection A Quick Note on Terminology
 
 @cindex Trap terminology
@@ -1886,19 +1785,6 @@ hi!
 guile> 
 @end lisp
 
-@anchor{Memoization}
-@cindex Memoization
-(For anyone wondering why the first @code{(do-main 4)} call above
-generates lots more trace lines than the subsequent calls: these
-examples also demonstrate how the Guile evaluator ``memoizes'' code.
-When Guile evaluates a source code expression for the first time, it
-changes some parts of the expression so that they will be quicker to
-evaluate when that expression is evaluated again; this is called
-memoization.  The trace output from the first @code{(do-main 4)} call
-shows memoization steps, such as an internal define being transformed to
-a letrec.)
-
-
 @c Local Variables:
 @c TeX-master: "guile.texi"
 @c End: