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
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
|
@c -*-texinfo-*-
@c This is part of the GNU Guile Reference Manual.
@c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004
@c Free Software Foundation, Inc.
@c See the file guile.texi for copying conditions.
@page
@node Debugging
@section Debugging Infrastructure
In order to understand Guile's debugging facilities, you first need to
understand a little about how the evaluator works and what the Scheme
stack is. With that in place we explain the low level trap calls that
the evaluator can be configured to make, and the trap and breakpoint
infrastructure that builds on top of those calls.
@menu
* Evaluation Model:: Evaluation and the Scheme stack.
* Debug on Error:: Debugging when an error occurs.
* Using Traps::
@end menu
@node Evaluation Model
@subsection Evaluation and the Scheme Stack
The idea of the Scheme stack is central to a lot of debugging. It
always exists implicitly, as a result of the way that the Guile
evaluator works, and can be summoned into concrete existence as a
first-class Scheme value by the @code{make-stack} call, so that an
introspective Scheme program -- such as a debugger -- can present it in
some way and allow the user to query its details. The first thing to
understand, therefore, is how the workings of the evaluator build up the
stack.
@cindex Evaluations
@cindex Applications
Broadly speaking, the evaluator performs @dfn{evaluations} and
@dfn{applications}. An evaluation means that it is looking at a source
code expression like @code{(+ x 5)} or @code{(if msg (loop))}, deciding
whether the top level of the expression is a procedure call, macro,
builtin syntax, or whatever, and doing some appropriate processing in
each case. (In the examples here, @code{(+ x 5)} would normally be a
procedure call, and @code{(if msg (loop))} builtin syntax.) For a
procedure call, ``appropriate processing'' includes evaluating the
procedure's arguments, as that must happen before the procedure itself
can be called. An application means calling a procedure once its
arguments have been calculated.
@cindex Stack
@cindex Frames
@cindex Stack frames
Typically evaluations and applications alternate with each other, and
together they form a @dfn{stack} of operations pending completion. This
is because, on the one hand, evaluation of an expression like @code{(+ x
5)} requires --- once its arguments have been calculated --- an
application (in this case, of the procedure @code{+}) before it can
complete and return a result, and, on the other hand, the application of
a procedure written in Scheme involves evaluating the sequence of
expressions that constitute that procedure's code. Each level on this
stack is called a @dfn{frame}.
Therefore, when an error occurs in a running program, or the program
hits a breakpoint, or in fact at any point that the programmer chooses,
its state at that point can be represented by a @dfn{stack} of all the
evaluations and procedure applications that are logically in progress at
that time, each of which is known as a @dfn{frame}. The programmer can
learn more about the program's state at that point by inspecting the
stack and its frames.
@menu
* Capturing the Stack or Innermost Stack Frame::
* Examining the Stack::
* Examining Stack Frames::
* Source Properties:: Remembering the source of an expression.
* Decoding Memoized Source Expressions::
* Starting a New Stack::
@end menu
@node Capturing the Stack or Innermost Stack Frame
@subsubsection Capturing the Stack or Innermost Stack Frame
A Scheme program can use the @code{make-stack} primitive anywhere in its
code, with first arg @code{#t}, to construct a Scheme value that
describes the Scheme stack at that point.
@lisp
(make-stack #t)
@result{}
#<stack 805c840:808d250>
@end lisp
@deffn {Scheme Procedure} make-stack obj . args
@deffnx {C Function} scm_make_stack (obj, args)
Create a new stack. If @var{obj} is @code{#t}, the current
evaluation stack is used for creating the stack frames,
otherwise the frames are taken from @var{obj} (which must be
either a debug object or a continuation).
@var{args} should be a list containing any combination of
integer, procedure and @code{#t} values.
These values specify various ways of cutting away uninteresting
stack frames from the top and bottom of the stack that
@code{make-stack} returns. They come in pairs like this:
@code{(@var{inner_cut_1} @var{outer_cut_1} @var{inner_cut_2}
@var{outer_cut_2} @dots{})}.
Each @var{inner_cut_N} can be @code{#t}, an integer, or a
procedure. @code{#t} means to cut away all frames up to but
excluding the first user module frame. An integer means to cut
away exactly that number of frames. A procedure means to cut
away all frames up to but excluding the application frame whose
procedure matches the specified one.
Each @var{outer_cut_N} can be an integer or a procedure. An
integer means to cut away that number of frames. A procedure
means to cut away frames down to but excluding the application
frame whose procedure matches the specified one.
If the @var{outer_cut_N} of the last pair is missing, it is
taken as 0.
@end deffn
@deffn {Scheme Procedure} last-stack-frame obj
@deffnx {C Function} scm_last_stack_frame (obj)
Return the last (innermost) frame of @var{obj}, which must be
either a debug object or a continuation.
@end deffn
@node Examining the Stack
@subsubsection Examining the Stack
@deffn {Scheme Procedure} stack? obj
@deffnx {C Function} scm_stack_p (obj)
Return @code{#t} if @var{obj} is a calling stack.
@end deffn
@deffn {Scheme Procedure} stack-id stack
@deffnx {C Function} scm_stack_id (stack)
Return the identifier given to @var{stack} by @code{start-stack}.
@end deffn
@deffn {Scheme Procedure} stack-length stack
@deffnx {C Function} scm_stack_length (stack)
Return the length of @var{stack}.
@end deffn
@deffn {Scheme Procedure} stack-ref stack index
@deffnx {C Function} scm_stack_ref (stack, index)
Return the @var{index}'th frame from @var{stack}.
@end deffn
@deffn {Scheme Procedure} display-backtrace stack port [first [depth [highlights]]]
@deffnx {C Function} scm_display_backtrace_with_highlights (stack, port, first, depth, highlights)
@deffnx {C Function} scm_display_backtrace (stack, port, first, depth)
Display a backtrace to the output port @var{port}. @var{stack}
is the stack to take the backtrace from, @var{first} specifies
where in the stack to start and @var{depth} how much frames
to display. Both @var{first} and @var{depth} can be @code{#f},
which means that default values will be used.
When @var{highlights} is given,
it should be a list and all members of it are highligthed in
the backtrace.
@end deffn
@node Examining Stack Frames
@subsubsection Examining Stack Frames
@deffn {Scheme Procedure} frame? obj
@deffnx {C Function} scm_frame_p (obj)
Return @code{#t} if @var{obj} is a stack frame.
@end deffn
@deffn {Scheme Procedure} frame-number frame
@deffnx {C Function} scm_frame_number (frame)
Return the frame number of @var{frame}.
@end deffn
@deffn {Scheme Procedure} frame-previous frame
@deffnx {C Function} scm_frame_previous (frame)
Return the previous frame of @var{frame}, or @code{#f} if
@var{frame} is the first frame in its stack.
@end deffn
@deffn {Scheme Procedure} frame-next frame
@deffnx {C Function} scm_frame_next (frame)
Return the next frame of @var{frame}, or @code{#f} if
@var{frame} is the last frame in its stack.
@end deffn
@deffn {Scheme Procedure} frame-source frame
@deffnx {C Function} scm_frame_source (frame)
Return the source of @var{frame}.
@end deffn
@deffn {Scheme Procedure} frame-procedure? frame
@deffnx {C Function} scm_frame_procedure_p (frame)
Return @code{#t} if a procedure is associated with @var{frame}.
@end deffn
@deffn {Scheme Procedure} frame-procedure frame
@deffnx {C Function} scm_frame_procedure (frame)
Return the procedure for @var{frame}, or @code{#f} if no
procedure is associated with @var{frame}.
@end deffn
@deffn {Scheme Procedure} frame-arguments frame
@deffnx {C Function} scm_frame_arguments (frame)
Return the arguments of @var{frame}.
@end deffn
@deffn {Scheme Procedure} frame-evaluating-args? frame
@deffnx {C Function} scm_frame_evaluating_args_p (frame)
Return @code{#t} if @var{frame} contains evaluated arguments.
@end deffn
@deffn {Scheme Procedure} frame-overflow? frame
@deffnx {C Function} scm_frame_overflow_p (frame)
Return @code{#t} if @var{frame} is an overflow frame.
@end deffn
@deffn {Scheme Procedure} frame-real? frame
@deffnx {C Function} scm_frame_real_p (frame)
Return @code{#t} if @var{frame} is a real frame.
@end deffn
@deffn {Scheme Procedure} display-application frame [port [indent]]
@deffnx {C Function} scm_display_application (frame, port, indent)
Display a procedure application @var{frame} to the output port
@var{port}. @var{indent} specifies the indentation of the
output.
@end deffn
@node Source Properties
@subsubsection Source Properties
@cindex source properties
As Guile reads in Scheme code from file or from standard input, it
remembers the file name, line number and column number where each
expression begins. These pieces of information are known as the
@dfn{source properties} of the expression. If an expression undergoes
transformation --- for example, if there is a syntax transformer in
effect, or the expression is a macro call --- the source properties are
copied from the untransformed to the transformed expression so that, if
an error occurs when evaluating the transformed expression, Guile's
debugger can point back to the file and location where the expression
originated.
The way that source properties are stored means that Guile can only
associate source properties with parenthesized expressions, and not, for
example, with individual symbols, numbers or strings. The difference
can be seen by typing @code{(xxx)} and @code{xxx} at the Guile prompt
(where the variable @code{xxx} has not been defined):
@example
guile> (xxx)
standard input:2:1: In expression (xxx):
standard input:2:1: Unbound variable: xxx
ABORT: (unbound-variable)
guile> xxx
<unnamed port>: In expression xxx:
<unnamed port>: Unbound variable: xxx
ABORT: (unbound-variable)
@end example
@noindent
In the latter case, no source properties were stored, so the best that
Guile could say regarding the location of the problem was ``<unnamed
port>''.
The recording of source properties is controlled by the read option
named ``positions'' (@pxref{Reader options}). This option is switched
@emph{on} by default, together with the debug options ``debug'' and
``backtrace'' (@pxref{Debugger options}), when Guile is run
interactively; all these options are @emph{off} by default when Guile
runs a script non-interactively.
The following procedures can be used to access and set the source
properties of read expressions.
@deffn {Scheme Procedure} set-source-properties! obj plist
@deffnx {C Function} scm_set_source_properties_x (obj, plist)
Install the association list @var{plist} as the source property
list for @var{obj}.
@end deffn
@deffn {Scheme Procedure} set-source-property! obj key datum
@deffnx {C Function} scm_set_source_property_x (obj, key, datum)
Set the source property of object @var{obj}, which is specified by
@var{key} to @var{datum}. Normally, the key will be a symbol.
@end deffn
@deffn {Scheme Procedure} source-properties obj
@deffnx {C Function} scm_source_properties (obj)
Return the source property association list of @var{obj}.
@end deffn
@deffn {Scheme Procedure} source-property obj key
@deffnx {C Function} scm_source_property (obj, key)
Return the source property specified by @var{key} from
@var{obj}'s source property list.
@end deffn
In practice there are only two ways that you should use the ability to
set an expression's source breakpoints.
@itemize
@item
To set a breakpoint on an expression, use @code{(set-source-property!
@var{expr} 'breakpoint #t)}. If you do this, you should also set the
@code{traps} and @code{enter-frame-handler} trap options
(@pxref{Evaluator trap options}) and @code{breakpoints} debug option
(@pxref{Debugger options}) appropriately, and the evaluator will then
call your enter frame handler whenever it is about to evaluate that
expression.
@item
To make a read or constructed expression appear to have come from a
different source than what the expression's source properties already
say, you can use @code{set-source-property!} to set the expression's
@code{filename}, @code{line} and @code{column} properties. The
properties that you set will then show up later if that expression is
involved in a backtrace or error report.
@end itemize
If you are looking for a way to attach arbitrary information to an
expression other than these properties, you should use
@code{make-object-property} instead (@pxref{Object Properties}), because
that will avoid bloating the source property hash table, which is really
only intended for the specific purposes described in this section.
@node Decoding Memoized Source Expressions
@subsubsection Decoding Memoized Source Expressions
@deffn {Scheme Procedure} memoized? obj
@deffnx {C Function} scm_memoized_p (obj)
Return @code{#t} if @var{obj} is memoized.
@end deffn
@deffn {Scheme Procedure} unmemoize m
@deffnx {C Function} scm_unmemoize (m)
Unmemoize the memoized expression @var{m},
@end deffn
@deffn {Scheme Procedure} memoized-environment m
@deffnx {C Function} scm_memoized_environment (m)
Return the environment of the memoized expression @var{m}.
@end deffn
@node Starting a New Stack
@subsubsection Starting a New Stack
@deffn {Scheme 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
@node Debug on Error
@subsection Debugging when an error occurs
@deffn {Scheme Procedure} backtrace [highlights]
@deffnx {C Function} scm_backtrace_with_highlights (highlights)
@deffnx {C Function} scm_backtrace ()
Display a backtrace of the stack saved by the last error
to the current output port. When @var{highlights} is given,
it should be a list and all members of it are highligthed in
the backtrace.
@end deffn
@deffn {Scheme Procedure} debug
Invoke the Guile debugger to explore the context of the last error.
@end deffn
@node Using Traps
@subsection Using Traps
@deffn {Scheme Procedure} with-traps thunk
@deffnx {C Function} scm_with_traps (thunk)
Call @var{thunk} with traps enabled.
@end deffn
@deffn {Scheme Procedure} debug-object? obj
@deffnx {C Function} scm_debug_object_p (obj)
Return @code{#t} if @var{obj} is a debug object.
@end deffn
@c Local Variables:
@c TeX-master: "guile.texi"
@c End:
|