diff --git a/doc/ref/ChangeLog b/doc/ref/ChangeLog index 1f7b4fc83..982871ee6 100644 --- a/doc/ref/ChangeLog +++ b/doc/ref/ChangeLog @@ -1,3 +1,14 @@ +2006-08-11 Neil Jerram + + * 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 * api-debug.texi (Breakpoints): Removed (all wrong). diff --git a/doc/ref/api-debug.texi b/doc/ref/api-debug.texi index f5aa07d0c..42527b7ec 100644 --- a/doc/ref/api-debug.texi +++ b/doc/ref/api-debug.texi @@ -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{} +# +@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: