@c -*-texinfo-*- @c This is part of the GNU Guile Reference Manual. @c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2006 @c Free Software Foundation, Inc. @c See the file guile.texi for copying conditions. @page @node Debugging Features @section Debugging Features Guile includes debugging tools to help you work out what is going wrong when a program signals an error or behaves differently to how you would expect. This chapter describes how to use these tools. @menu * Debug Last Error:: Debugging the most recent error. * Interactive Debugger:: Using the interactive debugger. * Tracing:: Tracing program execution. @end menu @node Debug Last Error @subsection Debugging the Most Recent Error When an error is signalled, Guile remembers the execution context where the error occurred. By default, Guile then displays only the most immediate information about where and why the error occurred, for example: @c Note: line break in "enter the debugger" to avoid an over-long @c line in both info and DVI. @lisp (make-string (* 4 (+ 3 #\s)) #\space) @print{} standard input:2:19: In procedure + in expression (+ 3 #\s): standard input:2:19: Wrong type argument: #\s ABORT: (wrong-type-arg) Type "(backtrace)" to get more information or "(debug)" to enter the debugger. @end lisp @noindent However, as the message above says, you can obtain much more information about the context of the error by typing @code{(backtrace)} or @code{(debug)}. @code{(backtrace)} displays the Scheme call stack at the point where the error occurred: @lisp (backtrace) @print{} Backtrace: In standard input: 2: 0* [make-string ... 2: 1* [* 4 ... 2: 2* [+ 3 #\s] Type "(debug-enable 'backtrace)" if you would like a backtrace automatically if an error occurs in the future. @end lisp @noindent In a more complex scenario than this one, this can be extremely useful for understanding where and why the error occurred. For more on the format of the displayed backtrace, see the subsection below. @code{(debug)} takes you into Guile's interactive debugger, which provides commands that allow you to @itemize @bullet @item display the Scheme call stack at the point where the error occurred (the @code{backtrace} command --- see @ref{Display Backtrace}) @item move up and down the call stack, to see in detail the expression being evaluated, or the procedure being applied, in each @dfn{frame} (the @code{up}, @code{down}, @code{frame}, @code{position}, @code{info args} and @code{info frame} commands --- see @ref{Frame Selection} and @ref{Frame Information}) @item examine the values of variables and expressions in the context of each frame (the @code{evaluate} command --- see @ref{Frame Evaluation}). @end itemize Use of the interactive debugger, including these commands, is described in @ref{Interactive Debugger}. @node Interactive Debugger @subsection Using the Interactive Debugger Guile's interactive debugger is a command line application that accepts commands from you for examining the stack and, if at a breakpoint, for continuing program execution in various ways. Unlike in the normal Guile REPL, commands are typed mostly without parentheses. When you first enter the debugger, it introduces itself with a message like this: @lisp This is the Guile debugger -- for help, type `help'. There are 3 frames on the stack. Frame 2 at standard input:36:19 [+ 3 #\s] debug> @end lisp @noindent ``debug>'' is the debugger's prompt, and a reminder that you are not in the normal Guile REPL. In case you find yourself in the debugger by mistake, the @code{quit} command will return you to the REPL. @deffn {Debugger Command} quit Exit the debugger. @end deffn The other available commands are described in the following subsections. @menu * Display Backtrace:: backtrace. * Frame Selection:: up, down, frame. * Frame Information:: info args, info frame, position. * Frame Evaluation:: evaluate. @end menu @node Display Backtrace @subsubsection Display Backtrace The @code{backtrace} command, which can also be invoked as @code{bt} or @code{where}, displays the call stack (aka backtrace) at the point where the debugger was entered: @lisp debug> bt In standard input: 36: 0* [make-string ... 36: 1* [* 4 ... 36: 2* [+ 3 #\s] @end lisp @deffn {Debugger Command} backtrace [count] @deffnx {Debugger Command} bt [count] @deffnx {Debugger Command} where [count] Print backtrace of all stack frames, or of the innermost @var{count} frames. With a negative argument, print the outermost -@var{count} frames. If the number of frames isn't explicitly given, the debug option @code{depth} determines the maximum number of frames printed. @end deffn The format of the displayed backtrace is the same as for the @code{backtrace} procedure. @node Frame Selection @subsubsection Frame Selection A call stack consists of a sequence of stack @dfn{frames}, with each frame describing one level of the nested evaluations and applications that the program was executing when it hit a breakpoint or an error. Frames are numbered such that frame 0 is the outermost --- i.e. the operation on the call stack that began least recently --- and frame N-1 the innermost (where N is the total number of frames on the stack). When you enter the debugger, the innermost frame is selected, which means that the commands for getting information about the ``current'' frame, or for evaluating expressions in the context of the current frame, will do so by default with respect to the innermost frame. To select a different frame, so that these operations will apply to it instead, use the @code{up}, @code{down} and @code{frame} commands like this: @lisp debug> up Frame 1 at standard input:36:14 [* 4 ... debug> frame 0 Frame 0 at standard input:36:1 [make-string ... debug> down Frame 1 at standard input:36:14 [* 4 ... @end lisp @deffn {Debugger Command} up [n] Move @var{n} frames up the stack. For positive @var{n}, this advances toward the outermost frame, to lower frame numbers, to frames that have existed longer. @var{n} defaults to one. @end deffn @deffn {Debugger Command} down [n] Move @var{n} frames down the stack. For positive @var{n}, this advances toward the innermost frame, to higher frame numbers, to frames that were created more recently. @var{n} defaults to one. @end deffn @deffn {Debugger Command} frame [n] Select and print a stack frame. With no argument, print the selected stack frame. (See also ``info frame''.) An argument specifies the frame to select; it must be a stack-frame number. @end deffn @node Frame Information @subsubsection Frame Information The following commands return detailed information about the currently selected frame. @deffn {Debugger Command} {info frame} Display a verbose description of the selected frame. The information that this command provides is equivalent to what can be deduced from the one line summary for the frame that appears in a backtrace, but is presented and explained more clearly. @end deffn @deffn {Debugger Command} {info args} Display the argument variables of the current stack frame. Arguments can also be seen in the backtrace, but are presented more clearly by this command. @end deffn @deffn {Debugger Command} position Display the name of the source file that the current expression comes from, and the line and column number of the expression's opening parenthesis within that file. This information is only available when the @code{positions} read option is enabled (@pxref{Reader options}). @end deffn @node Frame Evaluation @subsubsection Frame Evaluation The @code{evaluate} command is most useful for querying the value of a variable, either global or local, in the environment of the selected stack frame, but it can be used more generally to evaluate any expression. @deffn {Debugger Command} evaluate expression Evaluate an expression in the environment of the selected stack frame. The expression must appear on the same line as the command, however it may be continued over multiple lines. @end deffn @node Tracing @subsection Tracing The @code{(ice-9 debug)} module implements tracing of procedure applications. When a procedure is @dfn{traced}, it means that every call to that procedure is reported to the user during a program run. The idea is that you can mark a collection of procedures for tracing, and Guile will subsequently print out a line of the form @smalllisp | | [@var{procedure} @var{args} @dots{}] @end smalllisp whenever a marked procedure is about to be applied to its arguments. This can help a programmer determine whether a function is being called at the wrong time or with the wrong set of arguments. In addition, the indentation of the output is useful for demonstrating how the traced applications are or are not tail recursive with respect to each other. Thus, a trace of a non-tail recursive factorial implementation looks like this: @smalllisp [fact1 4] | [fact1 3] | | [fact1 2] | | | [fact1 1] | | | | [fact1 0] | | | | 1 | | | 1 | | 2 | 6 24 @end smalllisp While a typical tail recursive implementation would look more like this: @smalllisp [fact2 4] [facti 1 4] [facti 4 3] [facti 12 2] [facti 24 1] [facti 24 0] 24 @end smalllisp @deffn {Scheme Procedure} trace procedure Enable tracing for @code{procedure}. While a program is being run, Guile will print a brief report at each call to a traced procedure, advising the user which procedure was called and the arguments that were passed to it. @end deffn @deffn {Scheme Procedure} untrace procedure Disable tracing for @code{procedure}. @end deffn Here is another example: @lisp (define (rev ls) (if (null? ls) '() (append (rev (cdr ls)) (cons (car ls) '())))) @result{} rev (trace rev) @result{} (rev) (rev '(a b c d e)) @result{} [rev (a b c d e)] | [rev (b c d e)] | | [rev (c d e)] | | | [rev (d e)] | | | | [rev (e)] | | | | | [rev ()] | | | | | () | | | | (e) | | | (e d) | | (e d c) | (e d c b) (e d c b a) (e d c b a) @end lisp Note the way Guile indents the output, illustrating the depth of execution at each procedure call. This can be used to demonstrate, for example, that Guile implements self-tail-recursion properly: @lisp (define (rev ls sl) (if (null? ls) sl (rev (cdr ls) (cons (car ls) sl)))) @result{} rev (trace rev) @result{} (rev) (rev '(a b c d e) '()) @result{} [rev (a b c d e) ()] [rev (b c d e) (a)] [rev (c d e) (b a)] [rev (d e) (c b a)] [rev (e) (d c b a)] [rev () (e d c b a)] (e d c b a) (e d c b a) @end lisp Since the tail call is effectively optimized to a @code{goto} statement, there is no need for Guile to create a new stack frame for each iteration. Tracing reveals this optimization in operation. @c Local Variables: @c TeX-master: "guile.texi" @c End: