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