(Debug on Error): New text on how to catch errors
[bpt/guile.git] / doc / ref / api-debug.texi
CommitLineData
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
11In order to understand Guile's debugging facilities, you first need to
12understand a little about how the evaluator works and what the Scheme
13stack is. With that in place we explain the low level trap calls that
14the evaluator can be configured to make, and the trap and breakpoint
15infrastructure 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
28The idea of the Scheme stack is central to a lot of debugging. It
29always exists implicitly, as a result of the way that the Guile
30evaluator works, and can be summoned into concrete existence as a
31first-class Scheme value by the @code{make-stack} call, so that an
32introspective Scheme program -- such as a debugger -- can present it in
33some way and allow the user to query its details. The first thing to
34understand, therefore, is how the workings of the evaluator build up the
35stack.
36
37@cindex Evaluations
38@cindex Applications
39Broadly speaking, the evaluator performs @dfn{evaluations} and
40@dfn{applications}. An evaluation means that it is looking at a source
41code expression like @code{(+ x 5)} or @code{(if msg (loop))}, deciding
42whether the top level of the expression is a procedure call, macro,
43builtin syntax, or whatever, and doing some appropriate processing in
44each case. (In the examples here, @code{(+ x 5)} would normally be a
45procedure call, and @code{(if msg (loop))} builtin syntax.) For a
46procedure call, ``appropriate processing'' includes evaluating the
47procedure's arguments, as that must happen before the procedure itself
48can be called. An application means calling a procedure once its
49arguments have been calculated.
50
51@cindex Stack
52@cindex Frames
53@cindex Stack frames
54Typically evaluations and applications alternate with each other, and
55together they form a @dfn{stack} of operations pending completion. This
56is because, on the one hand, evaluation of an expression like @code{(+ x
575)} requires --- once its arguments have been calculated --- an
58application (in this case, of the procedure @code{+}) before it can
59complete and return a result, and, on the other hand, the application of
60a procedure written in Scheme involves evaluating the sequence of
61expressions that constitute that procedure's code. Each level on this
62stack is called a @dfn{frame}.
63
64Therefore, when an error occurs in a running program, or the program
65hits a breakpoint, or in fact at any point that the programmer chooses,
66its state at that point can be represented by a @dfn{stack} of all the
67evaluations and procedure applications that are logically in progress at
68that time, each of which is known as a @dfn{frame}. The programmer can
69learn more about the program's state at that point by inspecting the
70stack 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
84A Scheme program can use the @code{make-stack} primitive anywhere in its
85code, with first arg @code{#t}, to construct a Scheme value that
86describes 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)
96Create a new stack. If @var{obj} is @code{#t}, the current
97evaluation stack is used for creating the stack frames,
98otherwise the frames are taken from @var{obj} (which must be
99either a debug object or a continuation).
100
101@var{args} should be a list containing any combination of
102integer, procedure and @code{#t} values.
103
104These values specify various ways of cutting away uninteresting
105stack 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
110Each @var{inner_cut_N} can be @code{#t}, an integer, or a
111procedure. @code{#t} means to cut away all frames up to but
112excluding the first user module frame. An integer means to cut
113away exactly that number of frames. A procedure means to cut
114away all frames up to but excluding the application frame whose
115procedure matches the specified one.
116
117Each @var{outer_cut_N} can be an integer or a procedure. An
118integer means to cut away that number of frames. A procedure
119means to cut away frames down to but excluding the application
120frame whose procedure matches the specified one.
121
122If the @var{outer_cut_N} of the last pair is missing, it is
123taken 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
128Return the last (innermost) frame of @var{obj}, which must be
129either 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)
138Return @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)
143Return 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)
148Return 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)
153Return 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)
159Display a backtrace to the output port @var{port}. @var{stack}
160is the stack to take the backtrace from, @var{first} specifies
161where in the stack to start and @var{depth} how much frames
162to display. Both @var{first} and @var{depth} can be @code{#f},
163which means that default values will be used.
7cd44c6d
MV
164When @var{highlights} is given,
165it should be a list and all members of it are highligthed in
166the 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)
175Return @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)
180Return 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)
185Return 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)
191Return 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)
197Return 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)
202Return @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)
207Return the procedure for @var{frame}, or @code{#f} if no
208procedure is associated with @var{frame}.
209@end deffn
210
211@deffn {Scheme Procedure} frame-arguments frame
212@deffnx {C Function} scm_frame_arguments (frame)
213Return 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)
218Return @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)
223Return @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)
228Return @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)
233Display a procedure application @var{frame} to the output port
234@var{port}. @var{indent} specifies the indentation of the
235output.
236@end deffn
237
238
5af872e1
NJ
239@node Source Properties
240@subsubsection Source Properties
241
242@cindex source properties
243As Guile reads in Scheme code from file or from standard input, it
244remembers the file name, line number and column number where each
245expression begins. These pieces of information are known as the
246@dfn{source properties} of the expression. If an expression undergoes
247transformation --- for example, if there is a syntax transformer in
248effect, or the expression is a macro call --- the source properties are
249copied from the untransformed to the transformed expression so that, if
250an error occurs when evaluating the transformed expression, Guile's
251debugger can point back to the file and location where the expression
252originated.
253
254The way that source properties are stored means that Guile can only
255associate source properties with parenthesized expressions, and not, for
256example, with individual symbols, numbers or strings. The difference
257can 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
261guile> (xxx)
262standard input:2:1: In expression (xxx):
263standard input:2:1: Unbound variable: xxx
264ABORT: (unbound-variable)
265guile> xxx
266<unnamed port>: In expression xxx:
267<unnamed port>: Unbound variable: xxx
268ABORT: (unbound-variable)
269@end example
270
271@noindent
272In the latter case, no source properties were stored, so the best that
273Guile could say regarding the location of the problem was ``<unnamed
274port>''.
275
276The recording of source properties is controlled by the read option
277named ``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
280interactively; all these options are @emph{off} by default when Guile
281runs a script non-interactively.
282
283The following procedures can be used to access and set the source
284properties of read expressions.
285
286@deffn {Scheme Procedure} set-source-properties! obj plist
287@deffnx {C Function} scm_set_source_properties_x (obj, plist)
288Install the association list @var{plist} as the source property
289list 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)
294Set 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)
300Return 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)
305Return the source property specified by @var{key} from
306@var{obj}'s source property list.
307@end deffn
308
309In practice there are only two ways that you should use the ability to
310set an expression's source breakpoints.
311
312@itemize
313@item
314To 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
319call your enter frame handler whenever it is about to evaluate that
320expression.
321
322@item
323To make a read or constructed expression appear to have come from a
324different source than what the expression's source properties already
325say, you can use @code{set-source-property!} to set the expression's
326@code{filename}, @code{line} and @code{column} properties. The
327properties that you set will then show up later if that expression is
328involved in a backtrace or error report.
329@end itemize
330
331If you are looking for a way to attach arbitrary information to an
332expression other than these properties, you should use
333@code{make-object-property} instead (@pxref{Object Properties}), because
334that will avoid bloating the source property hash table, which is really
335only 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)
343Return @code{#t} if @var{obj} is memoized.
344@end deffn
345
346@deffn {Scheme Procedure} unmemoize m
347@deffnx {C Function} scm_unmemoize (m)
348Unmemoize the memoized expression @var{m},
349@end deffn
350
351@deffn {Scheme Procedure} memoized-environment m
352@deffnx {C Function} scm_memoized_environment (m)
353Return 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
361Evaluate @var{exp} on a new calling stack with identity @var{id}. If
362@var{exp} is interrupted during evaluation, backtraces will not display
363frames farther back than @var{exp}'s top-level form. This macro is a
364way of artificially limiting backtraces and stack procedures, largely as
365a 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
372A common requirement is to be able to show as much useful context as
373possible when a Scheme program hits an error. The most immediate
374information 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
376the error chose explicitly to provide. This information originates with
377the @code{error} or @code{throw} call (or their C code equivalents, if
378the error is detected by C code) that signals the error, and is passed
379automatically 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
384Therefore, to catch errors that occur within a chunk of Scheme code, and
385to intercept basic information about those errors, you need to execute
386that code inside the dynamic context of a @code{catch},
387@code{lazy-catch} or @code{with-throw-handler} expression, or the
388equivalent 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
403The @code{catch} here can also be @code{lazy-catch} or
404@code{with-throw-handler}; see @ref{Throw Handlers} and @ref{Lazy Catch}
405for the details of how these differ from @code{catch}. The @code{#t}
406means that the catch is applicable to all kinds of error; if you want to
407restrict your catch to just one kind of error, you can put the symbol
408for that kind of error instead of @code{#t}. The equivalent to this in
409C would be something like this:
410
411@lisp
412SCM my_body_proc (void *body_data)
413@{
414 /* Execute the code in which
415 you want to catch errors here. */
416 ...
417@}
418
419SCM 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
437Again, as with the Scheme version, @code{scm_c_catch} could be replaced
438by @code{scm_internal_lazy_catch} or @code{scm_c_with_throw_handler},
439and @code{SCM_BOOL_T} could instead be the symbol for a particular kind
440of error.
441
442@subsubsection Capturing the full error stack
443
444The other interesting information about an error is the full Scheme
445stack at the point where the error occurred; in other words what
446innermost expression was being evaluated, what was the expression that
447called that one, and so on. If you want to write your code so that it
448captures and can display this information as well, there are two
449important things to understand.
450
451Firstly, the stack at the point of the error needs to be explicitly
452captured 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
456this point because some people are misled by the fact that the Guile
457interactive REPL code @emph{does} capture and display the stack
458automatically. But the Guile interactive REPL is itself a Scheme
459program@footnote{In effect, it is the default program which is run when
460no commands or script file are specified on the Guile command line.}
461running 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
463stack 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 ()
468Display a backtrace of the stack saved by the last error
469to the current output port. When @var{highlights} is given,
470it should be a list and all members of it are highligthed in
471the backtrace.
472@end deffn
473
474@deffn {Scheme Procedure} debug
475Invoke 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
479discussion 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
487Guile's evaluator can be configured to call three user-specified
488procedures at various points in its operation: an
489@dfn{apply-frame-handler} procedure, an @dfn{enter-frame-handler}
490procedure, and an @dfn{exit-frame-handler} procedure. These procedures,
491and the circumstances under which the evaluator calls them, are
492configured by the ``evaluator trap options'' interface (@pxref{Evaluator
493trap options}), and by the @code{trace} and @code{breakpoints} fields of
494the ``debug options'' interface (@pxref{Debugger options}).
495
496It is not necessary to understand the fine details of these low level
497calls, and of the options which configure them, in order to use the
498class-based trap interface effectively. @code{guile-debugging} takes
499care of setting these options as required for whatever set of
500installed trap objects the user specifies.@footnote{And consequently,
501when 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
504have a overall idea of how the evaluator works and when these low
505level calls can happen, as follows.
506
507@cindex Frame entry
508@cindex Frame exit
509On the basis of this description, we can now specify the points where
510low level trap calls may occur (subject to configuration). Namely,
511whenever a new frame is added to the stack, because the evaluator is
512about to begin a new evaluation or to perform a new application, and
513whenever a frame is being removed from the stack because the
514computation that it refers to has completed and is returning its
515value@footnote{If this raises the question of how expressions with
516no return value are handled, the answer is that all computations in
517Guile return a value. Those that appear to have no return value do so
518by using the special @code{*unspecified*} value, which the Guile REPL
519avoids 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)
523Call @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)
528Return @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
542The low level C code of Guile's evaluator can be configured to call
543out at key points to arbitrary user-specified code. In principle this
544allows Scheme code to implement any model it chooses for examining the
545evaluation stack as program execution proceeds, and for suspending
546execution to be resumed later. Possible applications of this feature
547include breakpoints, runtime tracing, code coverage, and profiling.
548
549@cindex Trap classes
550@cindex Trap objects
551Based on these low level trap calls, the enhancements described here
552provide a much higher level, object-oriented interface for the
553manipulation of traps. Different kinds of trap are represented as
554GOOPS classes; for example, the @code{<procedure-trap>} class
555describes traps that are triggered by invocation of a specified
556procedure. A particular instance of a trap class --- or @dfn{trap
557object} --- describes the condition under which a single trap will be
558triggered, and what will happen then; for example, an instance of
559@code{<procedure-trap>} whose @code{procedure} and @code{behaviour}
560slots contain @code{my-factorial} and @code{debug-trap} would be a
561trap that enters the command line debugger when the
562@code{my-factorial} procedure is invoked.
563
564The following subsubsections describe all this in greater detail, for both
565the user wanting to use traps, and the developer interested in
566understanding how the interface hangs together.
567
568
569@subsubsection A Quick Note on Terminology
570
571@cindex Trap terminology
572It feels natural to use the word ``trap'' in some form for all levels
573of the structure just described, so we need to be clear on the
574terminology we use to describe each particular level. The terminology
575used 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
582directly 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
591of a trap class, and each describe a single logical trap condition
592plus behaviour as specified by the user of this interface.
593@end itemize
594
595A good example of when it is important to be clear, is when we talk
596below of behaviours that should only happen once per low level trap.
597A single low level trap call will typically map onto the processing of
598several trap objects, so ``once per low level trap'' is significantly
599different 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
628Setting a trap is done in two parts. First the trap is defined by
629creating an instance of the appropriate trap class, with slot values
630specifying the condition under which the trap will fire and the action
631to take when it fires. Secondly the trap object thus created must be
632@dfn{installed}.
633
634To make this immediately concrete, here is an example that sets a trap
635to fire on the next application of the @code{facti} procedure, and to
636handle 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
646Briefly, the elements of this incantation are as follows. (All of
647these 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
652of a specific procedure.
653
654@item
655@code{#:procedure facti} says that the specific procedure to trap on for this
656trap 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
662specified).
663
664@item
665@code{#:behaviour debug-trap} says that the trap infrastructure should
666call the procedure @code{debug-trap} when this trap fires.
667
668@item
669Finally, the @code{install-trap} call installs the trap immediately.
670@end itemize
671
672@noindent
673It is of course possible for the user to define more convenient
674shorthands for setting common kinds of traps. @xref{Trap Shorthands},
675for some examples.
676
677The ability to install, uninstall and reinstall a trap without losing
678its definition is @code{guile-debugging}'s equivalent of the
679disable/enable commands provided by debuggers like GDB.
680
681@deffn {Generic Function} install-trap trap
682Install the trap object @var{trap}, so that its behaviour will be
683executed when the conditions for the trap firing are met.
684@end deffn
685
686@deffn {Generic Function} uninstall-trap trap
687Uninstall the trap object @var{trap}, so that its behaviour will
688@emph{not} be executed even if the conditions for the trap firing are
689met.
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
698for common needs. All of the following can be used directly as the
699value of the @code{#:behaviour} option when creating a trap object.
700
701@deffn {Procedure} debug-trap trap-context
702Enter Guile's command line debugger to explore the stack at
703@var{trap-context}, and to single-step or continue program execution
704from that point.
705@end deffn
706
707@deffn {Procedure} gds-debug-trap trap-context
708Use the GDS debugging interface, which displays the stack and
709corresponding source code via Emacs, to explore the stack at
710@var{trap-context} and to single-step or continue program execution
711from that point.
712@end deffn
713
714@cindex Trace
715@cindex Tracing
716@deffn {Procedure} trace-trap trap-context
717Display trace information to summarize the current @var{trap-context}.
718@end deffn
719
720@deffn {Procedure} trace-at-exit trap-context
721Install a further trap to cause the return value of the application or
722evaluation just starting (as described by @var{trap-context}) to be
723traced using @code{trace-trap}, when this application or evaluation
724completes. The extra trap is automatically uninstalled after the
725return value has been traced.
726@end deffn
727
728@deffn {Procedure} trace-until-exit trap-context
729Install a further trap so that every step that the evaluator performs
730as part of the application or evaluation just starting (as described
731by @var{trap-context}) is traced using @code{trace-trap}. The extra
732trap is automatically uninstalled when the application or evaluation
733is complete. @code{trace-until-exit} can be very useful as a first
734step when all you know is that there is a bug ``somewhere in XXX or in
735something 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
741their behaviours are fairly self-explanatory. For more information on
742the operation of the GDS interface via Emacs, see @ref{Using Guile in
743Emacs}. The tracing behaviours are explained more fully below.
744
745@cindex Trap context
746More generally, the @dfn{behaviour} specified for a trap can be any
747procedure that expects to be called with one @dfn{trap context}
748argument. 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
761The @dfn{trap context} is an object that caches information about the
762low level trap call and the stack at the point of the trap, and is
763passed as the only argument to all behaviour procedures. The
764information in the trap context can be accessed through the procedures
765beginning @code{tc:} that are exported by the @code{(ice-9 debugging
766traps)} module@footnote{Plus of course any procedures that build on
767these, such as the @code{trace/@dots{}} procedures exported by
768@code{(ice-9 debugging trace)} (@pxref{Tracing Configuration}).}; the
769most useful of these are as follows.
770
771@deffn {Generic Function} tc:type trap-context
772Indicates the type of the low level trap by returning one of the
773keywords @code{#:application}, @code{#:evaluation}, @code{#:return} or
774@code{#:error}.
775@end deffn
776
777@deffn {Generic Function} tc:return-value trap-context
778When @code{tc:type} gives @code{#:return}, this provides the value
779that is being returned.
780@end deffn
781
782@deffn {Generic Function} tc:stack trap-context
783Provides the stack at the point of the trap (as computed by
784@code{make-stack}, but cached so that the lengthy @code{make-stack}
785operation is not performed more than once for the same low level
786trap).
787@end deffn
788
789@deffn {Generic Function} tc:frame trap-context
790The innermost frame of the stack at the point of the trap.
791@end deffn
792
793@deffn {Generic Function} tc:depth trap-context
794The number of frames (including tail recursive non-real frames) in the
795stack at the point of the trap.
796@end deffn
797
798@deffn {Generic Function} tc:real-depth trap-context
799The number of real frames (that is, excluding the non-real frames that
800describe 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
807The following examples show what tracing is and the kind of output that
808it generates. In the first example, we define a recursive function for
809reversing a list, then watch the effect of the recursive calls by
810tracing each call and return value.
811
812@lisp
813guile> (define (rev ls)
814 (if (null? ls)
815 ls
816 (append (rev (cdr ls))
817 (list (car ls)))))
818guile> (use-modules (ice-9 debugging traps) (ice-9 debugging trace))
819guile> (define t1 (make <procedure-trap>
820 #:procedure rev
821 #:behaviour (list trace-trap
822 trace-at-exit)))
823guile> (install-trap t1)
824guile> (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
837The number before the colon in this output (which follows @code{(ice-9
838debugging trace)}'s default output format) is the number of real frames
839on the stack. The fact that this number increases for each recursive
840call confirms that the implementation above of @code{rev} is not
841tail-recursive.
842
843In the next example, we probe the @emph{internal} workings of
844@code{rev} in more detail by using the @code{trace-until-exit}
845behaviour.
846
847@lisp
848guile> (uninstall-trap t1)
849guile> (define t2 (make <procedure-trap>
850 #:procedure rev
851 #:behaviour (list trace-trap
852 trace-until-exit)))
853guile> (install-trap t2)
854guile> (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
900The output in this case shows every step that the evaluator performs
901in evaluating @code{(rev '(a b))}.
902
903
904@node Tracing Configuration
905@subsubsection Tracing Configuration
906
907The detail of what gets printed in each trace line, and the port to
908which 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
913Get or set the port to which tracing is printed. The default is the
914value of @code{(current-output-port)} when the @code{(ice-9 debugging
915trace)} module is first loaded.
916@end deffn
917
918@deffn {Procedure} set-trace-layout format-string . arg-procs
919Layout each trace line using @var{format-string} and @var{arg-procs}.
920For each trace line, the list of values to be printed is obtained by
921calling all the @var{arg-procs}, passing the trap context as the only
922parameter to each one. This list of values is then formatted using
923the specified @var{format-string}.
924@end deffn
925
926@noindent
927The @code{(ice-9 debugging trace)} module exports a set of arg-proc
928procedures to cover most common needs, with names beginning
929@code{trace/}. These are all implemented on top of the @code{tc:} trap
930context accessor procedures documented in @ref{Trap Context}, and if any
931trace output not provided by the following is needed, it should be
932possible to implement based on a combination of the @code{tc:}
933procedures.
934
935@deffn {Procedure} trace/pid trap-context
936An arg-proc that returns the current process ID.
937@end deffn
938
939@deffn {Procedure} trace/stack-id trap-context
940An arg-proc that returns the stack ID of the stack in which the
941current trap occurred.
942@end deffn
943
944@deffn {Procedure} trace/stack-depth trap-context
945An arg-proc that returns the length (including non-real frames) of the
946stack at the point of the current trap.
947@end deffn
948
949@deffn {Procedure} trace/stack-real-depth trap-context
950An arg-proc that returns the length excluding non-real frames of the
951stack at the point of the current trap.
952@end deffn
953
954@deffn {Procedure} trace/stack trap-context
955An arg-proc that returns a string summarizing stack information. This
956string includes the stack ID, real depth, and count of additional
957non-real frames, with the format @code{"~a:~a+~a"}.
958@end deffn
959
960@deffn {Procedure} trace/source-file-name trap-context
961An arg-proc that returns the name of the source file for the innermost
962stack frame, or an empty string if source is not available for the
963innermost frame.
964@end deffn
965
966@deffn {Procedure} trace/source-line trap-context
967An arg-proc that returns the line number of the source code for the
968innermost stack frame, or zero if source is not available for the
969innermost frame.
970@end deffn
971
972@deffn {Procedure} trace/source-column trap-context
973An arg-proc that returns the column number of the start of the source
974code for the innermost stack frame, or zero if source is not available
975for the innermost frame.
976@end deffn
977
978@deffn {Procedure} trace/source trap-context
979An arg-proc that returns the source location for the innermost stack
980frame. This is a string composed of file name, line and column number
981with the format @code{"~a:~a:~a"}, or an empty string if source is not
982available for the innermost frame.
983@end deffn
984
985@deffn {Procedure} trace/type trap-context
986An arg-proc that returns a three letter abbreviation indicating the
987type 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
993An arg-proc that returns @code{" "} if the innermost stack frame is a
994real frame, or @code{"t"} if it is not.
995@end deffn
996
997@deffn {Procedure} trace/info trap-context
998An arg-proc that returns a string describing the expression being
999evaluated, application being performed, or return value, according to
1000the current trap type.
1001@end deffn
1002
1003@noindent
1004@code{trace/stack-depth} and @code{trace/stack-real-depth} are identical
1005to the trap context methods @code{tc:depth} and @code{tc:real-depth}
1006described before (@pxref{Trap Context}), but renamed here for
1007convenience.
1008
1009The default trace layout, as exhibited by the examples of the previous
1010subsubsubsection, is set by this line of code from the @code{(ice-9 debugging
1011traps)} module:
1012
1013@lisp
1014(set-trace-layout "|~3@@a: ~a\n" trace/stack-real-depth trace/info)
1015@end lisp
1016
1017@noindent
1018If we rerun the first of those examples, but with trace layout
1019configured to show source location and trap type in addition, the
1020output looks like this:
1021
1022@lisp
1023guile> (set-trace-layout "| ~25a ~3@@a: ~a ~a\n"
1024 trace/source
1025 trace/stack-real-depth
1026 trace/type
1027 trace/info)
1028guile> (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
1044The @code{(ice-9 debug)} module of the core Guile distribution
1045provides a tracing facility that is roughly similar to that described
1046here, but there are important differences.
1047
1048@itemize @bullet
1049@item
1050The @code{(ice-9 debug)} trace gives a nice pictorial view of changes
1051in 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
106324
1064@end lisp
1065
1066However its output can @emph{only} show the information seen here,
1067which corresponds to @code{guile-debugging}'s @code{trace/info}
1068procedure; it cannot be configured to show other pieces of information
1069about the trap context in the way that @code{guile-debugging}'s trace
1070feature can.
1071
1072@item
1073The @code{(ice-9 debug)} trace only allows the tracing of procedure
1074applications and their return values, whereas @code{guile-debugging}'s
1075trace allows any kind of trap to be traced.
1076
1077It's interesting to note that @code{(ice-9 debug)}'s restriction here,
1078which might initially appear to be just a straightforward consequence
1079of its implementation, is also somewhat dictated by its pictorial
1080display. The use of indentation in the output relies on hooking into
1081the low level trap calls in such a way that the trapped application
1082entries and exits exactly balance each other.
1083@code{guile-debugging}'s more general traps interface allows traps to
1084be installed such that entry and exit traps don't necessarily balance,
1085which means that, in general, indentation diagrams like the one above
1086don't work.
1087@end itemize
1088
1089It 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
1091of the low level trap options conflict with each other. (It should be
1092possible to fix this, by modifying @code{(ice-9 debug)} to use
1093@code{guile-debugging}'s trap installation interface, but only if and
1094when @code{guile-debugging} is integrated into the core Guile
1095distribution.)
1096
1097
1098@node Traps Installing More Traps
1099@subsubsection Traps Installing More Traps
1100
1101Sometimes it is desirable for the behaviour at one trap to install
1102further 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
1104three more steps'', or ``@dots{} when this frame completes''. This is
1105absolutely fine. For example, it is easy to code a generic ``do
1106so-and-so when the current frame exits'' procedure, which can be used
1107wherever 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
1117To continue and pin down the example, this could then be used as part
1118of a behaviour whose purpose was to measure the accumulated time spent
1119in 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
1144When creating any kind of trap object, settings for the trap being
1145created are specified as options on the @code{make} call using syntax
1146like this:
1147
1148@lisp
1149(make <@var{trap-class}>
1150 #:@var{option-keyword} @var{setting}
1151 @dots{})
1152@end lisp
1153
1154The 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>
1158Base class for trap objects.
1159@end deffn
1160
1161@deffn {Trap Option} #:condition thunk
1162If not @code{#f}, this is a thunk which is called when the trap fires,
1163to determine whether trap processing should proceed any further. If
1164the thunk returns @code{#f}, the trap is basically suppressed.
1165Otherwise processing continues normally. (Default value @code{#f}.)
1166@end deffn
1167
1168@deffn {Trap Option} #:skip-count count
1169A count of valid (after @code{#:condition} processing) firings of this
1170trap to skip. (Default value 0.)
1171@end deffn
1172
1173@deffn {Trap Option} #:single-shot boolean
1174If not @code{#f}, this indicates that the trap should be automatically
1175uninstalled after it has successfully fired (after @code{#:condition}
1176and @code{#:skip-count} processing) for the first time. (Default
1177value @code{#f}.)
1178@end deffn
1179
1180@deffn {Trap Option} #:behaviour behaviour-proc
1181A trap behaviour procedure --- as discussed in the preceding subsubsection
1182--- or a list of such procedures, in which case each procedure is
1183called in turn when the trap fires. (Default value @code{'()}.)
1184@end deffn
1185
1186@deffn {Trap Option} #:repeat-identical-behaviour boolean
1187Normally, if multiple trap objects are triggered by the same low level
1188trap, and they request the same behaviour, it's only actually useful
1189to do that behaviour once (per low level trap); so by default multiple
1190requests for the same behaviour are coalesced. If this option is set
1191other than @code{#f}, the contents of the @code{#:behaviour} option
1192are 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
1200The @code{<procedure-trap>} class implements traps that are triggered
1201upon application of a specified procedure. Instances of this class
1202should use the @code{#:procedure} option to specify the procedure to
1203trap on.
1204
1205@deffn {Class} <procedure-trap>
1206Class for traps triggered by application of a specified procedure.
1207@end deffn
1208
1209@deffn {Trap Option} #:procedure procedure
1210Specifies the procedure to trap on.
1211@end deffn
1212
1213@noindent
1214Example:
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
1227The @code{<exit-trap>} class implements traps that are triggered upon
1228stack frame exit past a specified stack depth. Instances of this
1229class should use the @code{#:depth} option to specify the target stack
1230depth.
1231
1232@deffn {Class} <exit-trap>
1233Class for traps triggered by exit past a specified stack depth.
1234@end deffn
1235
1236@deffn {Trap Option} #:depth depth
1237Specifies the reference depth for the trap.
1238@end deffn
1239
1240@noindent
1241Example:
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
1258The @code{<entry-trap>} class implements traps that are triggered upon
1259any stack frame entry. No further parameters are needed to specify an
1260instance of this class, so there are no class-specific trap options.
1261Note 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>
1266Class for traps triggered by any stack frame entry.
1267@end deffn
1268
1269@noindent
1270Example:
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
1282The @code{<apply-trap>} class implements traps that are triggered upon
1283any procedure application. No further parameters are needed to
1284specify an instance of this class, so there are no class-specific trap
1285options. 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
1287application where some condition is true.
1288
1289@deffn {Class} <apply-trap>
1290Class for traps triggered by any procedure application.
1291@end deffn
1292
1293@noindent
1294Example:
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
1306The @code{<step-trap>} class implements traps that do single-stepping
1307through a program's execution. They come in two flavours, with and
1308without a specified file name. If a file name is specified, the trap
1309is triggered by the next evaluation, application or frame exit
1310pertaining to source code from the specified file. If a file name is
1311not specified, the trap is triggered by the next evaluation,
1312application or frame exit from any file (or for code whose source
1313location was not recorded), in other words by the next evaluator step
1314of any kind.
1315
1316The design goal of the @code{<step-trap>} class is to match what a
1317user would intuitively think of as single-stepping through their code,
1318either through code in general (roughly corresponding to GDB's
1319@code{step} command, for example), or through code from a particular
1320source file (roughly corresponding to GDB's @code{next}). Therefore
1321if you are using @code{guile-debugging} to single-step through code
1322and finding its behaviour counter-intuitive, please let me know so
1323that I can improve it.
1324
1325The implementation and options of the @code{<step-trap>} class are
1326complicated by the fact that it is unreliable to determine whether a
1327low level frame exit trap is applicable to a specified file by
1328examining the details of the reported frame. This is a consequence of
1329tail recursion, which has the effect that many frames can be removed
1330from the stack at once, with only the outermost frame being reported
1331by the low level trap call. The effects of this on the
1332@code{<step-trap>} class are such as to require the introduction of
1333the strange-looking @code{#:exit-depth} option, for the following
1334reasons.
1335
1336@itemize @bullet
1337@item
1338When stopped at the start of an application or evaluation frame, and
1339it is desired to continue execution until the next ``step'' in the same
1340source file, that next step could be the start of a nested application
1341or evaluation frame, or --- if the procedure definition is in a
1342different file, for example --- it could be the exit from the current
1343frame.
1344
1345@item
1346Because of the effects of tail recursion noted above, the current
1347frame exit possibility must be expressed as frame exit past a
1348specified stack depth. When an instance of the @code{<step-trap>}
1349class is installed from the context of an application or evaluation
1350frame entry, the @code{#:exit-depth} option should be used to specify
1351this stack depth.
1352
1353@item
1354When stopped at a frame exit, on the other hand, we know that the next
1355step must be an application or evaluation frame entry. In this
1356context the @code{#:exit-depth} option is not needed and should be
1357omitted or set to @code{#f}.
1358@end itemize
1359
1360@noindent
1361When a step trap is installed without @code{#:single-shot #t}, such
1362that it keeps firing, the @code{<step-trap>} code automatically
1363updates its idea of the @code{#:exit-depth} setting each time, so that
1364the trap always fires correctly for the following step.
1365
1366@deffn {Class} <step-trap>
1367Class for single-stepping traps.
1368@end deffn
1369
1370@deffn {Trap Option} #:file-name name
1371If not @code{#f}, this is a string containing the name of a source
1372file, and restricts the step trap to evaluation steps within that
1373source file. (Default value @code{#f}.)
1374@end deffn
1375
1376@deffn {Trap Option} #:exit-depth depth
1377If not @code{#f}, this is a positive integer implying that the next
1378step may be frame exit past the stack depth @var{depth}. See the
1379discussion above for more details. (Default value @code{#f}.)
1380@end deffn
1381
1382@noindent
1383Example:
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
1399The @code{<source-trap>} class implements traps that are attached to a
1400precise source code expression, as read by the reader, and which fire
1401each time that that expression is evaluated. These traps use a low
1402level Guile feature which can mark individual expressions for
1403trapping, and are relatively efficient. But it can be tricky to get
1404at the source expression in the first place, and these traps are
1405liable to become irrelevant if the procedure containing the expression
1406is reevaluated; these issues are discussed further below.
1407
1408@deffn {Class} <source-trap>
1409Class for traps triggered by evaluation of a specific Scheme
1410expression.
1411@end deffn
1412
1413@deffn {Trap Option} #:expression expr
1414Specifies the Scheme expression to trap on.
1415@end deffn
1416
1417@noindent
1418Example:
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{}
1429Enter an expression: (+ 1 2 3 4 5 6)
1430| 3: (+ 1 2 3 4 5 6)
1431| 3: =>21
143221
1433@end lisp
1434
1435The key point here is that the expression specified by the
1436@code{#:expression} option must be @emph{exactly} (i.e. @code{eq?} to)
1437what is going to be evaluated later. It doesn't work, for example, to
1438say @code{#:expression '(+ x 3)}, with the expectation that the trap
1439will fire whenever evaluating any expression @code{(+ x 3)}.
1440
1441The @code{trap-here} macro can be used in source code to create and
1442install a source trap correctly. Take for example the factorial
1443function 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
1453To set a source trap on a particular expression --- let's say the
1454expression @code{(= n 0)} --- edit the code so that the expression is
1455enclosed 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
1465Install 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
1470Note that if the @code{trap-here} incantation is removed, and
1471@code{fact1} then redefined by reloading its source file, the effect
1472of the source trap is lost, because the text ``(= n 0)'' is read again
1473from scratch and becomes a new expression @code{(= n 0)} which does
1474not have the ``trap here'' mark on it.
1475
1476If the semantics and setting of source traps seem unwieldy, location
1477traps may meet your need more closely; these are described in the
1478following subsubsection.
1479
1480
1481@node Location Traps
1482@subsubsection Location Traps
1483
1484The @code{<location-trap>} class implements traps that are triggered
1485by evaluation of code at a specific source location or within a
1486specified range of source locations. When compared with source traps,
1487they are easier to set, and do not become irrelevant when the relevant
1488code is reloaded; but unfortunately they are considerably less
1489efficient, as they require running some ``are we in the right place
1490for a trap'' code on every low level frame entry trap call.
1491
1492@deffn {Class} <location-trap>
1493Class for traps triggered by evaluation of code at a specific source
1494location or in a specified range of source locations.
1495@end deffn
1496
1497@deffn {Trap Option} #:file-regexp regexp
1498A regular expression specifying the filenames that will match this
1499trap. This option must be specified when creating a location trap.
1500@end deffn
1501
1502@deffn {Trap Option} #:line line-spec
1503If specified, @var{line-spec} describes either a single line, in which
1504case it is a single integer, or a range of lines, in which case it is
1505a pair of the form @code{(@var{min-line} . @var{max-line})}. All line
1506numbers 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
1512If specified, @var{column-spec} describes either a single column, in
1513which case it is a single integer, or a range of columns, in which
1514case it is a pair of the form @code{(@var{min-column}
1515. @var{max-column})}. All column numbers are 0-based, and the range
1516form is inclusive-inclusive. If @code{#f} or not specified, the trap
1517is not restricted by column number. (Default value @code{#f}.)
1518@end deffn
1519
1520@noindent
1521Example:
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
1534If the code described in the preceding subsubsections for creating and
1535manipulating traps seems a little long-winded, it is of course
1536possible to define more convenient shorthand forms for typical usage
1537patterns. For example, my own @file{.guile} file contains the
1538following 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
1559Definitions like these are not provided out-of-the-box by
1560@code{guile-debugging}, because different users will have different
1561ideas about what their default debugger should be, or, for example,
1562which of the common trap options (@pxref{Common Trap Options}) it
1563might 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
1570objects. This uses a weak value hash table, keyed by a trap index
1571number. Each trap object has its index number assigned, and is added
1572to 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
1574removed from the hash table, and so no longer appears in the output
1575from @code{list-traps}.
1576
1577@deffn {Variable} all-traps
1578Weak value hash table containing all known trap objects.
1579@end deffn
1580
1581@deffn {Procedure} list-traps
1582Print a description of all known trap objects.
1583@end deffn
1584
1585The following example shows a single trap that traces applications of
1586the procedure @code{facti}.
1587
1588@lisp
1589guile> (list-traps)
1590#<<procedure-trap> 100d2e30> is an instance of class <procedure-trap>
1591Slots 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
1602When @code{all-traps} or @code{list-traps} reveals a trap that you
1603want to modify but no longer have a reference to, you can retrieve the
1604trap object by calling @code{get-trap} with the trap's number. For
1605example, here's how you could change the behaviour of the trap listed
1606just above.
1607
1608@lisp
1609(slot-set! (get-trap 1) 'behaviour (list debug-trap))
1610@end lisp
1611
1612@deffn {Procedure} get-trap number
1613Return the trap object with the specified @var{number}, or @code{#f}
1614if there isn't one.
1615@end deffn
1616
1617
1618@node Breakpoints
1619@subsection Breakpoints
1620
1621While they are an important piece of infrastructure, and directly
1622usable in some scenarios, traps are still too low level to meet some
1623of the requirements of interactive development.
1624
1625For example, in my experience a common scenario is that a newly
1626written procedure is not working properly, and so you'd like to be
1627able to step or trace through its code to find out why. Ideally this
1628should be possible from the IDE and without having to modify the
1629source code. There are two problems with using traps directly in this
1630scenario.
1631
1632@enumerate
1633@item
1634They are too detailed: constructing and installing a trap requires you
1635to say what kind of trap you want and to specify fairly low level
1636options for it, whereas what you really want is just to say ``break
1637here using the most efficient means possible.''
1638
1639@item
1640The most efficient kinds of trap --- that is, @code{<procedure-trap>}
1641and @code{<source-trap>} --- can only be specified and installed
1642@emph{after} the code that they refer to has been loaded. This is an
1643inconvenient detail for the user to deal with, and in some
1644applications it might be very difficult to insert an instruction to
1645install the required trap in between when the code is loaded and when
1646the procedure concerned is first called. It would be better to be
1647able to tell Guile about the requirement upfront, and for it to deal
1648with installing the trap when possible.
1649@end enumerate
1650
1651We solve these problems by introducing breakpoints. A breakpoint is
1652something which says ``I want to break at location X, or in procedure
1653P --- just make it happen'', and can be set regardless of whether the
1654relevant code has already been loaded. Breakpoints use traps to do
1655their work, but that is a detail that the user will usually not have
1656to care about.
1657
1658Breakpoints are provided by a combination of Scheme code in the client
1659program, and facilities for setting and managing breakpoints in the
1660GDS front end. On the Scheme side the entry points are as follows.
1661
1662@deffn {Getter with Setter} default-breakpoint-behaviour
1663A ``getter with setter'' procedure that can be used to get or set the
1664default behaviour for new breakpoints. When a new default behaviour
1665is set, by calling
1666
1667@lisp
1668(set! (default-breakpoint-behaviour) @var{new-behaviour})
1669@end lisp
1670
1671@noindent
1672the new behaviour applies to all following @code{break-in} and
1673@code{break-at} calls, but does not affect breakpoints which have
1674already been set. @var{new-behaviour} should be a behaviour procedure
1675with the signature
1676
1677@lisp
1678(lambda (trap-context) @dots{})
1679@end lisp
1680
1681@noindent
1682as described in @ref{Specifying Trap Behaviour}.
1683@end deffn
1684
1685@deffn {Procedure} break-in procedure-name [module-or-file-name] [options]
1686Set a breakpoint on entry to the procedure named @var{procedure-name},
1687which should be a symbol. @var{module-or-file-name}, if present, is
1688the name of the module (a list of symbols) or file (a string) which
1689includes the target procedure. If @var{module-or-file-name} is
1690absent, the target procedure is assumed to be in the current module.
1691
1692The available options are any of the common trap options
1693(@pxref{Common Trap Options}), and are used when creating the
1694breakpoint's underlying traps. The default breakpoint behaviour
1695(given earlier to @code{default-breakpoint-behaviour}) is only used if
1696these options do not include @code{#:behaviour @var{behaviour}}.
1697@end deffn
1698
1699@deffn {Procedure} break-at file-name line column [options]
1700Set a breakpoint on the expression in file @var{file-name} whose
1701opening parenthesis is on line @var{line} at column @var{column}.
1702@var{line} and @var{column} both count from 0 (not from 1).
1703
1704The available options are any of the common trap options
1705(@pxref{Common Trap Options}), and are used when creating the
1706breakpoint's underlying traps. The default breakpoint behaviour
1707(given earlier to @code{default-breakpoint-behaviour}) is only used if
1708these options do not include @code{#:behaviour @var{behaviour}}.
1709@end deffn
1710
1711@deffn {Procedure} set-gds-breakpoints
1712Ask the GDS front end for a list of breakpoints to set, and set these
1713using @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
1718breakpoints that it needs inline in that code. For example, to trace
1719calls and arguments to a group of procedures to handle HTTP requests,
1720one 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
1735above, and is intended to be the most practical option if you are
1736using GDS. The idea is that you only need to add this one call
1737somewhere 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
1745and then all the details of the breakpoints that you want to set can
1746be managed through GDS. For the details of GDS's breakpoints
1747interface, see @ref{Setting and Managing Breakpoints}.
1748
1749
07d83abe
MV
1750@c Local Variables:
1751@c TeX-master: "guile.texi"
1752@c End: