Commit | Line | Data |
---|---|---|
07d83abe MV |
1 | @c -*-texinfo-*- |
2 | @c This is part of the GNU Guile Reference Manual. | |
e10cf6b9 | 3 | @c Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2007, 2010 |
07d83abe MV |
4 | @c Free Software Foundation, Inc. |
5 | @c See the file guile.texi for copying conditions. | |
6 | ||
07d83abe MV |
7 | @node Debugging |
8 | @section Debugging Infrastructure | |
9 | ||
b20ef3a6 | 10 | @cindex Debugging |
5af872e1 | 11 | In order to understand Guile's debugging facilities, you first need to |
42cb9b03 | 12 | understand a little about how Guile represent the Scheme control stack. |
a1652dec AW |
13 | With that in place we explain the low level trap calls that the virtual |
14 | machine can be configured to make, and the trap and breakpoint | |
5af872e1 NJ |
15 | infrastructure that builds on top of those calls. |
16 | ||
07d83abe | 17 | @menu |
5af872e1 | 18 | * Evaluation Model:: Evaluation and the Scheme stack. |
659c1e29 | 19 | * Programmatic Error Handling:: Debugging when an error occurs. |
24dbb5ed | 20 | * Traps:: |
24dbb5ed | 21 | * Debugging Examples:: |
5af872e1 NJ |
22 | @end menu |
23 | ||
24 | @node Evaluation Model | |
25 | @subsection Evaluation and the Scheme Stack | |
26 | ||
42cb9b03 AW |
27 | The idea of the Scheme stack is central to a lot of debugging. The |
28 | Scheme stack is a reified representation of the pending function returns | |
a1652dec | 29 | in an expression's continuation. As Guile implements function calls |
42cb9b03 | 30 | using a stack, this reification takes the form of a number of nested |
a1652dec AW |
31 | stack frames, each of which corresponds to the application of a |
32 | procedure to a set of arguments. | |
42cb9b03 AW |
33 | |
34 | A Scheme stack always exists implicitly, and can be summoned into | |
35 | concrete existence as a first-class Scheme value by the | |
36 | @code{make-stack} call, so that an introspective Scheme program -- such | |
37 | as a debugger -- can present it in some way and allow the user to query | |
38 | its details. The first thing to understand, therefore, is how Guile's | |
39 | function call convention creates the stack. | |
40 | ||
41 | Broadly speaking, Guile represents all control flow on a stack. Calling | |
42 | a function involves pushing an empty frame on the stack, then evaluating | |
43 | the procedure and its arguments, then fixing up the new frame so that it | |
44 | points to the old one. Frames on the stack are thus linked together. A | |
45 | tail call is the same, except it reuses the existing frame instead of | |
46 | pushing on a new one. | |
47 | ||
48 | In this way, the only frames that are on the stack are ``active'' | |
49 | frames, frames which need to do some work before the computation is | |
50 | complete. On the other hand, a function that has tail-called another | |
51 | function will not be on the stack, as it has no work left to do. | |
5af872e1 NJ |
52 | |
53 | Therefore, when an error occurs in a running program, or the program | |
54 | hits a breakpoint, or in fact at any point that the programmer chooses, | |
55 | its state at that point can be represented by a @dfn{stack} of all the | |
a1652dec AW |
56 | procedure applications that are logically in progress at that time, each |
57 | of which is known as a @dfn{frame}. The programmer can learn more about | |
58 | the program's state at that point by inspecting the stack and its | |
59 | frames. | |
5af872e1 NJ |
60 | |
61 | @menu | |
07d83abe MV |
62 | * Capturing the Stack or Innermost Stack Frame:: |
63 | * Examining the Stack:: | |
64 | * Examining Stack Frames:: | |
5af872e1 | 65 | * Source Properties:: Remembering the source of an expression. |
07d83abe MV |
66 | * Starting a New Stack:: |
67 | @end menu | |
68 | ||
07d83abe | 69 | @node Capturing the Stack or Innermost Stack Frame |
5af872e1 | 70 | @subsubsection Capturing the Stack or Innermost Stack Frame |
07d83abe | 71 | |
5af872e1 NJ |
72 | A Scheme program can use the @code{make-stack} primitive anywhere in its |
73 | code, with first arg @code{#t}, to construct a Scheme value that | |
74 | describes the Scheme stack at that point. | |
75 | ||
76 | @lisp | |
77 | (make-stack #t) | |
78 | @result{} | |
a1652dec | 79 | #<stack 25205a0> |
5af872e1 | 80 | @end lisp |
07d83abe MV |
81 | |
82 | @deffn {Scheme Procedure} make-stack obj . args | |
83 | @deffnx {C Function} scm_make_stack (obj, args) | |
84 | Create a new stack. If @var{obj} is @code{#t}, the current | |
85 | evaluation stack is used for creating the stack frames, | |
86 | otherwise the frames are taken from @var{obj} (which must be | |
42cb9b03 | 87 | a continuation or a frame object). |
07d83abe MV |
88 | |
89 | @var{args} should be a list containing any combination of | |
42cb9b03 | 90 | integer, procedure, prompt tag and @code{#t} values. |
07d83abe MV |
91 | |
92 | These values specify various ways of cutting away uninteresting | |
93 | stack frames from the top and bottom of the stack that | |
94 | @code{make-stack} returns. They come in pairs like this: | |
95 | @code{(@var{inner_cut_1} @var{outer_cut_1} @var{inner_cut_2} | |
96 | @var{outer_cut_2} @dots{})}. | |
97 | ||
42cb9b03 AW |
98 | Each @var{inner_cut_N} can be @code{#t}, an integer, a prompt |
99 | tag, or a procedure. @code{#t} means to cut away all frames up | |
100 | to but excluding the first user module frame. An integer means | |
101 | to cut away exactly that number of frames. A prompt tag means | |
102 | to cut away all frames that are inside a prompt with the given | |
103 | tag. A procedure means to cut away all frames up to but | |
104 | excluding the application frame whose procedure matches the | |
105 | specified one. | |
106 | ||
107 | Each @var{outer_cut_N} can be an integer, a prompt tag, or a | |
108 | procedure. An integer means to cut away that number of frames. | |
109 | A prompt tag means to cut away all frames that are outside a | |
110 | prompt with the given tag. A procedure means to cut away | |
111 | frames down to but excluding the application frame whose | |
07d83abe MV |
112 | procedure matches the specified one. |
113 | ||
07d83abe MV |
114 | If the @var{outer_cut_N} of the last pair is missing, it is |
115 | taken as 0. | |
116 | @end deffn | |
117 | ||
07d83abe MV |
118 | |
119 | @node Examining the Stack | |
5af872e1 | 120 | @subsubsection Examining the Stack |
07d83abe MV |
121 | |
122 | @deffn {Scheme Procedure} stack? obj | |
123 | @deffnx {C Function} scm_stack_p (obj) | |
124 | Return @code{#t} if @var{obj} is a calling stack. | |
125 | @end deffn | |
126 | ||
127 | @deffn {Scheme Procedure} stack-id stack | |
128 | @deffnx {C Function} scm_stack_id (stack) | |
129 | Return the identifier given to @var{stack} by @code{start-stack}. | |
130 | @end deffn | |
131 | ||
132 | @deffn {Scheme Procedure} stack-length stack | |
133 | @deffnx {C Function} scm_stack_length (stack) | |
134 | Return the length of @var{stack}. | |
135 | @end deffn | |
136 | ||
137 | @deffn {Scheme Procedure} stack-ref stack index | |
138 | @deffnx {C Function} scm_stack_ref (stack, index) | |
139 | Return the @var{index}'th frame from @var{stack}. | |
140 | @end deffn | |
141 | ||
7cd44c6d MV |
142 | @deffn {Scheme Procedure} display-backtrace stack port [first [depth [highlights]]] |
143 | @deffnx {C Function} scm_display_backtrace_with_highlights (stack, port, first, depth, highlights) | |
07d83abe | 144 | @deffnx {C Function} scm_display_backtrace (stack, port, first, depth) |
fc3d5c43 | 145 | Display a backtrace to the output port @var{port}. @var{stack} |
07d83abe | 146 | is the stack to take the backtrace from, @var{first} specifies |
fc3d5c43 NJ |
147 | where in the stack to start and @var{depth} how many frames |
148 | to display. @var{first} and @var{depth} can be @code{#f}, | |
07d83abe | 149 | which means that default values will be used. |
fc3d5c43 NJ |
150 | If @var{highlights} is given it should be a list; the elements |
151 | of this list will be highlighted wherever they appear in the | |
152 | backtrace. | |
07d83abe MV |
153 | @end deffn |
154 | ||
155 | ||
156 | @node Examining Stack Frames | |
5af872e1 | 157 | @subsubsection Examining Stack Frames |
07d83abe MV |
158 | |
159 | @deffn {Scheme Procedure} frame? obj | |
160 | @deffnx {C Function} scm_frame_p (obj) | |
161 | Return @code{#t} if @var{obj} is a stack frame. | |
162 | @end deffn | |
163 | ||
07d83abe MV |
164 | @deffn {Scheme Procedure} frame-previous frame |
165 | @deffnx {C Function} scm_frame_previous (frame) | |
166 | Return the previous frame of @var{frame}, or @code{#f} if | |
167 | @var{frame} is the first frame in its stack. | |
168 | @end deffn | |
169 | ||
07d83abe MV |
170 | @deffn {Scheme Procedure} frame-procedure frame |
171 | @deffnx {C Function} scm_frame_procedure (frame) | |
172 | Return the procedure for @var{frame}, or @code{#f} if no | |
173 | procedure is associated with @var{frame}. | |
174 | @end deffn | |
175 | ||
176 | @deffn {Scheme Procedure} frame-arguments frame | |
177 | @deffnx {C Function} scm_frame_arguments (frame) | |
178 | Return the arguments of @var{frame}. | |
179 | @end deffn | |
180 | ||
07d83abe MV |
181 | @deffn {Scheme Procedure} display-application frame [port [indent]] |
182 | @deffnx {C Function} scm_display_application (frame, port, indent) | |
183 | Display a procedure application @var{frame} to the output port | |
184 | @var{port}. @var{indent} specifies the indentation of the | |
185 | output. | |
186 | @end deffn | |
187 | ||
188 | ||
5af872e1 NJ |
189 | @node Source Properties |
190 | @subsubsection Source Properties | |
191 | ||
192 | @cindex source properties | |
193 | As Guile reads in Scheme code from file or from standard input, it | |
194 | remembers the file name, line number and column number where each | |
42cb9b03 AW |
195 | expression begins. These pieces of information are known as the |
196 | @dfn{source properties} of the expression. Syntax expanders and the | |
197 | compiler propagate these source properties to compiled procedures, so | |
198 | that, if an error occurs when evaluating the transformed expression, | |
199 | Guile's debugger can point back to the file and location where the | |
200 | expression originated. | |
5af872e1 NJ |
201 | |
202 | The way that source properties are stored means that Guile can only | |
203 | associate source properties with parenthesized expressions, and not, for | |
204 | example, with individual symbols, numbers or strings. The difference | |
205 | can be seen by typing @code{(xxx)} and @code{xxx} at the Guile prompt | |
206 | (where the variable @code{xxx} has not been defined): | |
207 | ||
208 | @example | |
a1652dec AW |
209 | scheme@@(guile-user)> (xxx) |
210 | <unnamed port>:4:1: In procedure module-lookup: | |
211 | <unnamed port>:4:1: Unbound variable: xxx | |
212 | ||
213 | scheme@@(guile-user)> xxx | |
214 | ERROR: In procedure module-lookup: | |
215 | ERROR: Unbound variable: xxx | |
5af872e1 NJ |
216 | @end example |
217 | ||
218 | @noindent | |
a1652dec AW |
219 | In the latter case, no source properties were stored, so the error |
220 | doesn't have any source information. | |
5af872e1 NJ |
221 | |
222 | The recording of source properties is controlled by the read option | |
1518f649 | 223 | named ``positions'' (@pxref{Scheme Read}). This option is switched |
42cb9b03 | 224 | @emph{on} by default. |
5af872e1 NJ |
225 | |
226 | The following procedures can be used to access and set the source | |
227 | properties of read expressions. | |
228 | ||
916f175f NJ |
229 | @deffn {Scheme Procedure} set-source-properties! obj alist |
230 | @deffnx {C Function} scm_set_source_properties_x (obj, alist) | |
231 | Install the association list @var{alist} as the source property | |
5af872e1 NJ |
232 | list for @var{obj}. |
233 | @end deffn | |
234 | ||
235 | @deffn {Scheme Procedure} set-source-property! obj key datum | |
236 | @deffnx {C Function} scm_set_source_property_x (obj, key, datum) | |
237 | Set the source property of object @var{obj}, which is specified by | |
238 | @var{key} to @var{datum}. Normally, the key will be a symbol. | |
239 | @end deffn | |
240 | ||
241 | @deffn {Scheme Procedure} source-properties obj | |
242 | @deffnx {C Function} scm_source_properties (obj) | |
243 | Return the source property association list of @var{obj}. | |
244 | @end deffn | |
245 | ||
246 | @deffn {Scheme Procedure} source-property obj key | |
247 | @deffnx {C Function} scm_source_property (obj, key) | |
916f175f NJ |
248 | Return the property specified by @var{key} from @var{obj}'s source |
249 | properties. | |
5af872e1 NJ |
250 | @end deffn |
251 | ||
42cb9b03 AW |
252 | If the @code{positions} reader option is enabled, each parenthesized |
253 | expression will have values set for the @code{filename}, @code{line} and | |
254 | @code{column} properties. | |
5af872e1 | 255 | |
1fc8dcc7 AW |
256 | If you're stuck with defmacros (@pxref{Defmacros}), and want to preserve |
257 | source information, the following helper function might be useful to | |
258 | you: | |
07d83abe | 259 | |
1fc8dcc7 AW |
260 | @deffn {Scheme Procedure} cons-source xorig x y |
261 | @deffnx {C Function} scm_cons_source (xorig, x, y) | |
262 | Create and return a new pair whose car and cdr are @var{x} and @var{y}. | |
263 | Any source properties associated with @var{xorig} are also associated | |
264 | with the new pair. | |
07d83abe MV |
265 | @end deffn |
266 | ||
267 | ||
268 | @node Starting a New Stack | |
5af872e1 | 269 | @subsubsection Starting a New Stack |
07d83abe MV |
270 | |
271 | @deffn {Scheme Syntax} start-stack id exp | |
272 | Evaluate @var{exp} on a new calling stack with identity @var{id}. If | |
273 | @var{exp} is interrupted during evaluation, backtraces will not display | |
274 | frames farther back than @var{exp}'s top-level form. This macro is a | |
275 | way of artificially limiting backtraces and stack procedures, largely as | |
276 | a convenience to the user. | |
277 | @end deffn | |
278 | ||
279 | ||
659c1e29 AW |
280 | @node Programmatic Error Handling |
281 | @subsection Programmatic Error Handling | |
282 | ||
283 | For better or for worse, all programs have bugs, and dealing with bugs | |
284 | is part of programming. This section deals with that class of bugs that | |
285 | causes an exception to be raised -- from your own code, from within a | |
286 | library, or from Guile itself. | |
287 | ||
288 | @menu | |
289 | * Catching Exceptions:: Handling errors after the stack is unwound. | |
290 | * Capturing Stacks:: Capturing the stack at the time of error. | |
291 | * Pre-Unwind Debugging:: Debugging before the exception is thrown. | |
292 | * Debug Options:: A historical interface to debugging. | |
293 | @end menu | |
294 | ||
295 | @node Catching Exceptions | |
296 | @subsubsection Catching Exceptions | |
5af872e1 | 297 | |
2202fd6c NJ |
298 | A common requirement is to be able to show as much useful context as |
299 | possible when a Scheme program hits an error. The most immediate | |
300 | information about an error is the kind of error that it is -- such as | |
301 | ``division by zero'' -- and any parameters that the code which signalled | |
302 | the error chose explicitly to provide. This information originates with | |
303 | the @code{error} or @code{throw} call (or their C code equivalents, if | |
304 | the error is detected by C code) that signals the error, and is passed | |
305 | automatically to the handler procedure of the innermost applicable | |
42cb9b03 | 306 | @code{catch} or @code{with-throw-handler} expression. |
2202fd6c | 307 | |
2202fd6c NJ |
308 | Therefore, to catch errors that occur within a chunk of Scheme code, and |
309 | to intercept basic information about those errors, you need to execute | |
42cb9b03 AW |
310 | that code inside the dynamic context of a @code{catch} or |
311 | @code{with-throw-handler} expression, or the equivalent in C. In Scheme, | |
312 | this means you need something like this: | |
2202fd6c NJ |
313 | |
314 | @lisp | |
315 | (catch #t | |
316 | (lambda () | |
317 | ;; Execute the code in which | |
318 | ;; you want to catch errors here. | |
319 | ...) | |
320 | (lambda (key . parameters) | |
321 | ;; Put the code which you want | |
322 | ;; to handle an error here. | |
323 | ...)) | |
324 | @end lisp | |
325 | ||
326 | @noindent | |
659c1e29 AW |
327 | The @code{catch} here can also be @code{with-throw-handler}; see |
328 | @ref{Throw Handlers} for information on the when you might want to use | |
329 | @code{with-throw-handler} instead of @code{catch}. | |
330 | ||
331 | For example, to print out a message and return #f when an error occurs, | |
332 | you might use: | |
333 | ||
334 | @smalllisp | |
335 | (define (catch-all thunk) | |
336 | (catch #t | |
337 | thunk | |
338 | (lambda (key . parameters) | |
339 | (format (current-error-port) | |
340 | "Uncaught throw to '~a: ~a\n" key parameters) | |
341 | #f))) | |
342 | ||
343 | (catch-all | |
344 | (lambda () (error "Not a vegetable: tomato"))) | |
3b3518e7 | 345 | @print{} Uncaught throw to 'misc-error: (#f ~A (Not a vegetable: tomato) #f) |
659c1e29 AW |
346 | @result{} #f |
347 | @end smalllisp | |
348 | ||
349 | The @code{#t} means that the catch is applicable to all kinds of error. | |
350 | If you want to restrict your catch to just one kind of error, you can | |
351 | put the symbol for that kind of error instead of @code{#t}. The | |
352 | equivalent to this in C would be something like this: | |
2202fd6c NJ |
353 | |
354 | @lisp | |
355 | SCM my_body_proc (void *body_data) | |
356 | @{ | |
357 | /* Execute the code in which | |
358 | you want to catch errors here. */ | |
359 | ... | |
360 | @} | |
361 | ||
fc3d5c43 NJ |
362 | SCM my_handler_proc (void *handler_data, |
363 | SCM key, | |
364 | SCM parameters) | |
2202fd6c NJ |
365 | @{ |
366 | /* Put the code which you want | |
367 | to handle an error here. */ | |
368 | ... | |
369 | @} | |
370 | ||
371 | @{ | |
372 | ... | |
373 | scm_c_catch (SCM_BOOL_T, | |
374 | my_body_proc, body_data, | |
375 | my_handler_proc, handler_data, | |
376 | NULL, NULL); | |
377 | ... | |
378 | @} | |
379 | @end lisp | |
380 | ||
381 | @noindent | |
382 | Again, as with the Scheme version, @code{scm_c_catch} could be replaced | |
42cb9b03 AW |
383 | by @code{scm_c_with_throw_handler}, and @code{SCM_BOOL_T} could instead |
384 | be the symbol for a particular kind of error. | |
2202fd6c | 385 | |
659c1e29 | 386 | @node Capturing Stacks |
2202fd6c NJ |
387 | @subsubsection Capturing the full error stack |
388 | ||
389 | The other interesting information about an error is the full Scheme | |
390 | stack at the point where the error occurred; in other words what | |
391 | innermost expression was being evaluated, what was the expression that | |
392 | called that one, and so on. If you want to write your code so that it | |
42cb9b03 | 393 | captures and can display this information as well, there are a couple |
2202fd6c NJ |
394 | important things to understand. |
395 | ||
42cb9b03 | 396 | Firstly, the stack at the point of the error needs to be explicitly |
2202fd6c | 397 | captured by a @code{make-stack} call (or the C equivalent |
fc3d5c43 | 398 | @code{scm_make_stack}). The Guile library does not do this |
2202fd6c NJ |
399 | ``automatically'' for you, so you will need to write code with a |
400 | @code{make-stack} or @code{scm_make_stack} call yourself. (We emphasise | |
401 | this point because some people are misled by the fact that the Guile | |
402 | interactive REPL code @emph{does} capture and display the stack | |
403 | automatically. But the Guile interactive REPL is itself a Scheme | |
404 | program@footnote{In effect, it is the default program which is run when | |
405 | no commands or script file are specified on the Guile command line.} | |
406 | running on top of the Guile library, and which uses @code{catch} and | |
407 | @code{make-stack} in the way we are about to describe to capture the | |
408 | stack when an error occurs.) | |
409 | ||
42cb9b03 AW |
410 | And secondly, in order to capture the stack effectively at the point |
411 | where the error occurred, the @code{make-stack} call must be made before | |
412 | Guile unwinds the stack back to the location of the prevailing catch | |
413 | expression. This means that the @code{make-stack} call must be made | |
414 | within the handler of a @code{with-throw-handler} expression, or the | |
415 | optional "pre-unwind" handler of a @code{catch}. (For the full story of | |
416 | how these alternatives differ from each other, see @ref{Exceptions}. The | |
417 | main difference is that @code{catch} terminates the error, whereas | |
418 | @code{with-throw-handler} only intercepts it temporarily and then allow | |
fc3d5c43 NJ |
419 | it to continue propagating up to the next innermost handler.) |
420 | ||
421 | So, here are some examples of how to do all this in Scheme and in C. | |
422 | For the purpose of these examples we assume that the captured stack | |
423 | should be stored in a variable, so that it can be displayed or | |
424 | arbitrarily processed later on. In Scheme: | |
425 | ||
426 | @lisp | |
427 | (let ((captured-stack #f)) | |
428 | (catch #t | |
429 | (lambda () | |
430 | ;; Execute the code in which | |
431 | ;; you want to catch errors here. | |
432 | ...) | |
433 | (lambda (key . parameters) | |
434 | ;; Put the code which you want | |
435 | ;; to handle an error after the | |
436 | ;; stack has been unwound here. | |
437 | ...) | |
438 | (lambda (key . parameters) | |
439 | ;; Capture the stack here: | |
440 | (set! captured-stack (make-stack #t)))) | |
441 | ... | |
442 | (if captured-stack | |
443 | (begin | |
444 | ;; Display or process the captured stack. | |
445 | ...)) | |
446 | ...) | |
447 | @end lisp | |
448 | ||
449 | @noindent | |
450 | And in C: | |
451 | ||
452 | @lisp | |
453 | SCM my_body_proc (void *body_data) | |
454 | @{ | |
455 | /* Execute the code in which | |
456 | you want to catch errors here. */ | |
457 | ... | |
458 | @} | |
459 | ||
460 | SCM my_handler_proc (void *handler_data, | |
461 | SCM key, | |
462 | SCM parameters) | |
463 | @{ | |
464 | /* Put the code which you want | |
465 | to handle an error after the | |
466 | stack has been unwound here. */ | |
467 | ... | |
468 | @} | |
469 | ||
470 | SCM my_preunwind_proc (void *handler_data, | |
471 | SCM key, | |
472 | SCM parameters) | |
473 | @{ | |
474 | /* Capture the stack here: */ | |
475 | *(SCM *)handler_data = scm_make_stack (SCM_BOOL_T, SCM_EOL); | |
476 | @} | |
477 | ||
478 | @{ | |
479 | SCM captured_stack = SCM_BOOL_F; | |
480 | ... | |
481 | scm_c_catch (SCM_BOOL_T, | |
482 | my_body_proc, body_data, | |
483 | my_handler_proc, handler_data, | |
484 | my_preunwind_proc, &captured_stack); | |
485 | ... | |
486 | if (captured_stack != SCM_BOOL_F) | |
487 | @{ | |
488 | /* Display or process the captured stack. */ | |
489 | ... | |
490 | @} | |
491 | ... | |
492 | @} | |
493 | @end lisp | |
494 | ||
fc3d5c43 NJ |
495 | Once you have a captured stack, you can interrogate and display its |
496 | details in any way that you want, using the @code{stack-@dots{}} and | |
497 | @code{frame-@dots{}} API described in @ref{Examining the Stack} and | |
498 | @ref{Examining Stack Frames}. | |
499 | ||
500 | If you want to print out a backtrace in the same format that the Guile | |
501 | REPL does, you can use the @code{display-backtrace} procedure to do so. | |
502 | You can also use @code{display-application} to display an individual | |
659c1e29 | 503 | frame in the Guile REPL format. |
fc3d5c43 | 504 | |
659c1e29 AW |
505 | @node Pre-Unwind Debugging |
506 | @subsubsection Pre-Unwind Debugging | |
fc3d5c43 | 507 | |
659c1e29 AW |
508 | Instead of saving a stack away and waiting for the @code{catch} to |
509 | return, you can handle errors directly, from within the pre-unwind | |
510 | handler. | |
511 | ||
512 | For example, to show a backtrace when an error is thrown, you might want | |
513 | to use a procedure like this: | |
514 | ||
515 | @lisp | |
516 | (define (with-backtrace thunk) | |
517 | (with-throw-handler #t | |
518 | thunk | |
519 | (lambda args (backtrace)))) | |
520 | (with-backtrace (lambda () (error "Not a vegetable: tomato"))) | |
521 | @end lisp | |
522 | ||
523 | Since we used @code{with-throw-handler} here, we didn't actually catch | |
524 | the error. @xref{Throw Handlers}, for more information. However, we did | |
525 | print out a context at the time of the error, using the built-in | |
526 | procedure, @code{backtrace}. | |
fc3d5c43 | 527 | |
5af872e1 NJ |
528 | @deffn {Scheme Procedure} backtrace [highlights] |
529 | @deffnx {C Function} scm_backtrace_with_highlights (highlights) | |
530 | @deffnx {C Function} scm_backtrace () | |
659c1e29 AW |
531 | Display a backtrace of the current stack to the current output port. If |
532 | @var{highlights} is given it should be a list; the elements of this list | |
533 | will be highlighted wherever they appear in the backtrace. | |
5af872e1 NJ |
534 | @end deffn |
535 | ||
659c1e29 AW |
536 | The Guile REPL code (in @file{system/repl/repl.scm} and related files) |
537 | uses a @code{catch} with a pre-unwind handler to capture the stack when | |
538 | an error occurs in an expression that was typed into the REPL, and debug | |
539 | that stack interactively in the context of the error. | |
540 | ||
541 | These procedures are available for use by user programs, in the | |
542 | @code{(system repl error-handling)} module. | |
543 | ||
544 | @lisp | |
545 | (use-modules (system repl error-handling)) | |
546 | @end lisp | |
5b2da4cc | 547 | |
1f603ae2 AW |
548 | @deffn {Scheme Procedure} call-with-error-handling thunk @ |
549 | [#:on-error on-error='debug] [#:post-error post-error='catch] @ | |
550 | [#:pass-keys pass-keys='(quit)] [#:trap-handler trap-handler='debug] | |
551 | Call a thunk in a context in which errors are handled. | |
552 | ||
553 | There are four keyword arguments: | |
554 | ||
555 | @table @var | |
556 | @item on-error | |
557 | Specifies what to do before the stack is unwound. | |
558 | ||
559 | Valid options are @code{debug} (the default), which will enter a | |
560 | debugger; @code{pass}, in which case nothing is done, and the exception | |
561 | is rethrown; or a procedure, which will be the pre-unwind handler. | |
562 | ||
563 | @item post-error | |
564 | Specifies what to do after the stack is unwound. | |
565 | ||
566 | Valid options are @code{catch} (the default), which will silently catch | |
567 | errors, returning the unspecified value; @code{report}, which prints out | |
568 | a description of the error (via @code{display-error}), and then returns | |
569 | the unspecified value; or a procedure, which will be the catch handler. | |
570 | ||
571 | @item trap-handler | |
572 | Specifies a trap handler: what to do when a breakpoint is hit. | |
573 | ||
574 | Valid options are @code{debug}, which will enter the debugger; | |
575 | @code{pass}, which does nothing; or @code{disabled}, which disables | |
576 | traps entirely. @xref{Traps}, for more information. | |
577 | ||
578 | @item pass-keys | |
579 | A set of keys to ignore, as a list. | |
580 | @end table | |
5af872e1 NJ |
581 | @end deffn |
582 | ||
659c1e29 | 583 | @node Debug Options |
1cfdb1bb AW |
584 | @subsubsection Debug options |
585 | ||
586 | The behavior when an error is the @code{backtrace} procedure and of the | |
587 | default error handler can be parameterized via the debug options. | |
588 | ||
589 | @cindex options - debug | |
590 | @cindex debug options | |
591 | @deffn {Scheme Procedure} debug-options [setting] | |
592 | Display the current settings of the debug options. If @var{setting} is | |
593 | omitted, only a short form of the current read options is printed. | |
594 | Otherwise if @var{setting} is the symbol @code{help}, a complete options | |
595 | description is displayed. | |
596 | @end deffn | |
597 | ||
598 | The set of available options, and their default values, may be had by | |
599 | invoking @code{debug-options} at the prompt. | |
600 | ||
601 | @smallexample | |
602 | scheme@@(guile-user)> | |
603 | backwards no Display backtrace in anti-chronological order. | |
604 | width 79 Maximal width of backtrace. | |
605 | depth 20 Maximal length of printed backtrace. | |
606 | backtrace yes Show backtrace on error. | |
607 | stack 1048576 Stack size limit (measured in words; | |
608 | 0 = no check). | |
609 | show-file-name #t Show file names and line numbers in backtraces | |
610 | when not `#f'. A value of `base' displays only | |
611 | base names, while `#t' displays full names. | |
612 | warn-deprecated no Warn when deprecated features are used. | |
613 | @end smallexample | |
614 | ||
615 | The boolean options may be toggled with @code{debug-enable} and | |
616 | @code{debug-disable}. The non-boolean @code{keywords} option must be set | |
617 | using @code{debug-set!}. | |
618 | ||
619 | @deffn {Scheme Procedure} debug-enable option-name | |
620 | @deffnx {Scheme Procedure} debug-disable option-name | |
621 | @deffnx {Scheme Procedure} debug-set! option-name value | |
622 | Modify the debug options. @code{debug-enable} should be used with boolean | |
623 | options and switches them on, @code{debug-disable} switches them off. | |
624 | @code{debug-set!} can be used to set an option to a specific value. | |
625 | @end deffn | |
626 | ||
627 | @subsubheading Stack overflow | |
628 | ||
629 | @cindex overflow, stack | |
630 | @cindex stack overflow | |
631 | Stack overflow errors are caused by a computation trying to use more | |
3b3518e7 AW |
632 | stack space than has been enabled by the @code{stack} option. There are |
633 | actually two kinds of stack that can overflow, the C stack and the | |
634 | Scheme stack. | |
635 | ||
636 | Scheme stack overflows can occur if Scheme procedures recurse too far | |
637 | deeply. An example would be the following recursive loop: | |
638 | ||
639 | @lisp | |
640 | scheme@@(guile-user)> (let lp () (+ 1 (lp))) | |
641 | <unnamed port>:8:17: In procedure vm-run: | |
642 | <unnamed port>:8:17: VM: Stack overflow | |
643 | @end lisp | |
644 | ||
645 | The default stack size should allow for about 10000 frames or so, so one | |
646 | usually doesn't hit this level of recursion. Unfortunately there is no | |
647 | way currently to make a VM with a bigger stack. If you are in this | |
648 | unfortunate situation, please file a bug, and in the meantime, rewrite | |
649 | your code to be tail-recursive (@pxref{Tail Calls}). | |
650 | ||
651 | The other limit you might hit would be C stack overflows. If you call a | |
652 | primitive procedure which then calls a Scheme procedure in a loop, you | |
653 | will consume C stack space. Guile tries to detect excessive consumption | |
654 | of C stack space, throwing an error when you have hit 80% of the | |
655 | process' available stack (as allocated by the operating system), or 160 | |
656 | kilowords in the absence of a strict limit. | |
657 | ||
658 | For example, looping through @code{call-with-vm}, a primitive that calls | |
659 | a thunk, gives us the following: | |
1cfdb1bb AW |
660 | |
661 | @lisp | |
3b3518e7 AW |
662 | scheme@@(guile-user)> (use-modules (system vm vm)) |
663 | scheme@@(guile-user)> (debug-set! stack 10000) | |
664 | scheme@@(guile-user)> (let lp () (call-with-vm (the-vm) lp)) | |
665 | ERROR: In procedure call-with-vm: | |
1cfdb1bb | 666 | ERROR: Stack overflow |
1cfdb1bb AW |
667 | @end lisp |
668 | ||
669 | If you get an error like this, you can either try rewriting your code to | |
670 | use less stack space, or increase the maximum stack size. To increase | |
671 | the maximum stack size, use @code{debug-set!}, for example: | |
672 | ||
673 | @lisp | |
674 | (debug-set! stack 200000) | |
1cfdb1bb AW |
675 | @end lisp |
676 | ||
3b3518e7 AW |
677 | But of course it's better to have your code operate without so much |
678 | resource consumption, avoiding loops through C trampolines. | |
1cfdb1bb | 679 | |
62ae9557 | 680 | |
24dbb5ed NJ |
681 | @node Traps |
682 | @subsection Traps | |
62ae9557 NJ |
683 | |
684 | @cindex Traps | |
685 | @cindex Evaluator trap calls | |
686 | @cindex Breakpoints | |
687 | @cindex Trace | |
688 | @cindex Tracing | |
689 | @cindex Code coverage | |
690 | @cindex Profiling | |
42cb9b03 AW |
691 | Guile's virtual machine can be configured to call out at key points to |
692 | arbitrary user-specified procedures. For more information on these | |
693 | hooks, and the circumstances under which the VM calls them, see @ref{VM | |
694 | Behaviour}. | |
695 | ||
696 | In principle, these hooks allow Scheme code to implement any model it | |
697 | chooses for examining the evaluation stack as program execution | |
698 | proceeds, and for suspending execution to be resumed later. Possible | |
699 | applications of this feature include breakpoints, runtime tracing, code | |
700 | coverage, and profiling. | |
62ae9557 NJ |
701 | |
702 | @cindex Trap classes | |
703 | @cindex Trap objects | |
24dbb5ed NJ |
704 | Based on these low level trap calls, Guile provides a higher level, |
705 | object-oriented interface for the manipulation of traps. Different | |
706 | kinds of trap are represented as GOOPS classes; for example, the | |
707 | @code{<procedure-trap>} class describes traps that are triggered by | |
708 | invocation of a specified procedure. A particular instance of a trap | |
709 | class --- or @dfn{trap object} --- describes the condition under which | |
710 | a single trap will be triggered, and what will happen then; for | |
711 | example, an instance of @code{<procedure-trap>} whose @code{procedure} | |
712 | and @code{behaviour} slots contain @code{my-factorial} and | |
713 | @code{debug-trap} would be a trap that enters the command line | |
714 | debugger when the @code{my-factorial} procedure is invoked. | |
715 | ||
716 | The following subsections describe all this in detail, for both the | |
717 | user wanting to use traps, and the developer interested in | |
62ae9557 NJ |
718 | understanding how the interface hangs together. |
719 | ||
720 | ||
42cb9b03 AW |
721 | @subsubsection Actually, this section is bitrotten |
722 | ||
723 | Dear reader: the following sections have some great ideas, and some code | |
724 | that just needs a few days of massaging to get it to work with the VM | |
725 | (as opposed to the old interpreter). Want to help? Yes? Yes! | |
726 | @code{guile-devel@@gnu.org}, that's where. | |
727 | ||
728 | ||
62ae9557 NJ |
729 | @subsubsection A Quick Note on Terminology |
730 | ||
731 | @cindex Trap terminology | |
732 | It feels natural to use the word ``trap'' in some form for all levels | |
733 | of the structure just described, so we need to be clear on the | |
734 | terminology we use to describe each particular level. The terminology | |
735 | used in this subsection is as follows. | |
736 | ||
737 | @itemize @bullet | |
738 | @item | |
739 | @cindex Evaluator trap calls | |
740 | @cindex Low level trap calls | |
741 | ``Low level trap calls'', or ``low level traps'', are the calls made | |
742 | directly from the C code of the Guile evaluator. | |
743 | ||
744 | @item | |
745 | @cindex Trap classes | |
746 | ``Trap classes'' are self-explanatory. | |
747 | ||
748 | @item | |
749 | @cindex Trap objects | |
750 | ``Trap objects'', ``trap instances'', or just ``traps'', are instances | |
751 | of a trap class, and each describe a single logical trap condition | |
752 | plus behaviour as specified by the user of this interface. | |
753 | @end itemize | |
754 | ||
755 | A good example of when it is important to be clear, is when we talk | |
756 | below of behaviours that should only happen once per low level trap. | |
757 | A single low level trap call will typically map onto the processing of | |
758 | several trap objects, so ``once per low level trap'' is significantly | |
759 | different from ``once per trap''. | |
760 | ||
761 | ||
762 | @menu | |
763 | * How to Set a Trap:: | |
764 | * Specifying Trap Behaviour:: | |
765 | * Trap Context:: | |
766 | * Tracing Examples:: | |
767 | * Tracing Configuration:: | |
768 | * Tracing and (ice-9 debug):: | |
769 | * Traps Installing More Traps:: | |
770 | * Common Trap Options:: | |
771 | * Procedure Traps:: | |
772 | * Exit Traps:: | |
773 | * Entry Traps:: | |
774 | * Apply Traps:: | |
775 | * Step Traps:: | |
776 | * Source Traps:: | |
777 | * Location Traps:: | |
778 | * Trap Shorthands:: | |
779 | * Trap Utilities:: | |
780 | @end menu | |
781 | ||
782 | ||
783 | @node How to Set a Trap | |
784 | @subsubsection How to Set a Trap | |
785 | ||
786 | @cindex Setting traps | |
787 | @cindex Installing and uninstalling traps | |
788 | Setting a trap is done in two parts. First the trap is defined by | |
789 | creating an instance of the appropriate trap class, with slot values | |
790 | specifying the condition under which the trap will fire and the action | |
791 | to take when it fires. Secondly the trap object thus created must be | |
792 | @dfn{installed}. | |
793 | ||
794 | To make this immediately concrete, here is an example that sets a trap | |
795 | to fire on the next application of the @code{facti} procedure, and to | |
796 | handle the trap by entering the command line debugger. | |
797 | ||
798 | @lisp | |
799 | (install-trap (make <procedure-trap> | |
800 | #:procedure facti | |
801 | #:single-shot #t | |
802 | #:behaviour debug-trap)) | |
803 | @end lisp | |
804 | ||
805 | @noindent | |
806 | Briefly, the elements of this incantation are as follows. (All of | |
807 | these are described more fully in the following subsubsections.) | |
808 | ||
809 | @itemize @bullet | |
810 | @item | |
811 | @code{<procedure-trap>} is the trap class for trapping on invocation | |
812 | of a specific procedure. | |
813 | ||
814 | @item | |
815 | @code{#:procedure facti} says that the specific procedure to trap on for this | |
816 | trap object is @code{facti}. | |
817 | ||
818 | @item | |
819 | @code{#:single-shot #t} says that this trap should only fire on the | |
820 | @emph{next} invocation of @code{facti}, not on all future invocations | |
821 | (which is the default if the @code{#:single-shot} option is not | |
822 | specified). | |
823 | ||
824 | @item | |
825 | @code{#:behaviour debug-trap} says that the trap infrastructure should | |
826 | call the procedure @code{debug-trap} when this trap fires. | |
827 | ||
828 | @item | |
829 | Finally, the @code{install-trap} call installs the trap immediately. | |
830 | @end itemize | |
831 | ||
832 | @noindent | |
833 | It is of course possible for the user to define more convenient | |
834 | shorthands for setting common kinds of traps. @xref{Trap Shorthands}, | |
835 | for some examples. | |
836 | ||
837 | The ability to install, uninstall and reinstall a trap without losing | |
24dbb5ed NJ |
838 | its definition is Guile's equivalent of the disable/enable commands |
839 | provided by debuggers like GDB. | |
62ae9557 NJ |
840 | |
841 | @deffn {Generic Function} install-trap trap | |
842 | Install the trap object @var{trap}, so that its behaviour will be | |
843 | executed when the conditions for the trap firing are met. | |
844 | @end deffn | |
845 | ||
846 | @deffn {Generic Function} uninstall-trap trap | |
847 | Uninstall the trap object @var{trap}, so that its behaviour will | |
848 | @emph{not} be executed even if the conditions for the trap firing are | |
849 | met. | |
850 | @end deffn | |
851 | ||
852 | ||
853 | @node Specifying Trap Behaviour | |
854 | @subsubsection Specifying Trap Behaviour | |
855 | ||
856 | @cindex Trap behaviour | |
24dbb5ed NJ |
857 | Guile provides several ``out-of-the-box'' behaviours for common needs. |
858 | All of the following can be used directly as the value of the | |
859 | @code{#:behaviour} option when creating a trap object. | |
62ae9557 NJ |
860 | |
861 | @deffn {Procedure} debug-trap trap-context | |
862 | Enter Guile's command line debugger to explore the stack at | |
863 | @var{trap-context}, and to single-step or continue program execution | |
864 | from that point. | |
865 | @end deffn | |
866 | ||
867 | @deffn {Procedure} gds-debug-trap trap-context | |
868 | Use the GDS debugging interface, which displays the stack and | |
869 | corresponding source code via Emacs, to explore the stack at | |
870 | @var{trap-context} and to single-step or continue program execution | |
871 | from that point. | |
872 | @end deffn | |
873 | ||
874 | @cindex Trace | |
875 | @cindex Tracing | |
876 | @deffn {Procedure} trace-trap trap-context | |
877 | Display trace information to summarize the current @var{trap-context}. | |
878 | @end deffn | |
879 | ||
880 | @deffn {Procedure} trace-at-exit trap-context | |
881 | Install a further trap to cause the return value of the application or | |
882 | evaluation just starting (as described by @var{trap-context}) to be | |
883 | traced using @code{trace-trap}, when this application or evaluation | |
884 | completes. The extra trap is automatically uninstalled after the | |
885 | return value has been traced. | |
886 | @end deffn | |
887 | ||
888 | @deffn {Procedure} trace-until-exit trap-context | |
889 | Install a further trap so that every step that the evaluator performs | |
890 | as part of the application or evaluation just starting (as described | |
891 | by @var{trap-context}) is traced using @code{trace-trap}. The extra | |
892 | trap is automatically uninstalled when the application or evaluation | |
893 | is complete. @code{trace-until-exit} can be very useful as a first | |
894 | step when all you know is that there is a bug ``somewhere in XXX or in | |
895 | something that XXX calls''. | |
896 | @end deffn | |
897 | ||
898 | @noindent | |
899 | @code{debug-trap} and @code{gds-debug-trap} are provided by the modules | |
900 | @code{(ice-9 debugger)} and @code{(ice-9 gds-client)} respectively, and | |
901 | their behaviours are fairly self-explanatory. For more information on | |
902 | the operation of the GDS interface via Emacs, see @ref{Using Guile in | |
903 | Emacs}. The tracing behaviours are explained more fully below. | |
904 | ||
905 | @cindex Trap context | |
906 | More generally, the @dfn{behaviour} specified for a trap can be any | |
907 | procedure that expects to be called with one @dfn{trap context} | |
908 | argument. A trivial example would be: | |
909 | ||
910 | @lisp | |
911 | (define (report-stack-depth trap-context) | |
912 | (display "Stack depth at the trap is: ") | |
913 | (display (tc:depth trap-context)) | |
914 | (newline)) | |
915 | @end lisp | |
916 | ||
917 | ||
918 | @node Trap Context | |
919 | @subsubsection Trap Context | |
920 | ||
921 | The @dfn{trap context} is an object that caches information about the | |
922 | low level trap call and the stack at the point of the trap, and is | |
923 | passed as the only argument to all behaviour procedures. The | |
924 | information in the trap context can be accessed through the procedures | |
925 | beginning @code{tc:} that are exported by the @code{(ice-9 debugging | |
926 | traps)} module@footnote{Plus of course any procedures that build on | |
927 | these, such as the @code{trace/@dots{}} procedures exported by | |
928 | @code{(ice-9 debugging trace)} (@pxref{Tracing Configuration}).}; the | |
929 | most useful of these are as follows. | |
930 | ||
931 | @deffn {Generic Function} tc:type trap-context | |
932 | Indicates the type of the low level trap by returning one of the | |
933 | keywords @code{#:application}, @code{#:evaluation}, @code{#:return} or | |
934 | @code{#:error}. | |
935 | @end deffn | |
936 | ||
937 | @deffn {Generic Function} tc:return-value trap-context | |
938 | When @code{tc:type} gives @code{#:return}, this provides the value | |
939 | that is being returned. | |
940 | @end deffn | |
941 | ||
942 | @deffn {Generic Function} tc:stack trap-context | |
943 | Provides the stack at the point of the trap (as computed by | |
944 | @code{make-stack}, but cached so that the lengthy @code{make-stack} | |
945 | operation is not performed more than once for the same low level | |
946 | trap). | |
947 | @end deffn | |
948 | ||
949 | @deffn {Generic Function} tc:frame trap-context | |
950 | The innermost frame of the stack at the point of the trap. | |
951 | @end deffn | |
952 | ||
953 | @deffn {Generic Function} tc:depth trap-context | |
954 | The number of frames (including tail recursive non-real frames) in the | |
955 | stack at the point of the trap. | |
956 | @end deffn | |
957 | ||
958 | @deffn {Generic Function} tc:real-depth trap-context | |
959 | The number of real frames (that is, excluding the non-real frames that | |
960 | describe tail recursive calls) in the stack at the point of the trap. | |
961 | @end deffn | |
962 | ||
963 | ||
964 | @node Tracing Examples | |
965 | @subsubsection Tracing Examples | |
966 | ||
967 | The following examples show what tracing is and the kind of output that | |
968 | it generates. In the first example, we define a recursive function for | |
969 | reversing a list, then watch the effect of the recursive calls by | |
970 | tracing each call and return value. | |
971 | ||
972 | @lisp | |
973 | guile> (define (rev ls) | |
974 | (if (null? ls) | |
975 | ls | |
976 | (append (rev (cdr ls)) | |
977 | (list (car ls))))) | |
978 | guile> (use-modules (ice-9 debugging traps) (ice-9 debugging trace)) | |
979 | guile> (define t1 (make <procedure-trap> | |
980 | #:procedure rev | |
981 | #:behaviour (list trace-trap | |
982 | trace-at-exit))) | |
983 | guile> (install-trap t1) | |
984 | guile> (rev '(a b c)) | |
985 | | 2: [rev (a b c)] | |
986 | | 3: [rev (b c)] | |
987 | | 4: [rev (c)] | |
988 | | 5: [rev ()] | |
989 | | 5: =>() | |
990 | | 4: =>(c) | |
991 | | 3: =>(c b) | |
992 | | 2: =>(c b a) | |
993 | (c b a) | |
994 | @end lisp | |
995 | ||
996 | @noindent | |
997 | The number before the colon in this output (which follows @code{(ice-9 | |
998 | debugging trace)}'s default output format) is the number of real frames | |
999 | on the stack. The fact that this number increases for each recursive | |
1000 | call confirms that the implementation above of @code{rev} is not | |
1001 | tail-recursive. | |
1002 | ||
1003 | In the next example, we probe the @emph{internal} workings of | |
1004 | @code{rev} in more detail by using the @code{trace-until-exit} | |
1005 | behaviour. | |
1006 | ||
1007 | @lisp | |
1008 | guile> (uninstall-trap t1) | |
1009 | guile> (define t2 (make <procedure-trap> | |
1010 | #:procedure rev | |
1011 | #:behaviour (list trace-trap | |
1012 | trace-until-exit))) | |
1013 | guile> (install-trap t2) | |
1014 | guile> (rev '(a b)) | |
1015 | | 2: [rev (a b)] | |
1016 | | 2: (if (null? ls) ls (append (rev (cdr ls)) (list (car ls)))) | |
1017 | | 3: (null? ls) | |
1018 | | 3: [null? (a b)] | |
1019 | | 3: =>#f | |
1020 | | 2: (append (rev (cdr ls)) (list (car ls))) | |
1021 | | 3: (rev (cdr ls)) | |
1022 | | 4: (cdr ls) | |
1023 | | 4: [cdr (a b)] | |
1024 | | 4: =>(b) | |
1025 | | 3: [rev (b)] | |
1026 | | 3: (if (null? ls) ls (append (rev (cdr ls)) (list (car ls)))) | |
1027 | | 4: (null? ls) | |
1028 | | 4: [null? (b)] | |
1029 | | 4: =>#f | |
1030 | | 3: (append (rev (cdr ls)) (list (car ls))) | |
1031 | | 4: (rev (cdr ls)) | |
1032 | | 5: (cdr ls) | |
1033 | | 5: [cdr (b)] | |
1034 | | 5: =>() | |
1035 | | 4: [rev ()] | |
1036 | | 4: (if (null? ls) ls (append (rev (cdr ls)) (list (car ls)))) | |
1037 | | 5: (null? ls) | |
1038 | | 5: [null? ()] | |
1039 | | 5: =>#t | |
1040 | | 4: (list (car ls)) | |
1041 | | 5: (car ls) | |
1042 | | 5: [car (b)] | |
1043 | | 5: =>b | |
1044 | | 4: [list b] | |
1045 | | 4: =>(b) | |
1046 | | 3: [append () (b)] | |
1047 | | 3: =>(b) | |
1048 | | 3: (list (car ls)) | |
1049 | | 4: (car ls) | |
1050 | | 4: [car (a b)] | |
1051 | | 4: =>a | |
1052 | | 3: [list a] | |
1053 | | 3: =>(a) | |
1054 | | 2: [append (b) (a)] | |
1055 | | 2: =>(b a) | |
1056 | (b a) | |
1057 | @end lisp | |
1058 | ||
1059 | @noindent | |
1060 | The output in this case shows every step that the evaluator performs | |
1061 | in evaluating @code{(rev '(a b))}. | |
1062 | ||
1063 | ||
1064 | @node Tracing Configuration | |
1065 | @subsubsection Tracing Configuration | |
1066 | ||
1067 | The detail of what gets printed in each trace line, and the port to | |
1068 | which tracing is written, can be configured by the procedures | |
1069 | @code{set-trace-layout} and @code{trace-port}, both exported by the | |
1070 | @code{(ice-9 debugging trace)} module. | |
1071 | ||
1072 | @deffn {Procedure with Setter} trace-port | |
1073 | Get or set the port to which tracing is printed. The default is the | |
1074 | value of @code{(current-output-port)} when the @code{(ice-9 debugging | |
1075 | trace)} module is first loaded. | |
1076 | @end deffn | |
1077 | ||
1078 | @deffn {Procedure} set-trace-layout format-string . arg-procs | |
1079 | Layout each trace line using @var{format-string} and @var{arg-procs}. | |
1080 | For each trace line, the list of values to be printed is obtained by | |
1081 | calling all the @var{arg-procs}, passing the trap context as the only | |
1082 | parameter to each one. This list of values is then formatted using | |
1083 | the specified @var{format-string}. | |
1084 | @end deffn | |
1085 | ||
1086 | @noindent | |
1087 | The @code{(ice-9 debugging trace)} module exports a set of arg-proc | |
1088 | procedures to cover most common needs, with names beginning | |
1089 | @code{trace/}. These are all implemented on top of the @code{tc:} trap | |
1090 | context accessor procedures documented in @ref{Trap Context}, and if any | |
1091 | trace output not provided by the following is needed, it should be | |
1092 | possible to implement based on a combination of the @code{tc:} | |
1093 | procedures. | |
1094 | ||
1095 | @deffn {Procedure} trace/pid trap-context | |
1096 | An arg-proc that returns the current process ID. | |
1097 | @end deffn | |
1098 | ||
1099 | @deffn {Procedure} trace/stack-id trap-context | |
1100 | An arg-proc that returns the stack ID of the stack in which the | |
1101 | current trap occurred. | |
1102 | @end deffn | |
1103 | ||
1104 | @deffn {Procedure} trace/stack-depth trap-context | |
1105 | An arg-proc that returns the length (including non-real frames) of the | |
1106 | stack at the point of the current trap. | |
1107 | @end deffn | |
1108 | ||
1109 | @deffn {Procedure} trace/stack-real-depth trap-context | |
1110 | An arg-proc that returns the length excluding non-real frames of the | |
1111 | stack at the point of the current trap. | |
1112 | @end deffn | |
1113 | ||
1114 | @deffn {Procedure} trace/stack trap-context | |
1115 | An arg-proc that returns a string summarizing stack information. This | |
1116 | string includes the stack ID, real depth, and count of additional | |
1117 | non-real frames, with the format @code{"~a:~a+~a"}. | |
1118 | @end deffn | |
1119 | ||
1120 | @deffn {Procedure} trace/source-file-name trap-context | |
1121 | An arg-proc that returns the name of the source file for the innermost | |
1122 | stack frame, or an empty string if source is not available for the | |
1123 | innermost frame. | |
1124 | @end deffn | |
1125 | ||
1126 | @deffn {Procedure} trace/source-line trap-context | |
1127 | An arg-proc that returns the line number of the source code for the | |
1128 | innermost stack frame, or zero if source is not available for the | |
1129 | innermost frame. | |
1130 | @end deffn | |
1131 | ||
1132 | @deffn {Procedure} trace/source-column trap-context | |
1133 | An arg-proc that returns the column number of the start of the source | |
1134 | code for the innermost stack frame, or zero if source is not available | |
1135 | for the innermost frame. | |
1136 | @end deffn | |
1137 | ||
1138 | @deffn {Procedure} trace/source trap-context | |
1139 | An arg-proc that returns the source location for the innermost stack | |
1140 | frame. This is a string composed of file name, line and column number | |
1141 | with the format @code{"~a:~a:~a"}, or an empty string if source is not | |
1142 | available for the innermost frame. | |
1143 | @end deffn | |
1144 | ||
1145 | @deffn {Procedure} trace/type trap-context | |
1146 | An arg-proc that returns a three letter abbreviation indicating the | |
1147 | type of the current trap: @code{"APP"} for an application frame, | |
1148 | @code{"EVA"} for an evaluation, @code{"RET"} for an exit trap, or | |
1149 | @code{"ERR"} for an error (pseudo-)trap. | |
1150 | @end deffn | |
1151 | ||
1152 | @deffn {Procedure} trace/real? trap-context | |
1153 | An arg-proc that returns @code{" "} if the innermost stack frame is a | |
1154 | real frame, or @code{"t"} if it is not. | |
1155 | @end deffn | |
1156 | ||
1157 | @deffn {Procedure} trace/info trap-context | |
1158 | An arg-proc that returns a string describing the expression being | |
1159 | evaluated, application being performed, or return value, according to | |
1160 | the current trap type. | |
1161 | @end deffn | |
1162 | ||
1163 | @noindent | |
1164 | @code{trace/stack-depth} and @code{trace/stack-real-depth} are identical | |
1165 | to the trap context methods @code{tc:depth} and @code{tc:real-depth} | |
1166 | described before (@pxref{Trap Context}), but renamed here for | |
1167 | convenience. | |
1168 | ||
1169 | The default trace layout, as exhibited by the examples of the previous | |
1170 | subsubsubsection, is set by this line of code from the @code{(ice-9 debugging | |
1171 | traps)} module: | |
1172 | ||
1173 | @lisp | |
1174 | (set-trace-layout "|~3@@a: ~a\n" trace/stack-real-depth trace/info) | |
1175 | @end lisp | |
1176 | ||
1177 | @noindent | |
1178 | If we rerun the first of those examples, but with trace layout | |
1179 | configured to show source location and trap type in addition, the | |
1180 | output looks like this: | |
1181 | ||
1182 | @lisp | |
1183 | guile> (set-trace-layout "| ~25a ~3@@a: ~a ~a\n" | |
1184 | trace/source | |
1185 | trace/stack-real-depth | |
1186 | trace/type | |
1187 | trace/info) | |
1188 | guile> (rev '(a b c)) | |
1189 | | standard input:29:0 2: APP [rev (a b c)] | |
1190 | | standard input:4:21 3: APP [rev (b c)] | |
1191 | | standard input:4:21 4: APP [rev (c)] | |
1192 | | standard input:4:21 5: APP [rev ()] | |
1193 | | standard input:2:9 5: RET =>() | |
1194 | | standard input:4:13 4: RET =>(c) | |
1195 | | standard input:4:13 3: RET =>(c b) | |
1196 | | standard input:4:13 2: RET =>(c b a) | |
1197 | (c b a) | |
1198 | @end lisp | |
1199 | ||
1200 | ||
1201 | @node Tracing and (ice-9 debug) | |
1202 | @subsubsection Tracing and (ice-9 debug) | |
1203 | ||
24dbb5ed NJ |
1204 | The @code{(ice-9 debug)} module provides a tracing facility |
1205 | (@pxref{Tracing}) that is roughly similar to that described here, but | |
1206 | there are important differences. | |
62ae9557 NJ |
1207 | |
1208 | @itemize @bullet | |
1209 | @item | |
1210 | The @code{(ice-9 debug)} trace gives a nice pictorial view of changes | |
1211 | in stack depth, by using indentation like this: | |
1212 | ||
1213 | @lisp | |
1214 | [fact1 4] | |
1215 | | [fact1 3] | |
1216 | | | [fact1 2] | |
1217 | | | | [fact1 1] | |
1218 | | | | | [fact1 0] | |
1219 | | | | | 1 | |
1220 | | | | 1 | |
1221 | | | 2 | |
1222 | | 6 | |
1223 | 24 | |
1224 | @end lisp | |
1225 | ||
1226 | However its output can @emph{only} show the information seen here, | |
24dbb5ed NJ |
1227 | which corresponds to @code{(ice-9 debugging trace)}'s |
1228 | @code{trace/info} procedure; it cannot be configured to show other | |
1229 | pieces of information about the trap context in the way that the | |
1230 | @code{(ice-9 debugging trace)} implementation can. | |
62ae9557 NJ |
1231 | |
1232 | @item | |
1233 | The @code{(ice-9 debug)} trace only allows the tracing of procedure | |
24dbb5ed NJ |
1234 | applications and their return values, whereas the @code{(ice-9 debugging |
1235 | trace)} implementation allows any kind of trap to be traced. | |
62ae9557 NJ |
1236 | |
1237 | It's interesting to note that @code{(ice-9 debug)}'s restriction here, | |
1238 | which might initially appear to be just a straightforward consequence | |
1239 | of its implementation, is also somewhat dictated by its pictorial | |
1240 | display. The use of indentation in the output relies on hooking into | |
1241 | the low level trap calls in such a way that the trapped application | |
24dbb5ed NJ |
1242 | entries and exits exactly balance each other. The @code{ice-9 |
1243 | debugging trace} implementation allows traps to be installed such that | |
1244 | entry and exit traps don't necessarily balance, which means that, in | |
1245 | general, indentation diagrams like the one above don't work. | |
62ae9557 NJ |
1246 | @end itemize |
1247 | ||
1248 | It isn't currently possible to use both @code{(ice-9 debug)} trace and | |
24dbb5ed NJ |
1249 | @code{(ice-9 debugging trace)} in the same Guile session, because |
1250 | their settings of the low level trap options conflict with each other. | |
62ae9557 NJ |
1251 | |
1252 | ||
1253 | @node Traps Installing More Traps | |
1254 | @subsubsection Traps Installing More Traps | |
1255 | ||
1256 | Sometimes it is desirable for the behaviour at one trap to install | |
1257 | further traps. In other words, the behaviour is something like | |
1258 | ``Don't do much right now, but set things up to stop after two or | |
1259 | three more steps'', or ``@dots{} when this frame completes''. This is | |
1260 | absolutely fine. For example, it is easy to code a generic ``do | |
1261 | so-and-so when the current frame exits'' procedure, which can be used | |
1262 | wherever a trap context is available, as follows. | |
1263 | ||
1264 | @lisp | |
1265 | (define (at-exit trap-context behaviour) | |
1266 | (install-trap (make <exit-trap> | |
1267 | #:depth (tc:depth trap-context) | |
1268 | #:single-shot #t | |
1269 | #:behaviour behaviour))) | |
1270 | @end lisp | |
1271 | ||
1272 | To continue and pin down the example, this could then be used as part | |
1273 | of a behaviour whose purpose was to measure the accumulated time spent | |
1274 | in and below a specified procedure. | |
1275 | ||
1276 | @lisp | |
1277 | (define calls 0) | |
1278 | (define total 0) | |
1279 | ||
1280 | (define accumulate-time | |
1281 | (lambda (trap-context) | |
1282 | (set! calls (+ calls 1)) | |
1283 | (let ((entry (current-time))) | |
1284 | (at-exit trap-context | |
1285 | (lambda (ignored) | |
1286 | (set! total | |
1287 | (+ total (- (current-time) | |
1288 | entry)))))))) | |
1289 | ||
1290 | (install-trap (make <procedure-trap> | |
1291 | #:procedure my-proc | |
1292 | #:behaviour accumulate-time)) | |
1293 | @end lisp | |
1294 | ||
1295 | ||
1296 | @node Common Trap Options | |
1297 | @subsubsection Common Trap Options | |
1298 | ||
1299 | When creating any kind of trap object, settings for the trap being | |
1300 | created are specified as options on the @code{make} call using syntax | |
1301 | like this: | |
1302 | ||
1303 | @lisp | |
1304 | (make <@var{trap-class}> | |
1305 | #:@var{option-keyword} @var{setting} | |
1306 | @dots{}) | |
1307 | @end lisp | |
1308 | ||
1309 | The following common options are provided by the base class | |
1310 | @code{<trap>}, and so can be specified for any kind of trap. | |
1311 | ||
1312 | @deffn {Class} <trap> | |
1313 | Base class for trap objects. | |
1314 | @end deffn | |
1315 | ||
1316 | @deffn {Trap Option} #:condition thunk | |
1317 | If not @code{#f}, this is a thunk which is called when the trap fires, | |
1318 | to determine whether trap processing should proceed any further. If | |
1319 | the thunk returns @code{#f}, the trap is basically suppressed. | |
1320 | Otherwise processing continues normally. (Default value @code{#f}.) | |
1321 | @end deffn | |
1322 | ||
1323 | @deffn {Trap Option} #:skip-count count | |
1324 | A count of valid (after @code{#:condition} processing) firings of this | |
1325 | trap to skip. (Default value 0.) | |
1326 | @end deffn | |
1327 | ||
1328 | @deffn {Trap Option} #:single-shot boolean | |
1329 | If not @code{#f}, this indicates that the trap should be automatically | |
1330 | uninstalled after it has successfully fired (after @code{#:condition} | |
1331 | and @code{#:skip-count} processing) for the first time. (Default | |
1332 | value @code{#f}.) | |
1333 | @end deffn | |
1334 | ||
1335 | @deffn {Trap Option} #:behaviour behaviour-proc | |
1336 | A trap behaviour procedure --- as discussed in the preceding subsubsection | |
1337 | --- or a list of such procedures, in which case each procedure is | |
1338 | called in turn when the trap fires. (Default value @code{'()}.) | |
1339 | @end deffn | |
1340 | ||
1341 | @deffn {Trap Option} #:repeat-identical-behaviour boolean | |
1342 | Normally, if multiple trap objects are triggered by the same low level | |
1343 | trap, and they request the same behaviour, it's only actually useful | |
1344 | to do that behaviour once (per low level trap); so by default multiple | |
1345 | requests for the same behaviour are coalesced. If this option is set | |
1346 | other than @code{#f}, the contents of the @code{#:behaviour} option | |
1347 | are uniquified so that they avoid being coalesced in this way. | |
1348 | (Default value @code{#f}.) | |
1349 | @end deffn | |
1350 | ||
1351 | ||
1352 | @node Procedure Traps | |
1353 | @subsubsection Procedure Traps | |
1354 | ||
1355 | The @code{<procedure-trap>} class implements traps that are triggered | |
1356 | upon application of a specified procedure. Instances of this class | |
1357 | should use the @code{#:procedure} option to specify the procedure to | |
1358 | trap on. | |
1359 | ||
1360 | @deffn {Class} <procedure-trap> | |
1361 | Class for traps triggered by application of a specified procedure. | |
1362 | @end deffn | |
1363 | ||
1364 | @deffn {Trap Option} #:procedure procedure | |
1365 | Specifies the procedure to trap on. | |
1366 | @end deffn | |
1367 | ||
1368 | @noindent | |
1369 | Example: | |
1370 | ||
1371 | @lisp | |
1372 | (install-trap (make <procedure-trap> | |
1373 | #:procedure my-proc | |
1374 | #:behaviour (list trace-trap | |
1375 | trace-until-exit))) | |
1376 | @end lisp | |
1377 | ||
1378 | ||
1379 | @node Exit Traps | |
1380 | @subsubsection Exit Traps | |
1381 | ||
1382 | The @code{<exit-trap>} class implements traps that are triggered upon | |
1383 | stack frame exit past a specified stack depth. Instances of this | |
1384 | class should use the @code{#:depth} option to specify the target stack | |
1385 | depth. | |
1386 | ||
1387 | @deffn {Class} <exit-trap> | |
1388 | Class for traps triggered by exit past a specified stack depth. | |
1389 | @end deffn | |
1390 | ||
1391 | @deffn {Trap Option} #:depth depth | |
1392 | Specifies the reference depth for the trap. | |
1393 | @end deffn | |
1394 | ||
1395 | @noindent | |
1396 | Example: | |
1397 | ||
1398 | @lisp | |
1399 | (define (trace-at-exit trap-context) | |
1400 | (install-trap (make <exit-trap> | |
1401 | #:depth (tc:depth trap-context) | |
1402 | #:single-shot #t | |
1403 | #:behaviour trace-trap))) | |
1404 | @end lisp | |
1405 | ||
1406 | @noindent | |
1407 | (This is the actual definition of the @code{trace-at-exit} behaviour.) | |
1408 | ||
1409 | ||
1410 | @node Entry Traps | |
1411 | @subsubsection Entry Traps | |
1412 | ||
1413 | The @code{<entry-trap>} class implements traps that are triggered upon | |
1414 | any stack frame entry. No further parameters are needed to specify an | |
1415 | instance of this class, so there are no class-specific trap options. | |
1416 | Note that it remains possible to use the common trap options | |
1417 | (@pxref{Common Trap Options}), for example to set a trap for the | |
1418 | @var{n}th next frame entry. | |
1419 | ||
1420 | @deffn {Class} <entry-trap> | |
1421 | Class for traps triggered by any stack frame entry. | |
1422 | @end deffn | |
1423 | ||
1424 | @noindent | |
1425 | Example: | |
1426 | ||
1427 | @lisp | |
1428 | (install-trap (make <entry-trap> | |
1429 | #:skip-count 5 | |
1430 | #:behaviour gds-debug-trap)) | |
1431 | @end lisp | |
1432 | ||
1433 | ||
1434 | @node Apply Traps | |
1435 | @subsubsection Apply Traps | |
1436 | ||
1437 | The @code{<apply-trap>} class implements traps that are triggered upon | |
1438 | any procedure application. No further parameters are needed to | |
1439 | specify an instance of this class, so there are no class-specific trap | |
1440 | options. Note that it remains possible to use the common trap options | |
1441 | (@pxref{Common Trap Options}), for example to set a trap for the next | |
1442 | application where some condition is true. | |
1443 | ||
1444 | @deffn {Class} <apply-trap> | |
1445 | Class for traps triggered by any procedure application. | |
1446 | @end deffn | |
1447 | ||
1448 | @noindent | |
1449 | Example: | |
1450 | ||
1451 | @lisp | |
1452 | (install-trap (make <apply-trap> | |
1453 | #:condition my-condition | |
1454 | #:behaviour gds-debug-trap)) | |
1455 | @end lisp | |
1456 | ||
1457 | ||
1458 | @node Step Traps | |
1459 | @subsubsection Step Traps | |
1460 | ||
1461 | The @code{<step-trap>} class implements traps that do single-stepping | |
1462 | through a program's execution. They come in two flavours, with and | |
1463 | without a specified file name. If a file name is specified, the trap | |
1464 | is triggered by the next evaluation, application or frame exit | |
1465 | pertaining to source code from the specified file. If a file name is | |
1466 | not specified, the trap is triggered by the next evaluation, | |
1467 | application or frame exit from any file (or for code whose source | |
1468 | location was not recorded), in other words by the next evaluator step | |
1469 | of any kind. | |
1470 | ||
1471 | The design goal of the @code{<step-trap>} class is to match what a | |
1472 | user would intuitively think of as single-stepping through their code, | |
1473 | either through code in general (roughly corresponding to GDB's | |
1474 | @code{step} command, for example), or through code from a particular | |
1475 | source file (roughly corresponding to GDB's @code{next}). Therefore | |
24dbb5ed NJ |
1476 | if you are using a step trap to single-step through code and finding |
1477 | its behaviour counter-intuitive, please report that so we can improve | |
1478 | it. | |
62ae9557 NJ |
1479 | |
1480 | The implementation and options of the @code{<step-trap>} class are | |
1481 | complicated by the fact that it is unreliable to determine whether a | |
1482 | low level frame exit trap is applicable to a specified file by | |
1483 | examining the details of the reported frame. This is a consequence of | |
1484 | tail recursion, which has the effect that many frames can be removed | |
1485 | from the stack at once, with only the outermost frame being reported | |
1486 | by the low level trap call. The effects of this on the | |
1487 | @code{<step-trap>} class are such as to require the introduction of | |
1488 | the strange-looking @code{#:exit-depth} option, for the following | |
1489 | reasons. | |
1490 | ||
1491 | @itemize @bullet | |
1492 | @item | |
1493 | When stopped at the start of an application or evaluation frame, and | |
1494 | it is desired to continue execution until the next ``step'' in the same | |
1495 | source file, that next step could be the start of a nested application | |
1496 | or evaluation frame, or --- if the procedure definition is in a | |
1497 | different file, for example --- it could be the exit from the current | |
1498 | frame. | |
1499 | ||
1500 | @item | |
1501 | Because of the effects of tail recursion noted above, the current | |
1502 | frame exit possibility must be expressed as frame exit past a | |
1503 | specified stack depth. When an instance of the @code{<step-trap>} | |
1504 | class is installed from the context of an application or evaluation | |
1505 | frame entry, the @code{#:exit-depth} option should be used to specify | |
1506 | this stack depth. | |
1507 | ||
1508 | @item | |
1509 | When stopped at a frame exit, on the other hand, we know that the next | |
1510 | step must be an application or evaluation frame entry. In this | |
1511 | context the @code{#:exit-depth} option is not needed and should be | |
1512 | omitted or set to @code{#f}. | |
1513 | @end itemize | |
1514 | ||
1515 | @noindent | |
1516 | When a step trap is installed without @code{#:single-shot #t}, such | |
1517 | that it keeps firing, the @code{<step-trap>} code automatically | |
1518 | updates its idea of the @code{#:exit-depth} setting each time, so that | |
1519 | the trap always fires correctly for the following step. | |
1520 | ||
1521 | @deffn {Class} <step-trap> | |
1522 | Class for single-stepping traps. | |
1523 | @end deffn | |
1524 | ||
1525 | @deffn {Trap Option} #:file-name name | |
1526 | If not @code{#f}, this is a string containing the name of a source | |
1527 | file, and restricts the step trap to evaluation steps within that | |
1528 | source file. (Default value @code{#f}.) | |
1529 | @end deffn | |
1530 | ||
1531 | @deffn {Trap Option} #:exit-depth depth | |
1532 | If not @code{#f}, this is a positive integer implying that the next | |
1533 | step may be frame exit past the stack depth @var{depth}. See the | |
1534 | discussion above for more details. (Default value @code{#f}.) | |
1535 | @end deffn | |
1536 | ||
1537 | @noindent | |
1538 | Example: | |
1539 | ||
1540 | @lisp | |
1541 | (install-trap (make <step-trap> | |
1542 | #:file-name (frame-file-name | |
1543 | (stack-ref stack index)) | |
1544 | #:exit-depth (- (stack-length stack) | |
1545 | (stack-ref stack index)) | |
1546 | #:single-shot #t | |
1547 | #:behaviour debug-trap)) | |
1548 | @end lisp | |
1549 | ||
1550 | ||
1551 | @node Source Traps | |
1552 | @subsubsection Source Traps | |
1553 | ||
1554 | The @code{<source-trap>} class implements traps that are attached to a | |
1555 | precise source code expression, as read by the reader, and which fire | |
1556 | each time that that expression is evaluated. These traps use a low | |
1557 | level Guile feature which can mark individual expressions for | |
1558 | trapping, and are relatively efficient. But it can be tricky to get | |
1559 | at the source expression in the first place, and these traps are | |
1560 | liable to become irrelevant if the procedure containing the expression | |
1561 | is reevaluated; these issues are discussed further below. | |
1562 | ||
1563 | @deffn {Class} <source-trap> | |
1564 | Class for traps triggered by evaluation of a specific Scheme | |
1565 | expression. | |
1566 | @end deffn | |
1567 | ||
1568 | @deffn {Trap Option} #:expression expr | |
1569 | Specifies the Scheme expression to trap on. | |
1570 | @end deffn | |
1571 | ||
1572 | @noindent | |
1573 | Example: | |
1574 | ||
1575 | @lisp | |
1576 | (display "Enter an expression: ") | |
1577 | (let ((x (read))) | |
1578 | (install-trap (make <source-trap> | |
1579 | #:expression x | |
1580 | #:behaviour (list trace-trap | |
1581 | trace-at-exit))) | |
1582 | (primitive-eval x)) | |
1583 | @print{} | |
1584 | Enter an expression: (+ 1 2 3 4 5 6) | |
1585 | | 3: (+ 1 2 3 4 5 6) | |
1586 | | 3: =>21 | |
1587 | 21 | |
1588 | @end lisp | |
1589 | ||
1590 | The key point here is that the expression specified by the | |
1591 | @code{#:expression} option must be @emph{exactly} (i.e. @code{eq?} to) | |
1592 | what is going to be evaluated later. It doesn't work, for example, to | |
1593 | say @code{#:expression '(+ x 3)}, with the expectation that the trap | |
1594 | will fire whenever evaluating any expression @code{(+ x 3)}. | |
1595 | ||
1596 | The @code{trap-here} macro can be used in source code to create and | |
1597 | install a source trap correctly. Take for example the factorial | |
1598 | function defined in the @code{(ice-9 debugging example-fns)} module: | |
1599 | ||
1600 | @lisp | |
1601 | (define (fact1 n) | |
1602 | (if (= n 0) | |
1603 | 1 | |
1604 | (* n (fact1 (- n 1))))) | |
1605 | @end lisp | |
1606 | ||
1607 | @noindent | |
1608 | To set a source trap on a particular expression --- let's say the | |
1609 | expression @code{(= n 0)} --- edit the code so that the expression is | |
1610 | enclosed in a @code{trap-here} macro call like this: | |
1611 | ||
1612 | @lisp | |
1613 | (define (fact1 n) | |
1614 | (if (trap-here (= n 0) #:behaviour debug-trap) | |
1615 | 1 | |
1616 | (* n (fact1 (- n 1))))) | |
1617 | @end lisp | |
1618 | ||
1619 | @deffn {Macro} trap-here expression . trap-options | |
1620 | Install a source trap with options @var{trap-options} on | |
1621 | @var{expression}, then return with the whole call transformed to | |
1622 | @code{(begin @var{expression})}. | |
1623 | @end deffn | |
1624 | ||
1625 | Note that if the @code{trap-here} incantation is removed, and | |
1626 | @code{fact1} then redefined by reloading its source file, the effect | |
1627 | of the source trap is lost, because the text ``(= n 0)'' is read again | |
1628 | from scratch and becomes a new expression @code{(= n 0)} which does | |
1629 | not have the ``trap here'' mark on it. | |
1630 | ||
1631 | If the semantics and setting of source traps seem unwieldy, location | |
1632 | traps may meet your need more closely; these are described in the | |
1633 | following subsubsection. | |
1634 | ||
1635 | ||
1636 | @node Location Traps | |
1637 | @subsubsection Location Traps | |
1638 | ||
1639 | The @code{<location-trap>} class implements traps that are triggered | |
24dbb5ed NJ |
1640 | by evaluation of code at a specific source location. When compared |
1641 | with source traps, they are easier to set, and do not become | |
1642 | irrelevant when the relevant code is reloaded; but unfortunately they | |
1643 | are a lot less efficient, as they require running some ``are we in the | |
1644 | right place for a trap'' code on every low level frame entry trap | |
1645 | call. | |
62ae9557 NJ |
1646 | |
1647 | @deffn {Class} <location-trap> | |
1648 | Class for traps triggered by evaluation of code at a specific source | |
24dbb5ed | 1649 | location. |
62ae9557 NJ |
1650 | @end deffn |
1651 | ||
1652 | @deffn {Trap Option} #:file-regexp regexp | |
1653 | A regular expression specifying the filenames that will match this | |
1654 | trap. This option must be specified when creating a location trap. | |
1655 | @end deffn | |
1656 | ||
24dbb5ed NJ |
1657 | @deffn {Trap Option} #:line line |
1658 | The line number (0-based) of the source location at which the trap | |
1659 | should be triggered. This option must be specified when creating a | |
1660 | location trap. | |
62ae9557 NJ |
1661 | @end deffn |
1662 | ||
24dbb5ed NJ |
1663 | @deffn {Trap Option} #:column column |
1664 | The column number (0-based) of the source location at which the trap | |
1665 | should be triggered. This option must be specified when creating a | |
1666 | location trap. | |
62ae9557 NJ |
1667 | @end deffn |
1668 | ||
1669 | @noindent | |
24dbb5ed NJ |
1670 | Here is an example, which matches the @code{(facti (- n 1) (* a n))} |
1671 | expression in @file{ice-9/debugging/example-fns.scm}: | |
62ae9557 NJ |
1672 | |
1673 | @lisp | |
1674 | (install-trap (make <location-trap> | |
1675 | #:file-regexp "example-fns.scm" | |
24dbb5ed NJ |
1676 | #:line 11 |
1677 | #:column 6 | |
62ae9557 NJ |
1678 | #:behaviour gds-debug-trap)) |
1679 | @end lisp | |
1680 | ||
1681 | ||
1682 | @node Trap Shorthands | |
1683 | @subsubsection Trap Shorthands | |
1684 | ||
1685 | If the code described in the preceding subsubsections for creating and | |
1686 | manipulating traps seems a little long-winded, it is of course | |
1687 | possible to define more convenient shorthand forms for typical usage | |
24dbb5ed | 1688 | patterns. Here are some examples. |
62ae9557 NJ |
1689 | |
1690 | @lisp | |
1691 | (define (break! proc) | |
1692 | (install-trap (make <procedure-trap> | |
1693 | #:procedure proc | |
1694 | #:behaviour gds-debug-trap))) | |
1695 | ||
1696 | (define (trace! proc) | |
1697 | (install-trap (make <procedure-trap> | |
1698 | #:procedure proc | |
1699 | #:behaviour (list trace-trap | |
1700 | trace-at-exit)))) | |
1701 | ||
1702 | (define (trace-subtree! proc) | |
1703 | (install-trap (make <procedure-trap> | |
1704 | #:procedure proc | |
1705 | #:behaviour (list trace-trap | |
1706 | trace-until-exit)))) | |
1707 | @end lisp | |
1708 | ||
24dbb5ed NJ |
1709 | Definitions like these are not provided out-of-the-box by Guile, |
1710 | because different users will have different ideas about what their | |
1711 | default debugger should be, or, for example, which of the common trap | |
1712 | options (@pxref{Common Trap Options}) it might be useful to expose | |
1713 | through such shorthand procedures. | |
62ae9557 NJ |
1714 | |
1715 | ||
1716 | @node Trap Utilities | |
1717 | @subsubsection Trap Utilities | |
1718 | ||
1719 | @code{list-traps} can be used to print a description of all known trap | |
1720 | objects. This uses a weak value hash table, keyed by a trap index | |
1721 | number. Each trap object has its index number assigned, and is added | |
1722 | to the hash table, when it is created by a @code{make @var{trap-class} | |
1723 | @dots{}} call. When a trap object is GC'd, it is automatically | |
1724 | removed from the hash table, and so no longer appears in the output | |
1725 | from @code{list-traps}. | |
1726 | ||
1727 | @deffn {Variable} all-traps | |
1728 | Weak value hash table containing all known trap objects. | |
1729 | @end deffn | |
1730 | ||
1731 | @deffn {Procedure} list-traps | |
1732 | Print a description of all known trap objects. | |
1733 | @end deffn | |
1734 | ||
1735 | The following example shows a single trap that traces applications of | |
1736 | the procedure @code{facti}. | |
1737 | ||
1738 | @lisp | |
1739 | guile> (list-traps) | |
1740 | #<<procedure-trap> 100d2e30> is an instance of class <procedure-trap> | |
1741 | Slots are: | |
1742 | number = 1 | |
1743 | installed = #t | |
1744 | condition = #f | |
1745 | skip-count = 0 | |
1746 | single-shot = #f | |
1747 | behaviour = (#<procedure trace-trap (trap-context)>) | |
1748 | repeat-identical-behaviour = #f | |
1749 | procedure = #<procedure facti (n a)> | |
1750 | @end lisp | |
1751 | ||
1752 | When @code{all-traps} or @code{list-traps} reveals a trap that you | |
1753 | want to modify but no longer have a reference to, you can retrieve the | |
1754 | trap object by calling @code{get-trap} with the trap's number. For | |
1755 | example, here's how you could change the behaviour of the trap listed | |
1756 | just above. | |
1757 | ||
1758 | @lisp | |
1759 | (slot-set! (get-trap 1) 'behaviour (list debug-trap)) | |
1760 | @end lisp | |
1761 | ||
1762 | @deffn {Procedure} get-trap number | |
1763 | Return the trap object with the specified @var{number}, or @code{#f} | |
1764 | if there isn't one. | |
1765 | @end deffn | |
1766 | ||
1767 | ||
24dbb5ed NJ |
1768 | @node Debugging Examples |
1769 | @subsection Debugging Examples | |
1770 | ||
1771 | Here we present some examples of what you can do with the debugging | |
1772 | facilities just described. | |
1773 | ||
1774 | @menu | |
1775 | * Single Stepping through a Procedure's Code:: | |
1776 | * Profiling or Tracing a Procedure's Code:: | |
1777 | @end menu | |
1778 | ||
1779 | ||
1780 | @node Single Stepping through a Procedure's Code | |
1781 | @subsubsection Single Stepping through a Procedure's Code | |
1782 | ||
1783 | A good way to explore in detail what a Scheme procedure does is to set | |
1784 | a trap on it and then single step through what it does. To do this, | |
1785 | make and install a @code{<procedure-trap>} with the @code{debug-trap} | |
ba5f8bf4 | 1786 | behaviour from @code{(ice-9 debugger)}. |
24dbb5ed NJ |
1787 | |
1788 | The following sample session illustrates this. It assumes that the | |
1789 | file @file{matrix.scm} defines a procedure @code{mkmatrix}, which is | |
1790 | the one we want to explore, and another procedure @code{do-main} which | |
1791 | calls @code{mkmatrix}. | |
1792 | ||
1793 | @lisp | |
1794 | $ /usr/bin/guile -q | |
1795 | guile> (use-modules (ice-9 debugger) | |
24dbb5ed NJ |
1796 | (ice-9 debugging traps)) |
1797 | guile> (load "matrix.scm") | |
1798 | guile> (install-trap (make <procedure-trap> | |
1799 | #:procedure mkmatrix | |
1800 | #:behaviour debug-trap)) | |
1801 | guile> (do-main 4) | |
1802 | This is the Guile debugger -- for help, type `help'. | |
1803 | There are 3 frames on the stack. | |
1804 | ||
1805 | Frame 2 at matrix.scm:8:3 | |
1806 | [mkmatrix] | |
1807 | debug> next | |
1808 | Frame 3 at matrix.scm:4:3 | |
45867c2a | 1809 | (let ((x 1)) (quote hi!)) |
24dbb5ed NJ |
1810 | debug> info frame |
1811 | Stack frame: 3 | |
1812 | This frame is an evaluation. | |
1813 | The expression being evaluated is: | |
1814 | matrix.scm:4:3: | |
45867c2a | 1815 | (let ((x 1)) (quote hi!)) |
24dbb5ed NJ |
1816 | debug> next |
1817 | Frame 3 at matrix.scm:5:21 | |
45867c2a | 1818 | (quote hi!) |
24dbb5ed NJ |
1819 | debug> bt |
1820 | In unknown file: | |
1821 | ?: 0* [primitive-eval (do-main 4)] | |
1822 | In standard input: | |
1823 | 4: 1* [do-main 4] | |
1824 | In matrix.scm: | |
1825 | 8: 2 [mkmatrix] | |
1826 | ... | |
45867c2a | 1827 | 5: 3 (quote hi!) |
24dbb5ed | 1828 | debug> quit |
45867c2a | 1829 | hi! |
24dbb5ed NJ |
1830 | guile> |
1831 | @end lisp | |
1832 | ||
1833 | Or you can use Guile's Emacs interface (GDS), by using the module | |
1834 | @code{(ice-9 gds-client)} instead of @code{(ice-9 debugger)} and | |
ba5f8bf4 NJ |
1835 | changing @code{debug-trap} to @code{gds-debug-trap}. Then the stack and |
1836 | corresponding source locations are displayed in Emacs instead of on the | |
1837 | Guile command line. | |
24dbb5ed NJ |
1838 | |
1839 | ||
1840 | @node Profiling or Tracing a Procedure's Code | |
1841 | @subsubsection Profiling or Tracing a Procedure's Code | |
1842 | ||
1843 | What if you wanted to get a trace of everything that the Guile | |
1844 | evaluator does within a given procedure, but without Guile stopping | |
1845 | and waiting for your input at every step? For this requirement you | |
1846 | can install a trap on the procedure, as in the previous example, but | |
1847 | instead of @code{debug-trap} or @code{gds-debug-trap}, use the | |
1848 | @code{trace-trap} and @code{trace-until-exit} behaviours provided by | |
1849 | the @code{(ice-9 debugging trace)} module. | |
1850 | ||
1851 | @lisp | |
1852 | guile> (use-modules (ice-9 debugging traps) (ice-9 debugging trace)) | |
1853 | guile> (load "matrix.scm") | |
1854 | guile> (install-trap (make <procedure-trap> | |
1855 | #:procedure mkmatrix | |
1856 | #:behaviour (list trace-trap trace-until-exit))) | |
1857 | guile> (do-main 4) | |
1858 | | 2: [mkmatrix] | |
1859 | | 3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> define #f] | |
1860 | | 3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> define #f] | |
1861 | | 4: (and (memq sym bindings) (let ...)) | |
1862 | | 5: (memq sym bindings) | |
1863 | | 5: [memq define (debug)] | |
1864 | | 5: =>#f | |
1865 | | 3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> define #f] | |
1866 | | 3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> define #f] | |
1867 | | 4: (and (memq sym bindings) (let ...)) | |
1868 | | 5: (memq sym bindings) | |
1869 | | 5: [memq define (debug)] | |
1870 | | 5: =>#f | |
1871 | | 3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f] | |
1872 | | 3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f] | |
1873 | | 4: (and (memq sym bindings) (let ...)) | |
1874 | | 5: (memq sym bindings) | |
1875 | | 5: [memq let (debug)] | |
1876 | | 5: =>#f | |
1877 | | 3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f] | |
1878 | | 3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f] | |
1879 | | 4: (and (memq sym bindings) (let ...)) | |
1880 | | 5: (memq sym bindings) | |
1881 | | 5: [memq let (debug)] | |
1882 | | 5: =>#f | |
1883 | | 3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f] | |
1884 | | 3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f] | |
1885 | | 4: (and (memq sym bindings) (let ...)) | |
1886 | | 5: (memq sym bindings) | |
1887 | | 5: [memq let (debug)] | |
1888 | | 5: =>#f | |
45867c2a | 1889 | | 2: (letrec ((yy 23)) (let ((x 1)) (quote hi!))) |
24dbb5ed NJ |
1890 | | 3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f] |
1891 | | 3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f] | |
1892 | | 4: (and (memq sym bindings) (let ...)) | |
1893 | | 5: (memq sym bindings) | |
1894 | | 5: [memq let (debug)] | |
1895 | | 5: =>#f | |
1896 | | 3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f] | |
1897 | | 3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f] | |
1898 | | 4: (and (memq sym bindings) (let ...)) | |
1899 | | 5: (memq sym bindings) | |
1900 | | 5: [memq let (debug)] | |
1901 | | 5: =>#f | |
1902 | | 3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f] | |
1903 | | 3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f] | |
1904 | | 4: (and (memq sym bindings) (let ...)) | |
1905 | | 5: (memq sym bindings) | |
1906 | | 5: [memq let (debug)] | |
1907 | | 5: =>#f | |
45867c2a | 1908 | | 2: (let ((x 1)) (quote hi!)) |
24dbb5ed NJ |
1909 | | 3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f] |
1910 | | 3: [#<procedure #f (a sym definep)> #<autoload # b7c93870> let #f] | |
1911 | | 4: (and (memq sym bindings) (let ...)) | |
1912 | | 5: (memq sym bindings) | |
1913 | | 5: [memq let (debug)] | |
1914 | | 5: =>#f | |
1915 | | 2: [let (let # #) (# # #)] | |
1916 | | 2: [let (let # #) (# # #)] | |
45867c2a NJ |
1917 | | 2: =>(#@@let* (x 1) #@@let (quote hi!)) |
1918 | hi! | |
24dbb5ed NJ |
1919 | guile> (do-main 4) |
1920 | | 2: [mkmatrix] | |
45867c2a NJ |
1921 | | 2: (letrec ((yy 23)) (let* ((x 1)) (quote hi!))) |
1922 | | 2: (let* ((x 1)) (quote hi!)) | |
1923 | | 2: (quote hi!) | |
1924 | | 2: =>hi! | |
1925 | hi! | |
24dbb5ed NJ |
1926 | guile> |
1927 | @end lisp | |
1928 | ||
1929 | This example shows the default configuration for how each line of trace | |
1930 | output is formatted, which is: | |
1931 | ||
1932 | @itemize | |
1933 | @item | |
1934 | the character @code{|}, a visual clue that the line is a line of trace | |
1935 | output, followed by | |
1936 | ||
1937 | @item | |
1938 | a number indicating the real evaluator stack depth (where ``real'' means | |
1939 | not counting tail-calls), followed by | |
1940 | ||
1941 | @item | |
1942 | a summary of the expression being evaluated (@code{(@dots{})}), the | |
1943 | procedure being called (@code{[@dots{}]}), or the value being returned | |
1944 | from an evaluation or procedure call (@code{=>@dots{}}). | |
1945 | @end itemize | |
1946 | ||
1947 | @noindent | |
1948 | You can customize @code{(ice-9 debugging trace)} to show different | |
1949 | information in each trace line using the @code{set-trace-layout} | |
1950 | procedure. The next example shows how to get the source location in | |
1951 | each trace line instead of the stack depth. | |
1952 | ||
1953 | @lisp | |
1954 | guile> (set-trace-layout "|~16@@a: ~a\n" trace/source trace/info) | |
1955 | guile> (do-main 4) | |
1956 | | matrix.scm:7:2: [mkmatrix] | |
45867c2a NJ |
1957 | | : (letrec ((yy 23)) (let* ((x 1)) (quote hi!))) |
1958 | | matrix.scm:3:2: (let* ((x 1)) (quote hi!)) | |
1959 | | matrix.scm:4:4: (quote hi!) | |
1960 | | matrix.scm:4:4: =>hi! | |
1961 | hi! | |
24dbb5ed NJ |
1962 | guile> |
1963 | @end lisp | |
1964 | ||
07d83abe MV |
1965 | @c Local Variables: |
1966 | @c TeX-master: "guile.texi" | |
1967 | @c End: |