summaryrefslogtreecommitdiff
path: root/doc/ref/debugging.texi
blob: 28607c551d1ef3f0212c8773e4387efe46d0c0e3 (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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
@page
@node Debugger User Interface
@chapter Debugger User Interface

@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.
* Stacks and Frames::	Examine the state of an interrupted program.
@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
@appendixsec Backtrace

@node Stacks and Frames
@appendixsec Stacks and Frames

When a running program is interrupted, usually upon reaching an error or
breakpoint, its state is represented by a @dfn{stack} of suspended
function calls, each of which is called a @dfn{frame}.  The programmer
can learn more about the program's state at the point of interruption by
inspecting and modifying these frames.

@deffn primitive stack? obj
Return @code{#t} if @var{obj} is a calling stack.
@end deffn

@deffn primitive make-stack
@end deffn

@deffn syntax start-stack id exp
Evaluate @var{exp} on a new calling stack with identity @var{id}.  If
@var{exp} is interrupted during evaluation, backtraces will not display
frames farther back than @var{exp}'s top-level form.  This macro is a
way of artificially limiting backtraces and stack procedures, largely as
a convenience to the user.
@end deffn

@deffn primitive stack-id stack
Return the identifier given to @var{stack} by @code{start-stack}.
@end deffn

@deffn primitive stack-ref
@end deffn

@deffn primitive stack-length
@end deffn

@deffn primitive frame?
@end deffn

@deffn primitive last-stack-frame
@end deffn

@deffn primitive frame-number
@end deffn

@deffn primitive frame-source
@end deffn

@deffn primitive frame-procedure
@end deffn

@deffn primitive frame-arguments
@end deffn

@deffn primitive frame-previous
@end deffn

@deffn primitive frame-next
@end deffn

@deffn primitive frame-real?
@end deffn

@deffn primitive frame-procedure?
@end deffn

@deffn primitive frame-evaluating-args?
@end deffn

@deffn primitive frame-overflow
@end deffn