summaryrefslogtreecommitdiff
path: root/doc/ref/debugging.texi
blob: 06a61473d2e9d05caa36d54ebad419828508e1c8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
@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