mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-10 05:50:26 +02:00
(Debugging): New intro text. New subsection
"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".
This commit is contained in:
parent
b0b0deff2d
commit
5af872e136
2 changed files with 254 additions and 184 deletions
|
@ -1,3 +1,14 @@
|
|||
2006-08-11 Neil Jerram <neil@ossau.uklinux.net>
|
||||
|
||||
* api-debug.texi (Debugging): New intro text. New subsection
|
||||
"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".
|
||||
|
||||
2006-08-01 Neil Jerram <neil@ossau.uklinux.net>
|
||||
|
||||
* api-debug.texi (Breakpoints): Removed (all wrong).
|
||||
|
|
|
@ -8,36 +8,234 @@
|
|||
@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
|
||||
* Interactive Debugging:: Functions intended for interactive use.
|
||||
* Source Properties:: Remembering the source of an expression.
|
||||
* 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 Interactive Debugging
|
||||
@subsection Interactive Debugging
|
||||
@node Capturing the Stack or Innermost Stack Frame
|
||||
@subsubsection Capturing the Stack or Innermost Stack Frame
|
||||
|
||||
@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,
|
||||
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
|
||||
|
||||
@deffn {Scheme Procedure} debug
|
||||
Invoke the Guile debugger to explore the context of the last error.
|
||||
|
||||
@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
|
||||
@subsection Source Properties
|
||||
@subsubsection Source Properties
|
||||
|
||||
@cindex source properties
|
||||
As Guile reads in Scheme code from file or from standard input, it
|
||||
|
@ -135,178 +333,8 @@ that will avoid bloating the source property hash table, which is really
|
|||
only intended for the specific purposes described in this section.
|
||||
|
||||
|
||||
@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
|
||||
|
||||
|
||||
@node Capturing the Stack or Innermost Stack Frame
|
||||
@subsection Capturing the Stack or Innermost Stack Frame
|
||||
|
||||
When an error occurs in a running program, or the program hits a
|
||||
breakpoint, 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 the point of
|
||||
interruption or error by inspecting the stack and its frames.
|
||||
|
||||
@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 a stack which consists of a single frame, which is the
|
||||
last stack frame for @var{obj}. @var{obj} must be either a
|
||||
debug object or a continuation.
|
||||
@end deffn
|
||||
|
||||
|
||||
@node Examining the Stack
|
||||
@subsection 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
|
||||
@subsection 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 Decoding Memoized Source Expressions
|
||||
@subsection Decoding Memoized Source Expressions
|
||||
@subsubsection Decoding Memoized Source Expressions
|
||||
|
||||
@deffn {Scheme Procedure} memoized? obj
|
||||
@deffnx {C Function} scm_memoized_p (obj)
|
||||
|
@ -325,7 +353,7 @@ Return the environment of the memoized expression @var{m}.
|
|||
|
||||
|
||||
@node Starting a New Stack
|
||||
@subsection 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
|
||||
|
@ -336,6 +364,37 @@ 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:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue