mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 03:40:34 +02:00
"Evaluation Model". Moved existing subsections "Capturing the Stack or Innermost Stack Frame", "Examining the Stack", "Examining Stack Frames", "Source Properties", "Decoding Memoized Source Expressions" and "Starting a New Stack" under "Evaluation Model". (Capturing the Stack or Innermost Stack Frame): Some new text, and correction to doc for last-stack-frame. (Debug on Error): Renamed from "Interactive Debugging".
400 lines
14 KiB
Text
400 lines
14 KiB
Text
@c -*-texinfo-*-
|
|
@c This is part of the GNU Guile Reference Manual.
|
|
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004
|
|
@c Free Software Foundation, Inc.
|
|
@c See the file guile.texi for copying conditions.
|
|
|
|
@page
|
|
@node Debugging
|
|
@section Debugging Infrastructure
|
|
|
|
In order to understand Guile's debugging facilities, you first need to
|
|
understand a little about how the evaluator works and what the Scheme
|
|
stack is. With that in place we explain the low level trap calls that
|
|
the evaluator can be configured to make, and the trap and breakpoint
|
|
infrastructure that builds on top of those calls.
|
|
|
|
@menu
|
|
* Evaluation Model:: Evaluation and the Scheme stack.
|
|
* Debug on Error:: Debugging when an error occurs.
|
|
* Using Traps::
|
|
@end menu
|
|
|
|
@node Evaluation Model
|
|
@subsection Evaluation and the Scheme Stack
|
|
|
|
The idea of the Scheme stack is central to a lot of debugging. It
|
|
always exists implicitly, as a result of the way that the Guile
|
|
evaluator works, and can be summoned into concrete existence as a
|
|
first-class Scheme value by the @code{make-stack} call, so that an
|
|
introspective Scheme program -- such as a debugger -- can present it in
|
|
some way and allow the user to query its details. The first thing to
|
|
understand, therefore, is how the workings of the evaluator build up the
|
|
stack.
|
|
|
|
@cindex Evaluations
|
|
@cindex Applications
|
|
Broadly speaking, the evaluator performs @dfn{evaluations} and
|
|
@dfn{applications}. An evaluation means that it is looking at a source
|
|
code expression like @code{(+ x 5)} or @code{(if msg (loop))}, deciding
|
|
whether the top level of the expression is a procedure call, macro,
|
|
builtin syntax, or whatever, and doing some appropriate processing in
|
|
each case. (In the examples here, @code{(+ x 5)} would normally be a
|
|
procedure call, and @code{(if msg (loop))} builtin syntax.) For a
|
|
procedure call, ``appropriate processing'' includes evaluating the
|
|
procedure's arguments, as that must happen before the procedure itself
|
|
can be called. An application means calling a procedure once its
|
|
arguments have been calculated.
|
|
|
|
@cindex Stack
|
|
@cindex Frames
|
|
@cindex Stack frames
|
|
Typically evaluations and applications alternate with each other, and
|
|
together they form a @dfn{stack} of operations pending completion. This
|
|
is because, on the one hand, evaluation of an expression like @code{(+ x
|
|
5)} requires --- once its arguments have been calculated --- an
|
|
application (in this case, of the procedure @code{+}) before it can
|
|
complete and return a result, and, on the other hand, the application of
|
|
a procedure written in Scheme involves evaluating the sequence of
|
|
expressions that constitute that procedure's code. Each level on this
|
|
stack is called a @dfn{frame}.
|
|
|
|
Therefore, when an error occurs in a running program, or the program
|
|
hits a breakpoint, or in fact at any point that the programmer chooses,
|
|
its state at that point can be represented by a @dfn{stack} of all the
|
|
evaluations and procedure applications that are logically in progress at
|
|
that time, each of which is known as a @dfn{frame}. The programmer can
|
|
learn more about the program's state at that point by inspecting the
|
|
stack and its frames.
|
|
|
|
@menu
|
|
* Capturing the Stack or Innermost Stack Frame::
|
|
* Examining the Stack::
|
|
* Examining Stack Frames::
|
|
* Source Properties:: Remembering the source of an expression.
|
|
* Decoding Memoized Source Expressions::
|
|
* Starting a New Stack::
|
|
@end menu
|
|
|
|
@node Capturing the Stack or Innermost Stack Frame
|
|
@subsubsection Capturing the Stack or Innermost Stack Frame
|
|
|
|
A Scheme program can use the @code{make-stack} primitive anywhere in its
|
|
code, with first arg @code{#t}, to construct a Scheme value that
|
|
describes the Scheme stack at that point.
|
|
|
|
@lisp
|
|
(make-stack #t)
|
|
@result{}
|
|
#<stack 805c840:808d250>
|
|
@end lisp
|
|
|
|
@deffn {Scheme Procedure} make-stack obj . args
|
|
@deffnx {C Function} scm_make_stack (obj, args)
|
|
Create a new stack. If @var{obj} is @code{#t}, the current
|
|
evaluation stack is used for creating the stack frames,
|
|
otherwise the frames are taken from @var{obj} (which must be
|
|
either a debug object or a continuation).
|
|
|
|
@var{args} should be a list containing any combination of
|
|
integer, procedure and @code{#t} values.
|
|
|
|
These values specify various ways of cutting away uninteresting
|
|
stack frames from the top and bottom of the stack that
|
|
@code{make-stack} returns. They come in pairs like this:
|
|
@code{(@var{inner_cut_1} @var{outer_cut_1} @var{inner_cut_2}
|
|
@var{outer_cut_2} @dots{})}.
|
|
|
|
Each @var{inner_cut_N} can be @code{#t}, an integer, or a
|
|
procedure. @code{#t} means to cut away all frames up to but
|
|
excluding the first user module frame. An integer means to cut
|
|
away exactly that number of frames. A procedure means to cut
|
|
away all frames up to but excluding the application frame whose
|
|
procedure matches the specified one.
|
|
|
|
Each @var{outer_cut_N} can be an integer or a procedure. An
|
|
integer means to cut away that number of frames. A procedure
|
|
means to cut away frames down to but excluding the application
|
|
frame whose procedure matches the specified one.
|
|
|
|
If the @var{outer_cut_N} of the last pair is missing, it is
|
|
taken as 0.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} last-stack-frame obj
|
|
@deffnx {C Function} scm_last_stack_frame (obj)
|
|
Return the last (innermost) frame of @var{obj}, which must be
|
|
either a debug object or a continuation.
|
|
@end deffn
|
|
|
|
|
|
@node Examining the Stack
|
|
@subsubsection Examining the Stack
|
|
|
|
@deffn {Scheme Procedure} stack? obj
|
|
@deffnx {C Function} scm_stack_p (obj)
|
|
Return @code{#t} if @var{obj} is a calling stack.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} stack-id stack
|
|
@deffnx {C Function} scm_stack_id (stack)
|
|
Return the identifier given to @var{stack} by @code{start-stack}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} stack-length stack
|
|
@deffnx {C Function} scm_stack_length (stack)
|
|
Return the length of @var{stack}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} stack-ref stack index
|
|
@deffnx {C Function} scm_stack_ref (stack, index)
|
|
Return the @var{index}'th frame from @var{stack}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} display-backtrace stack port [first [depth [highlights]]]
|
|
@deffnx {C Function} scm_display_backtrace_with_highlights (stack, port, first, depth, highlights)
|
|
@deffnx {C Function} scm_display_backtrace (stack, port, first, depth)
|
|
Display a backtrace to the output port @var{port}. @var{stack}
|
|
is the stack to take the backtrace from, @var{first} specifies
|
|
where in the stack to start and @var{depth} how much frames
|
|
to display. Both @var{first} and @var{depth} can be @code{#f},
|
|
which means that default values will be used.
|
|
When @var{highlights} is given,
|
|
it should be a list and all members of it are highligthed in
|
|
the backtrace.
|
|
@end deffn
|
|
|
|
|
|
@node Examining Stack Frames
|
|
@subsubsection Examining Stack Frames
|
|
|
|
@deffn {Scheme Procedure} frame? obj
|
|
@deffnx {C Function} scm_frame_p (obj)
|
|
Return @code{#t} if @var{obj} is a stack frame.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} frame-number frame
|
|
@deffnx {C Function} scm_frame_number (frame)
|
|
Return the frame number of @var{frame}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} frame-previous frame
|
|
@deffnx {C Function} scm_frame_previous (frame)
|
|
Return the previous frame of @var{frame}, or @code{#f} if
|
|
@var{frame} is the first frame in its stack.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} frame-next frame
|
|
@deffnx {C Function} scm_frame_next (frame)
|
|
Return the next frame of @var{frame}, or @code{#f} if
|
|
@var{frame} is the last frame in its stack.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} frame-source frame
|
|
@deffnx {C Function} scm_frame_source (frame)
|
|
Return the source of @var{frame}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} frame-procedure? frame
|
|
@deffnx {C Function} scm_frame_procedure_p (frame)
|
|
Return @code{#t} if a procedure is associated with @var{frame}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} frame-procedure frame
|
|
@deffnx {C Function} scm_frame_procedure (frame)
|
|
Return the procedure for @var{frame}, or @code{#f} if no
|
|
procedure is associated with @var{frame}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} frame-arguments frame
|
|
@deffnx {C Function} scm_frame_arguments (frame)
|
|
Return the arguments of @var{frame}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} frame-evaluating-args? frame
|
|
@deffnx {C Function} scm_frame_evaluating_args_p (frame)
|
|
Return @code{#t} if @var{frame} contains evaluated arguments.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} frame-overflow? frame
|
|
@deffnx {C Function} scm_frame_overflow_p (frame)
|
|
Return @code{#t} if @var{frame} is an overflow frame.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} frame-real? frame
|
|
@deffnx {C Function} scm_frame_real_p (frame)
|
|
Return @code{#t} if @var{frame} is a real frame.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} display-application frame [port [indent]]
|
|
@deffnx {C Function} scm_display_application (frame, port, indent)
|
|
Display a procedure application @var{frame} to the output port
|
|
@var{port}. @var{indent} specifies the indentation of the
|
|
output.
|
|
@end deffn
|
|
|
|
|
|
@node Source Properties
|
|
@subsubsection Source Properties
|
|
|
|
@cindex source properties
|
|
As Guile reads in Scheme code from file or from standard input, it
|
|
remembers the file name, line number and column number where each
|
|
expression begins. These pieces of information are known as the
|
|
@dfn{source properties} of the expression. If an expression undergoes
|
|
transformation --- for example, if there is a syntax transformer in
|
|
effect, or the expression is a macro call --- the source properties are
|
|
copied from the untransformed to the transformed expression so that, if
|
|
an error occurs when evaluating the transformed expression, Guile's
|
|
debugger can point back to the file and location where the expression
|
|
originated.
|
|
|
|
The way that source properties are stored means that Guile can only
|
|
associate source properties with parenthesized expressions, and not, for
|
|
example, with individual symbols, numbers or strings. The difference
|
|
can be seen by typing @code{(xxx)} and @code{xxx} at the Guile prompt
|
|
(where the variable @code{xxx} has not been defined):
|
|
|
|
@example
|
|
guile> (xxx)
|
|
standard input:2:1: In expression (xxx):
|
|
standard input:2:1: Unbound variable: xxx
|
|
ABORT: (unbound-variable)
|
|
guile> xxx
|
|
<unnamed port>: In expression xxx:
|
|
<unnamed port>: Unbound variable: xxx
|
|
ABORT: (unbound-variable)
|
|
@end example
|
|
|
|
@noindent
|
|
In the latter case, no source properties were stored, so the best that
|
|
Guile could say regarding the location of the problem was ``<unnamed
|
|
port>''.
|
|
|
|
The recording of source properties is controlled by the read option
|
|
named ``positions'' (@pxref{Reader options}). This option is switched
|
|
@emph{on} by default, together with the debug options ``debug'' and
|
|
``backtrace'' (@pxref{Debugger options}), when Guile is run
|
|
interactively; all these options are @emph{off} by default when Guile
|
|
runs a script non-interactively.
|
|
|
|
The following procedures can be used to access and set the source
|
|
properties of read expressions.
|
|
|
|
@deffn {Scheme Procedure} set-source-properties! obj plist
|
|
@deffnx {C Function} scm_set_source_properties_x (obj, plist)
|
|
Install the association list @var{plist} as the source property
|
|
list for @var{obj}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} set-source-property! obj key datum
|
|
@deffnx {C Function} scm_set_source_property_x (obj, key, datum)
|
|
Set the source property of object @var{obj}, which is specified by
|
|
@var{key} to @var{datum}. Normally, the key will be a symbol.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} source-properties obj
|
|
@deffnx {C Function} scm_source_properties (obj)
|
|
Return the source property association list of @var{obj}.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} source-property obj key
|
|
@deffnx {C Function} scm_source_property (obj, key)
|
|
Return the source property specified by @var{key} from
|
|
@var{obj}'s source property list.
|
|
@end deffn
|
|
|
|
In practice there are only two ways that you should use the ability to
|
|
set an expression's source breakpoints.
|
|
|
|
@itemize
|
|
@item
|
|
To set a breakpoint on an expression, use @code{(set-source-property!
|
|
@var{expr} 'breakpoint #t)}. If you do this, you should also set the
|
|
@code{traps} and @code{enter-frame-handler} trap options
|
|
(@pxref{Evaluator trap options}) and @code{breakpoints} debug option
|
|
(@pxref{Debugger options}) appropriately, and the evaluator will then
|
|
call your enter frame handler whenever it is about to evaluate that
|
|
expression.
|
|
|
|
@item
|
|
To make a read or constructed expression appear to have come from a
|
|
different source than what the expression's source properties already
|
|
say, you can use @code{set-source-property!} to set the expression's
|
|
@code{filename}, @code{line} and @code{column} properties. The
|
|
properties that you set will then show up later if that expression is
|
|
involved in a backtrace or error report.
|
|
@end itemize
|
|
|
|
If you are looking for a way to attach arbitrary information to an
|
|
expression other than these properties, you should use
|
|
@code{make-object-property} instead (@pxref{Object Properties}), because
|
|
that will avoid bloating the source property hash table, which is really
|
|
only intended for the specific purposes described in this section.
|
|
|
|
|
|
@node Decoding Memoized Source Expressions
|
|
@subsubsection Decoding Memoized Source Expressions
|
|
|
|
@deffn {Scheme Procedure} memoized? obj
|
|
@deffnx {C Function} scm_memoized_p (obj)
|
|
Return @code{#t} if @var{obj} is memoized.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} unmemoize m
|
|
@deffnx {C Function} scm_unmemoize (m)
|
|
Unmemoize the memoized expression @var{m},
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} memoized-environment m
|
|
@deffnx {C Function} scm_memoized_environment (m)
|
|
Return the environment of the memoized expression @var{m}.
|
|
@end deffn
|
|
|
|
|
|
@node Starting a New Stack
|
|
@subsubsection Starting a New Stack
|
|
|
|
@deffn {Scheme Syntax} start-stack id exp
|
|
Evaluate @var{exp} on a new calling stack with identity @var{id}. If
|
|
@var{exp} is interrupted during evaluation, backtraces will not display
|
|
frames farther back than @var{exp}'s top-level form. This macro is a
|
|
way of artificially limiting backtraces and stack procedures, largely as
|
|
a convenience to the user.
|
|
@end deffn
|
|
|
|
|
|
@node Debug on Error
|
|
@subsection Debugging when an error occurs
|
|
|
|
@deffn {Scheme Procedure} backtrace [highlights]
|
|
@deffnx {C Function} scm_backtrace_with_highlights (highlights)
|
|
@deffnx {C Function} scm_backtrace ()
|
|
Display a backtrace of the stack saved by the last error
|
|
to the current output port. When @var{highlights} is given,
|
|
it should be a list and all members of it are highligthed in
|
|
the backtrace.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} debug
|
|
Invoke the Guile debugger to explore the context of the last error.
|
|
@end deffn
|
|
|
|
|
|
@node Using Traps
|
|
@subsection Using Traps
|
|
|
|
@deffn {Scheme Procedure} with-traps thunk
|
|
@deffnx {C Function} scm_with_traps (thunk)
|
|
Call @var{thunk} with traps enabled.
|
|
@end deffn
|
|
|
|
@deffn {Scheme Procedure} debug-object? obj
|
|
@deffnx {C Function} scm_debug_object_p (obj)
|
|
Return @code{#t} if @var{obj} is a debug object.
|
|
@end deffn
|
|
|
|
|
|
@c Local Variables:
|
|
@c TeX-master: "guile.texi"
|
|
@c End:
|