mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-01 12:20:26 +02:00
115 lines
3.2 KiB
Text
115 lines
3.2 KiB
Text
@page
|
|
@node Debugging Features
|
|
@chapter Debugging Features
|
|
|
|
@c --- The title and introduction of this appendix need to
|
|
@c distinguish this clearly from the chapter on the internal
|
|
@c debugging interface.
|
|
|
|
When debugging a program, programmers often find it helpful to examine
|
|
the program's internal status while it runs: the values of internal
|
|
variables, the choices made in @code{if} and @code{cond} statements, and
|
|
so forth. Guile Scheme provides a debugging interface that programmers
|
|
can use to single-step through Scheme functions and examine symbol
|
|
bindings. This is different from the @ref{Debugging}, which permits
|
|
programmers to debug the Guile interpreter itself. Most programmers
|
|
will be more interested in debugging their own Scheme programs than the
|
|
interpreter which evaluates them.
|
|
|
|
[FIXME: should we include examples of traditional debuggers
|
|
and explain why they can't be used to debug interpreted Scheme or Lisp?]
|
|
|
|
@menu
|
|
* Single-Step:: Execute a program or function one step at a time.
|
|
* Trace:: Print a report each time a given function is called.
|
|
* Backtrace:: See a list of the statements that caused an error.
|
|
@end menu
|
|
|
|
|
|
@node Single-Step
|
|
@section Single-Step
|
|
|
|
|
|
@node Trace
|
|
@section Trace
|
|
|
|
When a function is @dfn{traced}, it means that every call to that
|
|
function is reported to the user during a program run. This can help a
|
|
programmer determine whether a function is being called at the wrong
|
|
time or with the wrong set of arguments.
|
|
|
|
@defun trace function
|
|
Enable debug tracing on @code{function}. While a program is being run, Guile
|
|
will print a brief report at each call to a traced function,
|
|
advising the user which function was called and the arguments that were
|
|
passed to it.
|
|
@end defun
|
|
|
|
@defun untrace function
|
|
Disable debug tracing for @code{function}.
|
|
@end defun
|
|
|
|
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 function 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. Using @code{trace} here helps us see why this is so.
|
|
|
|
|
|
@node Backtrace
|
|
@section Backtrace
|
|
|
|
@deffn {Scheme Procedure} backtrace
|
|
@deffnx {C Function} scm_backtrace ()
|
|
Display a backtrace of the stack saved by the last error
|
|
to the current output port.
|
|
@end deffn
|