diff options
Diffstat (limited to 'doc/ref/api-debug.texi')
-rw-r--r-- | doc/ref/api-debug.texi | 351 |
1 files changed, 205 insertions, 146 deletions
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,156 +8,86 @@ @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 - -@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 Source Properties -@subsection 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 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 +@subsubsection 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. +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) @@ -193,14 +123,13 @@ taken as 0. @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. +Return the last (innermost) frame of @var{obj}, which must be +either a debug object or a continuation. @end deffn @node Examining the Stack -@subsection Examining the Stack +@subsubsection Examining the Stack @deffn {Scheme Procedure} stack? obj @deffnx {C Function} scm_stack_p (obj) @@ -237,7 +166,7 @@ the backtrace. @node Examining Stack Frames -@subsection Examining Stack Frames +@subsubsection Examining Stack Frames @deffn {Scheme Procedure} frame? obj @deffnx {C Function} scm_frame_p (obj) @@ -305,8 +234,107 @@ 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 -@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: |