mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-01 12:20:26 +02:00
actually present in the 1.8.x series... * api-debug.texi (Breakpoints): Removed. * scheme-debugging.texi (Debugging Features): Breakpoint-related text removed. (Intro to Breakpoints, Breakpoints Overview, Source Breakpoints, Procedural Breakpoints, Setting Breakpoints, break! trace! trace-subtree!, Accessing Breakpoints, Breakpoint Behaviours, Enabling and Disabling, Deleting Breakpoints, Breakpoint Information, Other Breakpoint Types, Single Stepping, Run To Frame Exit, Continue Execution, New Tracing, Tracing Compared): Removed. (Old Tracing): Text moved to parent Tracing node. (Tracing): Removed introductory statement about two tracing implementations. (Display Backtrace): Remove ref to Backtrace Format node. (Backtrace Format): Removed (as it was empty). (Interactive Debugger, Frame Selection, Frame Information, Frame Evaluation): Merge textual improvements from CVS HEAD. (Leave Debugger): Removed. (Interactive Debugger): Document quit command here, as in CVS HEAD.
367 lines
11 KiB
Text
367 lines
11 KiB
Text
@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:
|