summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeil Jerram <neil@ossau.uklinux.net>2006-08-11 16:21:14 +0000
committerNeil Jerram <neil@ossau.uklinux.net>2006-08-11 16:21:14 +0000
commit62ae95577a503e89114584ae8571b2b128d79ca5 (patch)
tree370ebdfe3574f074537f98474f3b85426e841ef8
parent5af872e136b2e7c74b566b68bbab97b288464578 (diff)
downloadguile-62ae95577a503e89114584ae8571b2b128d79ca5.tar.gz
* scheme-using.texi (Run To Frame Exit): Improved doc for finish.
(Continue Execution): Improved doc for continue. (Using Guile in Emacs): Lots of new docs about the Emacs interface. * api-debug.texi (Low Level Trap Calls): New. (Using Traps): Removed, material incorporated into Low Level Trap Calls. (High Level Traps): New. (Breakpoints): New. * scheme-using.texi (Single Stepping): Improve doc for step and next. * api-debug.texi (Debug on Error): Note need to handling of errors in C.
-rw-r--r--doc/ref/ChangeLog17
-rw-r--r--doc/ref/api-debug.texi1267
-rw-r--r--doc/ref/scheme-using.texi783
3 files changed, 2058 insertions, 9 deletions
diff --git a/doc/ref/ChangeLog b/doc/ref/ChangeLog
index 982871ee6..451c6f575 100644
--- a/doc/ref/ChangeLog
+++ b/doc/ref/ChangeLog
@@ -1,5 +1,22 @@
2006-08-11 Neil Jerram <neil@ossau.uklinux.net>
+ * scheme-using.texi (Run To Frame Exit): Improved doc for finish.
+ (Continue Execution): Improved doc for continue.
+ (Using Guile in Emacs): Lots of new docs about the Emacs
+ interface.
+
+ * api-debug.texi (Low Level Trap Calls): New.
+ (Using Traps): Removed, material incorporated into Low Level Trap
+ Calls.
+ (High Level Traps): New.
+ (Breakpoints): New.
+
+ * scheme-using.texi (Single Stepping): Improve doc for step and
+ next.
+
+ * api-debug.texi (Debug on Error): Note need to handling of errors
+ in C.
+
* api-debug.texi (Debugging): New intro text. New subsection
"Evaluation Model". Moved existing subsections "Capturing the
Stack or Innermost Stack Frame", "Examining the Stack", "Examining
diff --git a/doc/ref/api-debug.texi b/doc/ref/api-debug.texi
index 42527b7ec..6868ef211 100644
--- a/doc/ref/api-debug.texi
+++ b/doc/ref/api-debug.texi
@@ -17,7 +17,9 @@ infrastructure that builds on top of those calls.
@menu
* Evaluation Model:: Evaluation and the Scheme stack.
* Debug on Error:: Debugging when an error occurs.
-* Using Traps::
+* Low Level Trap Calls::
+* High Level Traps::
+* Breakpoints::
@end menu
@node Evaluation Model
@@ -380,9 +382,48 @@ the backtrace.
Invoke the Guile debugger to explore the context of the last error.
@end deffn
-
-@node Using Traps
-@subsection Using Traps
+[Should also cover how to catch and debug errors from C, including
+discussion of lazy/pre-unwind handlers.]
+
+
+@node Low Level Trap Calls
+@subsection Low Level Trap Calls
+
+@cindex Low level trap calls
+@cindex Evaluator trap calls
+Guile's evaluator can be configured to call three user-specified
+procedures at various points in its operation: an
+@dfn{apply-frame-handler} procedure, an @dfn{enter-frame-handler}
+procedure, and an @dfn{exit-frame-handler} procedure. These procedures,
+and the circumstances under which the evaluator calls them, are
+configured by the ``evaluator trap options'' interface (@pxref{Evaluator
+trap options}), and by the @code{trace} and @code{breakpoints} fields of
+the ``debug options'' interface (@pxref{Debugger options}).
+
+It is not necessary to understand the fine details of these low level
+calls, and of the options which configure them, in order to use the
+class-based trap interface effectively. @code{guile-debugging} takes
+care of setting these options as required for whatever set of
+installed trap objects the user specifies.@footnote{And consequently,
+when using the class-based trap interface, users/applications should
+@emph{not} modify these options themselves, to avoid interfering with
+@code{guile-debugging}'s option settings.} It is useful, though, to
+have a overall idea of how the evaluator works and when these low
+level calls can happen, as follows.
+
+@cindex Frame entry
+@cindex Frame exit
+On the basis of this description, we can now specify the points where
+low level trap calls may occur (subject to configuration). Namely,
+whenever a new frame is added to the stack, because the evaluator is
+about to begin a new evaluation or to perform a new application, and
+whenever a frame is being removed from the stack because the
+computation that it refers to has completed and is returning its
+value@footnote{If this raises the question of how expressions with
+no return value are handled, the answer is that all computations in
+Guile return a value. Those that appear to have no return value do so
+by using the special @code{*unspecified*} value, which the Guile REPL
+avoids displaying to the user.} to its caller.
@deffn {Scheme Procedure} with-traps thunk
@deffnx {C Function} scm_with_traps (thunk)
@@ -395,6 +436,1224 @@ Return @code{#t} if @var{obj} is a debug object.
@end deffn
+@node High Level Traps
+@subsection High Level Traps
+
+@cindex Traps
+@cindex Evaluator trap calls
+@cindex Breakpoints
+@cindex Trace
+@cindex Tracing
+@cindex Code coverage
+@cindex Profiling
+The low level C code of Guile's evaluator can be configured to call
+out at key points to arbitrary user-specified code. In principle this
+allows Scheme code to implement any model it chooses for examining the
+evaluation stack as program execution proceeds, and for suspending
+execution to be resumed later. Possible applications of this feature
+include breakpoints, runtime tracing, code coverage, and profiling.
+
+@cindex Trap classes
+@cindex Trap objects
+Based on these low level trap calls, the enhancements described here
+provide a much higher level, object-oriented interface for the
+manipulation of traps. Different kinds of trap are represented as
+GOOPS classes; for example, the @code{<procedure-trap>} class
+describes traps that are triggered by invocation of a specified
+procedure. A particular instance of a trap class --- or @dfn{trap
+object} --- describes the condition under which a single trap will be
+triggered, and what will happen then; for example, an instance of
+@code{<procedure-trap>} whose @code{procedure} and @code{behaviour}
+slots contain @code{my-factorial} and @code{debug-trap} would be a
+trap that enters the command line debugger when the
+@code{my-factorial} procedure is invoked.
+
+The following subsubsections describe all this in greater detail, for both
+the user wanting to use traps, and the developer interested in
+understanding how the interface hangs together.
+
+
+@subsubsection A Quick Note on Terminology
+
+@cindex Trap terminology
+It feels natural to use the word ``trap'' in some form for all levels
+of the structure just described, so we need to be clear on the
+terminology we use to describe each particular level. The terminology
+used in this subsection is as follows.
+
+@itemize @bullet
+@item
+@cindex Evaluator trap calls
+@cindex Low level trap calls
+``Low level trap calls'', or ``low level traps'', are the calls made
+directly from the C code of the Guile evaluator.
+
+@item
+@cindex Trap classes
+``Trap classes'' are self-explanatory.
+
+@item
+@cindex Trap objects
+``Trap objects'', ``trap instances'', or just ``traps'', are instances
+of a trap class, and each describe a single logical trap condition
+plus behaviour as specified by the user of this interface.
+@end itemize
+
+A good example of when it is important to be clear, is when we talk
+below of behaviours that should only happen once per low level trap.
+A single low level trap call will typically map onto the processing of
+several trap objects, so ``once per low level trap'' is significantly
+different from ``once per trap''.
+
+
+@menu
+* How to Set a Trap::
+* Specifying Trap Behaviour::
+* Trap Context::
+* Tracing Examples::
+* Tracing Configuration::
+* Tracing and (ice-9 debug)::
+* Traps Installing More Traps::
+* Common Trap Options::
+* Procedure Traps::
+* Exit Traps::
+* Entry Traps::
+* Apply Traps::
+* Step Traps::
+* Source Traps::
+* Location Traps::
+* Trap Shorthands::
+* Trap Utilities::
+@end menu
+
+
+@node How to Set a Trap
+@subsubsection How to Set a Trap
+
+@cindex Setting traps
+@cindex Installing and uninstalling traps
+Setting a trap is done in two parts. First the trap is defined by
+creating an instance of the appropriate trap class, with slot values
+specifying the condition under which the trap will fire and the action
+to take when it fires. Secondly the trap object thus created must be
+@dfn{installed}.
+
+To make this immediately concrete, here is an example that sets a trap
+to fire on the next application of the @code{facti} procedure, and to
+handle the trap by entering the command line debugger.
+
+@lisp
+(install-trap (make <procedure-trap>
+ #:procedure facti
+ #:single-shot #t
+ #:behaviour debug-trap))
+@end lisp
+
+@noindent
+Briefly, the elements of this incantation are as follows. (All of
+these are described more fully in the following subsubsections.)
+
+@itemize @bullet
+@item
+@code{<procedure-trap>} is the trap class for trapping on invocation
+of a specific procedure.
+
+@item
+@code{#:procedure facti} says that the specific procedure to trap on for this
+trap object is @code{facti}.
+
+@item
+@code{#:single-shot #t} says that this trap should only fire on the
+@emph{next} invocation of @code{facti}, not on all future invocations
+(which is the default if the @code{#:single-shot} option is not
+specified).
+
+@item
+@code{#:behaviour debug-trap} says that the trap infrastructure should
+call the procedure @code{debug-trap} when this trap fires.
+
+@item
+Finally, the @code{install-trap} call installs the trap immediately.
+@end itemize
+
+@noindent
+It is of course possible for the user to define more convenient
+shorthands for setting common kinds of traps. @xref{Trap Shorthands},
+for some examples.
+
+The ability to install, uninstall and reinstall a trap without losing
+its definition is @code{guile-debugging}'s equivalent of the
+disable/enable commands provided by debuggers like GDB.
+
+@deffn {Generic Function} install-trap trap
+Install the trap object @var{trap}, so that its behaviour will be
+executed when the conditions for the trap firing are met.
+@end deffn
+
+@deffn {Generic Function} uninstall-trap trap
+Uninstall the trap object @var{trap}, so that its behaviour will
+@emph{not} be executed even if the conditions for the trap firing are
+met.
+@end deffn
+
+
+@node Specifying Trap Behaviour
+@subsubsection Specifying Trap Behaviour
+
+@cindex Trap behaviour
+@code{guile-debugging} provides several ``out-of-the-box'' behaviours
+for common needs. All of the following can be used directly as the
+value of the @code{#:behaviour} option when creating a trap object.
+
+@deffn {Procedure} debug-trap trap-context
+Enter Guile's command line debugger to explore the stack at
+@var{trap-context}, and to single-step or continue program execution
+from that point.
+@end deffn
+
+@deffn {Procedure} gds-debug-trap trap-context
+Use the GDS debugging interface, which displays the stack and
+corresponding source code via Emacs, to explore the stack at
+@var{trap-context} and to single-step or continue program execution
+from that point.
+@end deffn
+
+@cindex Trace
+@cindex Tracing
+@deffn {Procedure} trace-trap trap-context
+Display trace information to summarize the current @var{trap-context}.
+@end deffn
+
+@deffn {Procedure} trace-at-exit trap-context
+Install a further trap to cause the return value of the application or
+evaluation just starting (as described by @var{trap-context}) to be
+traced using @code{trace-trap}, when this application or evaluation
+completes. The extra trap is automatically uninstalled after the
+return value has been traced.
+@end deffn
+
+@deffn {Procedure} trace-until-exit trap-context
+Install a further trap so that every step that the evaluator performs
+as part of the application or evaluation just starting (as described
+by @var{trap-context}) is traced using @code{trace-trap}. The extra
+trap is automatically uninstalled when the application or evaluation
+is complete. @code{trace-until-exit} can be very useful as a first
+step when all you know is that there is a bug ``somewhere in XXX or in
+something that XXX calls''.
+@end deffn
+
+@noindent
+@code{debug-trap} and @code{gds-debug-trap} are provided by the modules
+@code{(ice-9 debugger)} and @code{(ice-9 gds-client)} respectively, and
+their behaviours are fairly self-explanatory. For more information on
+the operation of the GDS interface via Emacs, see @ref{Using Guile in
+Emacs}. The tracing behaviours are explained more fully below.
+
+@cindex Trap context
+More generally, the @dfn{behaviour} specified for a trap can be any
+procedure that expects to be called with one @dfn{trap context}
+argument. A trivial example would be:
+
+@lisp
+(define (report-stack-depth trap-context)
+ (display "Stack depth at the trap is: ")
+ (display (tc:depth trap-context))
+ (newline))
+@end lisp
+
+
+@node Trap Context
+@subsubsection Trap Context
+
+The @dfn{trap context} is an object that caches information about the
+low level trap call and the stack at the point of the trap, and is
+passed as the only argument to all behaviour procedures. The
+information in the trap context can be accessed through the procedures
+beginning @code{tc:} that are exported by the @code{(ice-9 debugging
+traps)} module@footnote{Plus of course any procedures that build on
+these, such as the @code{trace/@dots{}} procedures exported by
+@code{(ice-9 debugging trace)} (@pxref{Tracing Configuration}).}; the
+most useful of these are as follows.
+
+@deffn {Generic Function} tc:type trap-context
+Indicates the type of the low level trap by returning one of the
+keywords @code{#:application}, @code{#:evaluation}, @code{#:return} or
+@code{#:error}.
+@end deffn
+
+@deffn {Generic Function} tc:return-value trap-context
+When @code{tc:type} gives @code{#:return}, this provides the value
+that is being returned.
+@end deffn
+
+@deffn {Generic Function} tc:stack trap-context
+Provides the stack at the point of the trap (as computed by
+@code{make-stack}, but cached so that the lengthy @code{make-stack}
+operation is not performed more than once for the same low level
+trap).
+@end deffn
+
+@deffn {Generic Function} tc:frame trap-context
+The innermost frame of the stack at the point of the trap.
+@end deffn
+
+@deffn {Generic Function} tc:depth trap-context
+The number of frames (including tail recursive non-real frames) in the
+stack at the point of the trap.
+@end deffn
+
+@deffn {Generic Function} tc:real-depth trap-context
+The number of real frames (that is, excluding the non-real frames that
+describe tail recursive calls) in the stack at the point of the trap.
+@end deffn
+
+
+@node Tracing Examples
+@subsubsection Tracing Examples
+
+The following examples show what tracing is and the kind of output that
+it generates. In the first example, we define a recursive function for
+reversing a list, then watch the effect of the recursive calls by
+tracing each call and return value.
+
+@lisp
+guile> (define (rev ls)
+ (if (null? ls)
+ ls
+ (append (rev (cdr ls))
+ (list (car ls)))))
+guile> (use-modules (ice-9 debugging traps) (ice-9 debugging trace))
+guile> (define t1 (make <procedure-trap>
+ #:procedure rev
+ #:behaviour (list trace-trap
+ trace-at-exit)))
+guile> (install-trap t1)
+guile> (rev '(a b c))
+| 2: [rev (a b c)]
+| 3: [rev (b c)]
+| 4: [rev (c)]
+| 5: [rev ()]
+| 5: =>()
+| 4: =>(c)
+| 3: =>(c b)
+| 2: =>(c b a)
+(c b a)
+@end lisp
+
+@noindent
+The number before the colon in this output (which follows @code{(ice-9
+debugging trace)}'s default output format) is the number of real frames
+on the stack. The fact that this number increases for each recursive
+call confirms that the implementation above of @code{rev} is not
+tail-recursive.
+
+In the next example, we probe the @emph{internal} workings of
+@code{rev} in more detail by using the @code{trace-until-exit}
+behaviour.
+
+@lisp
+guile> (uninstall-trap t1)
+guile> (define t2 (make <procedure-trap>
+ #:procedure rev
+ #:behaviour (list trace-trap
+ trace-until-exit)))
+guile> (install-trap t2)
+guile> (rev '(a b))
+| 2: [rev (a b)]
+| 2: (if (null? ls) ls (append (rev (cdr ls)) (list (car ls))))
+| 3: (null? ls)
+| 3: [null? (a b)]
+| 3: =>#f
+| 2: (append (rev (cdr ls)) (list (car ls)))
+| 3: (rev (cdr ls))
+| 4: (cdr ls)
+| 4: [cdr (a b)]
+| 4: =>(b)
+| 3: [rev (b)]
+| 3: (if (null? ls) ls (append (rev (cdr ls)) (list (car ls))))
+| 4: (null? ls)
+| 4: [null? (b)]
+| 4: =>#f
+| 3: (append (rev (cdr ls)) (list (car ls)))
+| 4: (rev (cdr ls))
+| 5: (cdr ls)
+| 5: [cdr (b)]
+| 5: =>()
+| 4: [rev ()]
+| 4: (if (null? ls) ls (append (rev (cdr ls)) (list (car ls))))
+| 5: (null? ls)
+| 5: [null? ()]
+| 5: =>#t
+| 4: (list (car ls))
+| 5: (car ls)
+| 5: [car (b)]
+| 5: =>b
+| 4: [list b]
+| 4: =>(b)
+| 3: [append () (b)]
+| 3: =>(b)
+| 3: (list (car ls))
+| 4: (car ls)
+| 4: [car (a b)]
+| 4: =>a
+| 3: [list a]
+| 3: =>(a)
+| 2: [append (b) (a)]
+| 2: =>(b a)
+(b a)
+@end lisp
+
+@noindent
+The output in this case shows every step that the evaluator performs
+in evaluating @code{(rev '(a b))}.
+
+
+@node Tracing Configuration
+@subsubsection Tracing Configuration
+
+The detail of what gets printed in each trace line, and the port to
+which tracing is written, can be configured by the procedures
+@code{set-trace-layout} and @code{trace-port}, both exported by the
+@code{(ice-9 debugging trace)} module.
+
+@deffn {Procedure with Setter} trace-port
+Get or set the port to which tracing is printed. The default is the
+value of @code{(current-output-port)} when the @code{(ice-9 debugging
+trace)} module is first loaded.
+@end deffn
+
+@deffn {Procedure} set-trace-layout format-string . arg-procs
+Layout each trace line using @var{format-string} and @var{arg-procs}.
+For each trace line, the list of values to be printed is obtained by
+calling all the @var{arg-procs}, passing the trap context as the only
+parameter to each one. This list of values is then formatted using
+the specified @var{format-string}.
+@end deffn
+
+@noindent
+The @code{(ice-9 debugging trace)} module exports a set of arg-proc
+procedures to cover most common needs, with names beginning
+@code{trace/}. These are all implemented on top of the @code{tc:} trap
+context accessor procedures documented in @ref{Trap Context}, and if any
+trace output not provided by the following is needed, it should be
+possible to implement based on a combination of the @code{tc:}
+procedures.
+
+@deffn {Procedure} trace/pid trap-context
+An arg-proc that returns the current process ID.
+@end deffn
+
+@deffn {Procedure} trace/stack-id trap-context
+An arg-proc that returns the stack ID of the stack in which the
+current trap occurred.
+@end deffn
+
+@deffn {Procedure} trace/stack-depth trap-context
+An arg-proc that returns the length (including non-real frames) of the
+stack at the point of the current trap.
+@end deffn
+
+@deffn {Procedure} trace/stack-real-depth trap-context
+An arg-proc that returns the length excluding non-real frames of the
+stack at the point of the current trap.
+@end deffn
+
+@deffn {Procedure} trace/stack trap-context
+An arg-proc that returns a string summarizing stack information. This
+string includes the stack ID, real depth, and count of additional
+non-real frames, with the format @code{"~a:~a+~a"}.
+@end deffn
+
+@deffn {Procedure} trace/source-file-name trap-context
+An arg-proc that returns the name of the source file for the innermost
+stack frame, or an empty string if source is not available for the
+innermost frame.
+@end deffn
+
+@deffn {Procedure} trace/source-line trap-context
+An arg-proc that returns the line number of the source code for the
+innermost stack frame, or zero if source is not available for the
+innermost frame.
+@end deffn
+
+@deffn {Procedure} trace/source-column trap-context
+An arg-proc that returns the column number of the start of the source
+code for the innermost stack frame, or zero if source is not available
+for the innermost frame.
+@end deffn
+
+@deffn {Procedure} trace/source trap-context
+An arg-proc that returns the source location for the innermost stack
+frame. This is a string composed of file name, line and column number
+with the format @code{"~a:~a:~a"}, or an empty string if source is not
+available for the innermost frame.
+@end deffn
+
+@deffn {Procedure} trace/type trap-context
+An arg-proc that returns a three letter abbreviation indicating the
+type of the current trap: @code{"APP"} for an application frame,
+@code{"EVA"} for an evaluation, @code{"RET"} for an exit trap, or
+@code{"ERR"} for an error (pseudo-)trap.
+@end deffn
+
+@deffn {Procedure} trace/real? trap-context
+An arg-proc that returns @code{" "} if the innermost stack frame is a
+real frame, or @code{"t"} if it is not.
+@end deffn
+
+@deffn {Procedure} trace/info trap-context
+An arg-proc that returns a string describing the expression being
+evaluated, application being performed, or return value, according to
+the current trap type.
+@end deffn
+
+@noindent
+@code{trace/stack-depth} and @code{trace/stack-real-depth} are identical
+to the trap context methods @code{tc:depth} and @code{tc:real-depth}
+described before (@pxref{Trap Context}), but renamed here for
+convenience.
+
+The default trace layout, as exhibited by the examples of the previous
+subsubsubsection, is set by this line of code from the @code{(ice-9 debugging
+traps)} module:
+
+@lisp
+(set-trace-layout "|~3@@a: ~a\n" trace/stack-real-depth trace/info)
+@end lisp
+
+@noindent
+If we rerun the first of those examples, but with trace layout
+configured to show source location and trap type in addition, the
+output looks like this:
+
+@lisp
+guile> (set-trace-layout "| ~25a ~3@@a: ~a ~a\n"
+ trace/source
+ trace/stack-real-depth
+ trace/type
+ trace/info)
+guile> (rev '(a b c))
+| standard input:29:0 2: APP [rev (a b c)]
+| standard input:4:21 3: APP [rev (b c)]
+| standard input:4:21 4: APP [rev (c)]
+| standard input:4:21 5: APP [rev ()]
+| standard input:2:9 5: RET =>()
+| standard input:4:13 4: RET =>(c)
+| standard input:4:13 3: RET =>(c b)
+| standard input:4:13 2: RET =>(c b a)
+(c b a)
+@end lisp
+
+
+@node Tracing and (ice-9 debug)
+@subsubsection Tracing and (ice-9 debug)
+
+The @code{(ice-9 debug)} module of the core Guile distribution
+provides a tracing facility that is roughly similar to that described
+here, but there are important differences.
+
+@itemize @bullet
+@item
+The @code{(ice-9 debug)} trace gives a nice pictorial view of changes
+in stack depth, by using indentation like this:
+
+@lisp
+[fact1 4]
+| [fact1 3]
+| | [fact1 2]
+| | | [fact1 1]
+| | | | [fact1 0]
+| | | | 1
+| | | 1
+| | 2
+| 6
+24
+@end lisp
+
+However its output can @emph{only} show the information seen here,
+which corresponds to @code{guile-debugging}'s @code{trace/info}
+procedure; it cannot be configured to show other pieces of information
+about the trap context in the way that @code{guile-debugging}'s trace
+feature can.
+
+@item
+The @code{(ice-9 debug)} trace only allows the tracing of procedure
+applications and their return values, whereas @code{guile-debugging}'s
+trace allows any kind of trap to be traced.
+
+It's interesting to note that @code{(ice-9 debug)}'s restriction here,
+which might initially appear to be just a straightforward consequence
+of its implementation, is also somewhat dictated by its pictorial
+display. The use of indentation in the output relies on hooking into
+the low level trap calls in such a way that the trapped application
+entries and exits exactly balance each other.
+@code{guile-debugging}'s more general traps interface allows traps to
+be installed such that entry and exit traps don't necessarily balance,
+which means that, in general, indentation diagrams like the one above
+don't work.
+@end itemize
+
+It isn't currently possible to use both @code{(ice-9 debug)} trace and
+@code{guile-debugging} in the same Guile session, because their settings
+of the low level trap options conflict with each other. (It should be
+possible to fix this, by modifying @code{(ice-9 debug)} to use
+@code{guile-debugging}'s trap installation interface, but only if and
+when @code{guile-debugging} is integrated into the core Guile
+distribution.)
+
+
+@node Traps Installing More Traps
+@subsubsection Traps Installing More Traps
+
+Sometimes it is desirable for the behaviour at one trap to install
+further traps. In other words, the behaviour is something like
+``Don't do much right now, but set things up to stop after two or
+three more steps'', or ``@dots{} when this frame completes''. This is
+absolutely fine. For example, it is easy to code a generic ``do
+so-and-so when the current frame exits'' procedure, which can be used
+wherever a trap context is available, as follows.
+
+@lisp
+(define (at-exit trap-context behaviour)
+ (install-trap (make <exit-trap>
+ #:depth (tc:depth trap-context)
+ #:single-shot #t
+ #:behaviour behaviour)))
+@end lisp
+
+To continue and pin down the example, this could then be used as part
+of a behaviour whose purpose was to measure the accumulated time spent
+in and below a specified procedure.
+
+@lisp
+(define calls 0)
+(define total 0)
+
+(define accumulate-time
+ (lambda (trap-context)
+ (set! calls (+ calls 1))
+ (let ((entry (current-time)))
+ (at-exit trap-context
+ (lambda (ignored)
+ (set! total
+ (+ total (- (current-time)
+ entry))))))))
+
+(install-trap (make <procedure-trap>
+ #:procedure my-proc
+ #:behaviour accumulate-time))
+@end lisp
+
+
+@node Common Trap Options
+@subsubsection Common Trap Options
+
+When creating any kind of trap object, settings for the trap being
+created are specified as options on the @code{make} call using syntax
+like this:
+
+@lisp
+(make <@var{trap-class}>
+ #:@var{option-keyword} @var{setting}
+ @dots{})
+@end lisp
+
+The following common options are provided by the base class
+@code{<trap>}, and so can be specified for any kind of trap.
+
+@deffn {Class} <trap>
+Base class for trap objects.
+@end deffn
+
+@deffn {Trap Option} #:condition thunk
+If not @code{#f}, this is a thunk which is called when the trap fires,
+to determine whether trap processing should proceed any further. If
+the thunk returns @code{#f}, the trap is basically suppressed.
+Otherwise processing continues normally. (Default value @code{#f}.)
+@end deffn
+
+@deffn {Trap Option} #:skip-count count
+A count of valid (after @code{#:condition} processing) firings of this
+trap to skip. (Default value 0.)
+@end deffn
+
+@deffn {Trap Option} #:single-shot boolean
+If not @code{#f}, this indicates that the trap should be automatically
+uninstalled after it has successfully fired (after @code{#:condition}
+and @code{#:skip-count} processing) for the first time. (Default
+value @code{#f}.)
+@end deffn
+
+@deffn {Trap Option} #:behaviour behaviour-proc
+A trap behaviour procedure --- as discussed in the preceding subsubsection
+--- or a list of such procedures, in which case each procedure is
+called in turn when the trap fires. (Default value @code{'()}.)
+@end deffn
+
+@deffn {Trap Option} #:repeat-identical-behaviour boolean
+Normally, if multiple trap objects are triggered by the same low level
+trap, and they request the same behaviour, it's only actually useful
+to do that behaviour once (per low level trap); so by default multiple
+requests for the same behaviour are coalesced. If this option is set
+other than @code{#f}, the contents of the @code{#:behaviour} option
+are uniquified so that they avoid being coalesced in this way.
+(Default value @code{#f}.)
+@end deffn
+
+
+@node Procedure Traps
+@subsubsection Procedure Traps
+
+The @code{<procedure-trap>} class implements traps that are triggered
+upon application of a specified procedure. Instances of this class
+should use the @code{#:procedure} option to specify the procedure to
+trap on.
+
+@deffn {Class} <procedure-trap>
+Class for traps triggered by application of a specified procedure.
+@end deffn
+
+@deffn {Trap Option} #:procedure procedure
+Specifies the procedure to trap on.
+@end deffn
+
+@noindent
+Example:
+
+@lisp
+(install-trap (make <procedure-trap>
+ #:procedure my-proc
+ #:behaviour (list trace-trap
+ trace-until-exit)))
+@end lisp
+
+
+@node Exit Traps
+@subsubsection Exit Traps
+
+The @code{<exit-trap>} class implements traps that are triggered upon
+stack frame exit past a specified stack depth. Instances of this
+class should use the @code{#:depth} option to specify the target stack
+depth.
+
+@deffn {Class} <exit-trap>
+Class for traps triggered by exit past a specified stack depth.
+@end deffn
+
+@deffn {Trap Option} #:depth depth
+Specifies the reference depth for the trap.
+@end deffn
+
+@noindent
+Example:
+
+@lisp
+(define (trace-at-exit trap-context)
+ (install-trap (make <exit-trap>
+ #:depth (tc:depth trap-context)
+ #:single-shot #t
+ #:behaviour trace-trap)))
+@end lisp
+
+@noindent
+(This is the actual definition of the @code{trace-at-exit} behaviour.)
+
+
+@node Entry Traps
+@subsubsection Entry Traps
+
+The @code{<entry-trap>} class implements traps that are triggered upon
+any stack frame entry. No further parameters are needed to specify an
+instance of this class, so there are no class-specific trap options.
+Note that it remains possible to use the common trap options
+(@pxref{Common Trap Options}), for example to set a trap for the
+@var{n}th next frame entry.
+
+@deffn {Class} <entry-trap>
+Class for traps triggered by any stack frame entry.
+@end deffn
+
+@noindent
+Example:
+
+@lisp
+(install-trap (make <entry-trap>
+ #:skip-count 5
+ #:behaviour gds-debug-trap))
+@end lisp
+
+
+@node Apply Traps
+@subsubsection Apply Traps
+
+The @code{<apply-trap>} class implements traps that are triggered upon
+any procedure application. No further parameters are needed to
+specify an instance of this class, so there are no class-specific trap
+options. Note that it remains possible to use the common trap options
+(@pxref{Common Trap Options}), for example to set a trap for the next
+application where some condition is true.
+
+@deffn {Class} <apply-trap>
+Class for traps triggered by any procedure application.
+@end deffn
+
+@noindent
+Example:
+
+@lisp
+(install-trap (make <apply-trap>
+ #:condition my-condition
+ #:behaviour gds-debug-trap))
+@end lisp
+
+
+@node Step Traps
+@subsubsection Step Traps
+
+The @code{<step-trap>} class implements traps that do single-stepping
+through a program's execution. They come in two flavours, with and
+without a specified file name. If a file name is specified, the trap
+is triggered by the next evaluation, application or frame exit
+pertaining to source code from the specified file. If a file name is
+not specified, the trap is triggered by the next evaluation,
+application or frame exit from any file (or for code whose source
+location was not recorded), in other words by the next evaluator step
+of any kind.
+
+The design goal of the @code{<step-trap>} class is to match what a
+user would intuitively think of as single-stepping through their code,
+either through code in general (roughly corresponding to GDB's
+@code{step} command, for example), or through code from a particular
+source file (roughly corresponding to GDB's @code{next}). Therefore
+if you are using @code{guile-debugging} to single-step through code
+and finding its behaviour counter-intuitive, please let me know so
+that I can improve it.
+
+The implementation and options of the @code{<step-trap>} class are
+complicated by the fact that it is unreliable to determine whether a
+low level frame exit trap is applicable to a specified file by
+examining the details of the reported frame. This is a consequence of
+tail recursion, which has the effect that many frames can be removed
+from the stack at once, with only the outermost frame being reported
+by the low level trap call. The effects of this on the
+@code{<step-trap>} class are such as to require the introduction of
+the strange-looking @code{#:exit-depth} option, for the following
+reasons.
+
+@itemize @bullet
+@item
+When stopped at the start of an application or evaluation frame, and
+it is desired to continue execution until the next ``step'' in the same
+source file, that next step could be the start of a nested application
+or evaluation frame, or --- if the procedure definition is in a
+different file, for example --- it could be the exit from the current
+frame.
+
+@item
+Because of the effects of tail recursion noted above, the current
+frame exit possibility must be expressed as frame exit past a
+specified stack depth. When an instance of the @code{<step-trap>}
+class is installed from the context of an application or evaluation
+frame entry, the @code{#:exit-depth} option should be used to specify
+this stack depth.
+
+@item
+When stopped at a frame exit, on the other hand, we know that the next
+step must be an application or evaluation frame entry. In this
+context the @code{#:exit-depth} option is not needed and should be
+omitted or set to @code{#f}.
+@end itemize
+
+@noindent
+When a step trap is installed without @code{#:single-shot #t}, such
+that it keeps firing, the @code{<step-trap>} code automatically
+updates its idea of the @code{#:exit-depth} setting each time, so that
+the trap always fires correctly for the following step.
+
+@deffn {Class} <step-trap>
+Class for single-stepping traps.
+@end deffn
+
+@deffn {Trap Option} #:file-name name
+If not @code{#f}, this is a string containing the name of a source
+file, and restricts the step trap to evaluation steps within that
+source file. (Default value @code{#f}.)
+@end deffn
+
+@deffn {Trap Option} #:exit-depth depth
+If not @code{#f}, this is a positive integer implying that the next
+step may be frame exit past the stack depth @var{depth}. See the
+discussion above for more details. (Default value @code{#f}.)
+@end deffn
+
+@noindent
+Example:
+
+@lisp
+(install-trap (make <step-trap>
+ #:file-name (frame-file-name
+ (stack-ref stack index))
+ #:exit-depth (- (stack-length stack)
+ (stack-ref stack index))
+ #:single-shot #t
+ #:behaviour debug-trap))
+@end lisp
+
+
+@node Source Traps
+@subsubsection Source Traps
+
+The @code{<source-trap>} class implements traps that are attached to a
+precise source code expression, as read by the reader, and which fire
+each time that that expression is evaluated. These traps use a low
+level Guile feature which can mark individual expressions for
+trapping, and are relatively efficient. But it can be tricky to get
+at the source expression in the first place, and these traps are
+liable to become irrelevant if the procedure containing the expression
+is reevaluated; these issues are discussed further below.
+
+@deffn {Class} <source-trap>
+Class for traps triggered by evaluation of a specific Scheme
+expression.
+@end deffn
+
+@deffn {Trap Option} #:expression expr
+Specifies the Scheme expression to trap on.
+@end deffn
+
+@noindent
+Example:
+
+@lisp
+(display "Enter an expression: ")
+(let ((x (read)))
+ (install-trap (make <source-trap>
+ #:expression x
+ #:behaviour (list trace-trap
+ trace-at-exit)))
+ (primitive-eval x))
+@print{}
+Enter an expression: (+ 1 2 3 4 5 6)
+| 3: (+ 1 2 3 4 5 6)
+| 3: =>21
+21
+@end lisp
+
+The key point here is that the expression specified by the
+@code{#:expression} option must be @emph{exactly} (i.e. @code{eq?} to)
+what is going to be evaluated later. It doesn't work, for example, to
+say @code{#:expression '(+ x 3)}, with the expectation that the trap
+will fire whenever evaluating any expression @code{(+ x 3)}.
+
+The @code{trap-here} macro can be used in source code to create and
+install a source trap correctly. Take for example the factorial
+function defined in the @code{(ice-9 debugging example-fns)} module:
+
+@lisp
+(define (fact1 n)
+ (if (= n 0)
+ 1
+ (* n (fact1 (- n 1)))))
+@end lisp
+
+@noindent
+To set a source trap on a particular expression --- let's say the
+expression @code{(= n 0)} --- edit the code so that the expression is
+enclosed in a @code{trap-here} macro call like this:
+
+@lisp
+(define (fact1 n)
+ (if (trap-here (= n 0) #:behaviour debug-trap)
+ 1
+ (* n (fact1 (- n 1)))))
+@end lisp
+
+@deffn {Macro} trap-here expression . trap-options
+Install a source trap with options @var{trap-options} on
+@var{expression}, then return with the whole call transformed to
+@code{(begin @var{expression})}.
+@end deffn
+
+Note that if the @code{trap-here} incantation is removed, and
+@code{fact1} then redefined by reloading its source file, the effect
+of the source trap is lost, because the text ``(= n 0)'' is read again
+from scratch and becomes a new expression @code{(= n 0)} which does
+not have the ``trap here'' mark on it.
+
+If the semantics and setting of source traps seem unwieldy, location
+traps may meet your need more closely; these are described in the
+following subsubsection.
+
+
+@node Location Traps
+@subsubsection Location Traps
+
+The @code{<location-trap>} class implements traps that are triggered
+by evaluation of code at a specific source location or within a
+specified range of source locations. When compared with source traps,
+they are easier to set, and do not become irrelevant when the relevant
+code is reloaded; but unfortunately they are considerably less
+efficient, as they require running some ``are we in the right place
+for a trap'' code on every low level frame entry trap call.
+
+@deffn {Class} <location-trap>
+Class for traps triggered by evaluation of code at a specific source
+location or in a specified range of source locations.
+@end deffn
+
+@deffn {Trap Option} #:file-regexp regexp
+A regular expression specifying the filenames that will match this
+trap. This option must be specified when creating a location trap.
+@end deffn
+
+@deffn {Trap Option} #:line line-spec
+If specified, @var{line-spec} describes either a single line, in which
+case it is a single integer, or a range of lines, in which case it is
+a pair of the form @code{(@var{min-line} . @var{max-line})}. All line
+numbers are 0-based, and the range form is inclusive-inclusive. If
+@code{#f} or not specified, the trap is not restricted by line number.
+(Default value @code{#f}.)
+@end deffn
+
+@deffn {Trap Option} #:column column-spec
+If specified, @var{column-spec} describes either a single column, in
+which case it is a single integer, or a range of columns, in which
+case it is a pair of the form @code{(@var{min-column}
+. @var{max-column})}. All column numbers are 0-based, and the range
+form is inclusive-inclusive. If @code{#f} or not specified, the trap
+is not restricted by column number. (Default value @code{#f}.)
+@end deffn
+
+@noindent
+Example:
+
+@lisp
+(install-trap (make <location-trap>
+ #:file-regexp "example-fns.scm"
+ #:line '(11 . 13)
+ #:behaviour gds-debug-trap))
+@end lisp
+
+
+@node Trap Shorthands
+@subsubsection Trap Shorthands
+
+If the code described in the preceding subsubsections for creating and
+manipulating traps seems a little long-winded, it is of course
+possible to define more convenient shorthand forms for typical usage
+patterns. For example, my own @file{.guile} file contains the
+following definitions for setting breakpoints and for tracing.
+
+@lisp
+(define (break! proc)
+ (install-trap (make <procedure-trap>
+ #:procedure proc
+ #:behaviour gds-debug-trap)))
+
+(define (trace! proc)
+ (install-trap (make <procedure-trap>
+ #:procedure proc
+ #:behaviour (list trace-trap
+ trace-at-exit))))
+
+(define (trace-subtree! proc)
+ (install-trap (make <procedure-trap>
+ #:procedure proc
+ #:behaviour (list trace-trap
+ trace-until-exit))))
+@end lisp
+
+Definitions like these are not provided out-of-the-box by
+@code{guile-debugging}, because different users will have different
+ideas about what their default debugger should be, or, for example,
+which of the common trap options (@pxref{Common Trap Options}) it
+might be useful to expose through such shorthand procedures.
+
+
+@node Trap Utilities
+@subsubsection Trap Utilities
+
+@code{list-traps} can be used to print a description of all known trap
+objects. This uses a weak value hash table, keyed by a trap index
+number. Each trap object has its index number assigned, and is added
+to the hash table, when it is created by a @code{make @var{trap-class}
+@dots{}} call. When a trap object is GC'd, it is automatically
+removed from the hash table, and so no longer appears in the output
+from @code{list-traps}.
+
+@deffn {Variable} all-traps
+Weak value hash table containing all known trap objects.
+@end deffn
+
+@deffn {Procedure} list-traps
+Print a description of all known trap objects.
+@end deffn
+
+The following example shows a single trap that traces applications of
+the procedure @code{facti}.
+
+@lisp
+guile> (list-traps)
+#<<procedure-trap> 100d2e30> is an instance of class <procedure-trap>
+Slots are:
+ number = 1
+ installed = #t
+ condition = #f
+ skip-count = 0
+ single-shot = #f
+ behaviour = (#<procedure trace-trap (trap-context)>)
+ repeat-identical-behaviour = #f
+ procedure = #<procedure facti (n a)>
+@end lisp
+
+When @code{all-traps} or @code{list-traps} reveals a trap that you
+want to modify but no longer have a reference to, you can retrieve the
+trap object by calling @code{get-trap} with the trap's number. For
+example, here's how you could change the behaviour of the trap listed
+just above.
+
+@lisp
+(slot-set! (get-trap 1) 'behaviour (list debug-trap))
+@end lisp
+
+@deffn {Procedure} get-trap number
+Return the trap object with the specified @var{number}, or @code{#f}
+if there isn't one.
+@end deffn
+
+
+@node Breakpoints
+@subsection Breakpoints
+
+While they are an important piece of infrastructure, and directly
+usable in some scenarios, traps are still too low level to meet some
+of the requirements of interactive development.
+
+For example, in my experience a common scenario is that a newly
+written procedure is not working properly, and so you'd like to be
+able to step or trace through its code to find out why. Ideally this
+should be possible from the IDE and without having to modify the
+source code. There are two problems with using traps directly in this
+scenario.
+
+@enumerate
+@item
+They are too detailed: constructing and installing a trap requires you
+to say what kind of trap you want and to specify fairly low level
+options for it, whereas what you really want is just to say ``break
+here using the most efficient means possible.''
+
+@item
+The most efficient kinds of trap --- that is, @code{<procedure-trap>}
+and @code{<source-trap>} --- can only be specified and installed
+@emph{after} the code that they refer to has been loaded. This is an
+inconvenient detail for the user to deal with, and in some
+applications it might be very difficult to insert an instruction to
+install the required trap in between when the code is loaded and when
+the procedure concerned is first called. It would be better to be
+able to tell Guile about the requirement upfront, and for it to deal
+with installing the trap when possible.
+@end enumerate
+
+We solve these problems by introducing breakpoints. A breakpoint is
+something which says ``I want to break at location X, or in procedure
+P --- just make it happen'', and can be set regardless of whether the
+relevant code has already been loaded. Breakpoints use traps to do
+their work, but that is a detail that the user will usually not have
+to care about.
+
+Breakpoints are provided by a combination of Scheme code in the client
+program, and facilities for setting and managing breakpoints in the
+GDS front end. On the Scheme side the entry points are as follows.
+
+@deffn {Getter with Setter} default-breakpoint-behaviour
+A ``getter with setter'' procedure that can be used to get or set the
+default behaviour for new breakpoints. When a new default behaviour
+is set, by calling
+
+@lisp
+(set! (default-breakpoint-behaviour) @var{new-behaviour})
+@end lisp
+
+@noindent
+the new behaviour applies to all following @code{break-in} and
+@code{break-at} calls, but does not affect breakpoints which have
+already been set. @var{new-behaviour} should be a behaviour procedure
+with the signature
+
+@lisp
+(lambda (trap-context) @dots{})
+@end lisp
+
+@noindent
+as described in @ref{Specifying Trap Behaviour}.
+@end deffn
+
+@deffn {Procedure} break-in procedure-name [module-or-file-name] [options]
+Set a breakpoint on entry to the procedure named @var{procedure-name},
+which should be a symbol. @var{module-or-file-name}, if present, is
+the name of the module (a list of symbols) or file (a string) which
+includes the target procedure. If @var{module-or-file-name} is
+absent, the target procedure is assumed to be in the current module.
+
+The available options are any of the common trap options
+(@pxref{Common Trap Options}), and are used when creating the
+breakpoint's underlying traps. The default breakpoint behaviour
+(given earlier to @code{default-breakpoint-behaviour}) is only used if
+these options do not include @code{#:behaviour @var{behaviour}}.
+@end deffn
+
+@deffn {Procedure} break-at file-name line column [options]
+Set a breakpoint on the expression in file @var{file-name} whose
+opening parenthesis is on line @var{line} at column @var{column}.
+@var{line} and @var{column} both count from 0 (not from 1).
+
+The available options are any of the common trap options
+(@pxref{Common Trap Options}), and are used when creating the
+breakpoint's underlying traps. The default breakpoint behaviour
+(given earlier to @code{default-breakpoint-behaviour}) is only used if
+these options do not include @code{#:behaviour @var{behaviour}}.
+@end deffn
+
+@deffn {Procedure} set-gds-breakpoints
+Ask the GDS front end for a list of breakpoints to set, and set these
+using @code{break-in} and @code{break-at} as appropriate.
+@end deffn
+
+@code{default-breakpoint-behaviour}, @code{break-in} and
+@code{break-at} allow an application's startup code to specify any
+breakpoints that it needs inline in that code. For example, to trace
+calls and arguments to a group of procedures to handle HTTP requests,
+one might write something like this:
+
+@lisp
+(use-modules (ice-9 debugging breakpoints)
+ (ice-9 debugging trace))
+
+(set! (default-breakpoint-behaviour) trace-trap)
+
+(break-in 'handle-http-request '(web http))
+(break-in 'read-http-request '(web http))
+(break-in 'decode-form-data '(web http))
+(break-in 'send-http-response '(web http))
+@end lisp
+
+@code{set-gds-breakpoints} can be used as well as or instead of the
+above, and is intended to be the most practical option if you are
+using GDS. The idea is that you only need to add this one call
+somewhere in your application's startup code, like this:
+
+@lisp
+(use-modules (ice-9 gds-client))
+(set-gds-breakpoints)
+@end lisp
+
+@noindent
+and then all the details of the breakpoints that you want to set can
+be managed through GDS. For the details of GDS's breakpoints
+interface, see @ref{Setting and Managing Breakpoints}.
+
+
@c Local Variables:
@c TeX-master: "guile.texi"
@c End:
diff --git a/doc/ref/scheme-using.texi b/doc/ref/scheme-using.texi
index b596ce50a..f7f49a45d 100644
--- a/doc/ref/scheme-using.texi
+++ b/doc/ref/scheme-using.texi
@@ -309,11 +309,16 @@ however it may be continued over multiple lines.
[to be completed]
@deffn {Debugger Command} step [n]
-Continue until entry to @var{n}th next frame.
+Tell the debugged program to do @var{n} single-steps to the next frame
+entry or exit of any kind. @var{n} defaults to 1.
@end deffn
@deffn {Debugger Command} next [n]
-Continue until entry to @var{n}th next frame in same file.
+Tell the debugged program to do @var{n} single-steps to the entry or
+exit of a frame whose code comes from the same source file as the
+selected stack frame. (See @ref{Step Traps} for the details of how
+this works.) If the selected stack frame has no source, the effect of
+this command is the same as of @code{step}. @var{n} defaults to 1.
@end deffn
@@ -323,8 +328,9 @@ Continue until entry to @var{n}th next frame in same file.
[to be completed]
@deffn {Debugger Command} finish
-Continue until evaluation of the current frame is complete, and
-print the result obtained.
+Tell the program being debugged to continue running until the
+completion of the selected stack frame, and at that time to print the
+result and reenter the command line debugger.
@end deffn
@deffn {Debugger Command} trace-finish
@@ -338,7 +344,7 @@ Trace until evaluation of the current frame is complete.
[to be completed]
@deffn {Debugger Command} continue
-Continue program execution.
+Tell the program being debugged to continue running.
@end deffn
@@ -405,7 +411,774 @@ can also run a program until it hits a breakpoint, then examine,
modify and reevaluate some of the relevant code, and then tell the
program to continue running.
+@ignore
+GDS is a user interface for working on Guile Scheme programs in Emacs.
+It aims to provide whatever facilities are needed to make the writing,
+debugging and maintenance of Scheme code in Emacs as fluid and
+productive as possible. These facilities currently include the
+following.
+
+@table @asis
+@item Displaying the Scheme stack
+When running Scheme code hits a trap or throws an exception, GDS can
+display the stack at the point of the trap or exception. The
+presentation makes it very easy to move up and down the stack, showing
+whenever possible the source code for each frame in another Emacs
+buffer, and allowing you to evaluate test expressions in the context of
+the selected frame.
+
+@item Continuing execution from a trap
+When GDS is showing the stack for code that has hit a trap, it also
+allows you to control how execution continues from that point. For
+example you can select a stack frame and tell Guile to run until that
+frame completes, at which point GDS will display the frame's return
+value.
+
+@item Evaluating Scheme code
+GDS allows you to select a region of a Scheme buffer and send it to
+Guile for evaluation, or to enter a Scheme expression to be evaluated in
+the Emacs minibuffer. In both cases the evaluation results are popped
+up in a temporary Emacs window.
+
+@item Setting breakpoints in Scheme code
+GDS makes it easy to set breakpoints in Scheme code from within Emacs.
+Deep down this uses the traps described in previous chapters, but GDS
+makes the practicalities as simple as typing @kbd{C-x @key{SPC}}. When
+a GDS breakpoint is hit, the stack at that point is popped up in Emacs.
+GDS also remembers your breakpoints between editing sessions, so you
+don't have to set them again when you visit the relevant files.
+
+@item Access to Guile's built in help system
+GDS makes it easy to query Guile's ``help'' and ``apropos'' commands,
+and pops up the results in a temporary Emacs window.
+
+@item Symbol completion
+GDS provides a keystroke which tries to complete a partially entered
+symbol by asking Guile to match it against all the accessible bindings.
+@end table
+
+(For a hands-on, tutorial introduction to using GDS, use Emacs to open
+the file @file{gds-tutorial.txt}, which is included with the
+guile-debugging distribution, and then follow the steps in that file.)
+
+GDS can provide these facilities for any number of Guile Scheme programs
+(which we often call ``clients'') at once, and these programs can be
+started either completely independently of GDS, including outside Emacs,
+or specifically @emph{by} GDS. The two common cases are:
+@itemize
+@item
+a Guile application, such as @uref{http://www.gnucash.org, GnuCash},
+which is started from your desktop, and which connects to GDS as a
+result of some incantation added to its startup code
+
+@item
+a ``utility'' Guile process which is run by GDS to provide help,
+completion and evaluation for Scheme code that you are working on in
+Emacs.
+@end itemize
+
+@noindent
+The user experience --- in other words the ways that the GDS front end
+allows you to interact with the client --- is much the same in all
+cases.
+
+Communication between the Guile client program and GDS uses a TCP
+socket, which means that it is orthogonal to any other interfaces that
+the client program has. In particular GDS does not interfere with a
+program's standard input and output.
+@end ignore
+
+@menu
+* GDS Setup::
+* How To Use GDS::
+* Displaying the Scheme Stack::
+* Continuing Execution::
+* Evaluating Scheme Code::
+* Setting and Managing Breakpoints::
+* Access to Guile Help and Completion::
+* Associating Buffers with Clients::
+* An Example GDS Session::
+* GDS Architecture::
+@end menu
+
+
+@node GDS Setup
+@subsection GDS Setup
+
+GDS's Scheme and Emacs Lisp files will have been installed in
+the correct places system-wide when the @code{guile-debugging} package
+as a whole was installed. To enable the use of GDS in your own Emacs
+sessions, simply add
+
+@lisp
+(require 'gds)
+@end lisp
+
+@noindent
+somewhere in your @file{.emacs} file.
+
+
+@node How To Use GDS
+@subsection How To Use GDS
+
+There are lots of ways to use GDS, but they boil down to two overall
+approaches.
+
+@enumerate
+@item
+When you are writing Scheme code in Emacs, you can use GDS while you are
+writing to help with things like name completion, looking up help, and
+evaluating fragments of code to check that they do what you expect.
+
+The first time you do something that needs a running Guile process, GDS
+will automatically create one as an Emacs subprocess. This Guile
+program does nothing but wait for and act on instructions from GDS, and
+we refer to it as a @dfn{utility} Guile client.
+
+Over time this utility Guile will accumulate the code that you ask it to
+evaluate, and you can also tell it to load complete files or modules by
+sending it @code{load} or @code{use-modules} expressions. You can set
+breakpoints and evaluate code which hits those breakpoints, and GDS will
+pop up the stack at the breakpoint so you can explore your code by
+single-stepping and evaluating test expressions.
+
+@item
+Alternatively, you can use GDS to explore and debug a Guile program or
+script which is started independently of GDS. This could be a script
+that you invoke from the command line, or a graphical Guile-using
+application which is launched from your desktop's start menu.
+
+In this case the program has to put something in its startup code to
+cause it to connect to GDS at some point: either immediately during the
+startup processing, or later when an error occurs or a trap is hit.
+Several possibilities for this are described below.
+
+Under certain conditions, then, the program will stop, pass its current
+Scheme stack to GDS, and then wait for instruction before continuing
+execution. At such points you can use GDS to explore the stack,
+obviously, but also to set or delete other breakpoints, modify the
+program's code (by editing and then reevaluating it from Emacs), and use
+the help and completion facilities, before eventually telling the
+program to single-step or to continue running normally.
+@end enumerate
+
+Here are some of the ways that a Guile program or script can arrange in
+its startup code to use GDS.
+
+@subsubsection Invoking GDS when an Exception Occurs
+
+@lisp
+(use-modules (ice-9 gds-client)
+ (ice-9 debugging traps))
+
+(on-lazy-handler-dispatch gds-debug-trap)
+@end lisp
+
+This means that the program will use GDS to display the stack whenever
+it hits an exception that is protected by a @code{lazy-catch} using
+Guile's standard @code{lazy-catch-handler} (defined in
+@file{boot-9.scm}).
+
+@code{lazy-catch-handler} is used by the @code{stack-catch} procedure,
+provided by the @code{(ice-9 stack-catch)} module, so this will include
+exceptions within a @code{stack-catch}. @code{lazy-catch-handler} is
+also used by the standard Guile REPL, when you run Guile interactively,
+so you can add the above lines to your @file{.guile} file if you want to
+use GDS whenever something that you type into the REPL throws an
+exception.
+
+@subsubsection Setting GDS-managed Breakpoints
+
+@lisp
+(use-modules (ice-9 gds-client))
+(set-gds-breakpoints)
+@end lisp
+
+These lines tell the program to connect to GDS immediately and download
+a set of breakpoint definitions. The program sets those breakpoints in
+its code, then continues running.
+
+When the program later hits one of the breakpoints, it will use GDS to
+display the stack and wait for instruction on what to do next, as
+described above.
+
+@subsubsection Setting Specific Breakpoints
+
+@lisp
+(use-modules (ice-9 debugging breakpoints)
+ (ice-9 gds-client))
+
+(break-in 'fact2 "ice-9/debugging/example-fns"
+ #:behaviour gds-debug-trap)
+@end lisp
+
+In this example, the program chooses to define its breakpoint explicitly
+in its code, rather than downloading definitions from GDS, but it still
+uses GDS to control what happens when the breakpoint is hit, by
+specifying @code{gds-debug-trap} as the breakpoint behaviour.
+
+@subsubsection Accepting GDS Instructions at Any Time
+
+In addition to setting breakpoints and/or an exception handler as
+described above, a Guile program can in principle set itself up to
+accept new instructions from GDS at any time, not just when it has
+stopped at a breakpoint or exception. This would allow the GDS user to
+set new breakpoints or to evaluate code in the context of the running
+program, without having to wait for the program to stop first.
+
+@lisp
+(use-modules (ice-9 gds-client))
+(gds-accept-input #t)
+@end lisp
+
+@code{gds-accept-input} causes the calling program to loop processing
+instructions from GDS, until GDS sends the @code{continue} instruction.
+This blocks the thread that calls it, however, so it will normally be
+more practical for the program to set up a dedicated GDS thread and call
+@code{gds-accept-input} from that thread.
+
+For @code{select}-driven applications, an alternative approach would be
+for the GDS client code to provide an API which allowed the application
+to
+
+@itemize
+@item
+discover the file descriptors (or Scheme ports) that are used for
+receiving instruction from the GDS front end, so that it could include
+these in its @code{select} call
+
+@item
+call the GDS instruction handler when @code{select} indicated data
+available for reading on those descriptors/ports.
+@end itemize
+
+@noindent
+This approach is not yet implemented, though.
+
+@subsubsection Utility Guile Implementation
+
+We bring this subsection full circle by noting that the ``utility'' Guile
+client, which GDS starts automatically when you use GDS as described
+under approach 1 above, is really just a special case of ``a Guile
+program or script which is started independently'' (approach 2), and
+provides the services that the GDS front end needs by a simple
+combination of some of the code fragments just described.
+
+To be precise, the code for the utility Guile client is essentially
+this:
+
+@lisp
+(use-modules (ice-9 gds-client))
+
+(set-gds-breakpoints)
+(named-module-use! '(guile-user) '(ice-9 session))
+(gds-accept-input #f))
+@end lisp
+
+@code{set-gds-breakpoints} works as already described. The
+@code{named-module-use!} line ensures that the client can process
+@code{help} and @code{apropos} expressions, which is what the front end
+sends to implement lookups in Guile's online help. The @code{#f}
+parameter to @code{gds-accept-input} means that the @code{continue}
+instruction will not cause the instruction loop to exit, which makes
+sense here because the utility client has nothing to do except to
+process GDS instructions.
+
+(The utility client does not use @code{on-lazy-handler-dispatch},
+because it has its own mechanism for catching and reporting exceptions
+in the code that it is asked to evaluate. This mechanism summarizes the
+exception and gives the user a button they can click to see the full
+stack, so the end result is very similar to what
+@code{on-lazy-handler-dispatch} provides.)
+
+
+@node Displaying the Scheme Stack
+@subsection Displaying the Scheme Stack
+
+When you specify @code{gds-debug-trap} as the behaviour for a trap or
+a breakpoint and the Guile program concerned hits that trap or
+breakpoint, GDS displays the stack and the relevant Scheme source code
+in Emacs, allowing you to explore the state of the program and then
+decide what to do next. The same applies if the program calls
+@code{(on-lazy-handler-dispatch gds-debug-trap)} and then throws an
+exception that passes through @code{lazy-handler-dispatch}, except
+that in this case you can only explore; it isn't possible to continue
+normal execution after an exception.
+
+The following commands are available in the stack buffer for exploring
+the state of the program.
+
+@table @asis
+@item @kbd{u}, @kbd{C-p}, @kbd{@key{up}}
+@findex gds-up
+Select the stack frame one up from the currently selected frame
+(@code{gds-up}). GDS displays stack frames with the innermost at the
+top, so moving ``up'' means selecting a more ``inner'' frame.
+
+@item @kbd{d}, @kbd{C-n}, @kbd{@key{down}}
+@findex gds-down
+Select the stack frame one down from the currently selected frame
+(@code{gds-down}). GDS displays stack frames with the innermost at the
+top, so moving ``down'' means selecting a more ``outer'' frame.
+
+@item @kbd{@key{RET}}
+@findex gds-select-stack-frame
+Select the stack frame at point (@code{gds-select-stack-frame}). This
+is useful after clicking somewhere in the stack trace with the mouse.
+@end table
+
+Selecting a frame means that GDS will display the source code
+corresponding to that frame in the adjacent window, and that
+subsequent frame-sensitive commands, such as @code{gds-evaluate} (see
+below) and @code{gds-step-over} (@pxref{Continuing Execution}), will
+refer to that frame.
+
+@table @kbd
+@item e
+@findex gds-evaluate
+Evaluate a variable or expression in the local environment of the
+selected stack frame (@code{gds-evaluate}). The result is displayed in
+the echo area.
+
+@item I
+@findex gds-frame-info
+Show summary information about the selected stack frame
+(@code{gds-frame-info}). This includes what type of frame it is, the
+associated expression, and the frame's source location, if any.
+
+@item A
+@findex gds-frame-args
+For an application frame, display the frame's arguments
+(@code{gds-frame-args}).
+
+@item S
+@findex gds-proc-source
+For an application frame, show the Scheme source code of the procedure
+being called (@code{gds-proc-source}). The source code (where
+available) is displayed in the echo area.
+@end table
+
+@kbd{S} (@code{gds-proc-source}) is useful when the procedure being
+called was created by an anonymous @code{(lambda @dots{})} expression.
+Such procedures appear in the stack trace as @code{<procedure #f
+(@dots{})>}, which doesn't give you much clue as to what will happen
+next. @kbd{S} will show you the procedure's code, which is usually
+enough for you to identify it.
+
+
+@node Continuing Execution
+@subsection Continuing Execution
+
+If it makes sense to continue execution from the stack which is being
+displayed, GDS provides the following further commands in the stack
+buffer.
+
+@table @asis
+@item @kbd{g}, @kbd{c}, @kbd{q}
+@findex gds-go
+Tell the program to continue running (@code{gds-go}). It may of course
+stop again if it hits another trap, or another occurrence of the same
+trap.
+
+The multiple keystrokes reflect that you can think of this as ``going'',
+``continuing'' or ``quitting'' (in the sense of quitting the GDS
+display).
+
+@item @kbd{@key{SPC}}
+@findex gds-step-file
+Tell the program to do a single-step to the next entry or exit of a
+frame whose code comes from the same source file as the selected stack
+frame (@code{gds-step-file}).
+
+In other words, you can hit @kbd{@key{SPC}} repeatedly to step through
+the code in a given file, automatically stepping @emph{over} any
+evaluations or procedure calls that use code from other files (or from
+no file).
+
+If the selected stack frame has no source, the effect of this command is
+the same as that of @kbd{i}, described next.
+
+@item @kbd{i}
+@findex gds-step-into
+Tell the debugged program to do a single-step to the next frame entry or
+exit of any kind (@code{gds-step-into}). @kbd{i} therefore steps
+through code at the most detailed level possible.
+
+@item @kbd{o}
+@findex gds-step-over
+Tell the debugged program to continue running until the selected stack
+frame completes, and then to display its result (@code{gds-step-over}).
+Note that the program may stop before then if it hits another trap; in
+this case the trap telling it to stop when the marked frame completes
+remains in place and so will still fire at the appropriate point.
+@end table
+
+
+@node Evaluating Scheme Code
+@subsection Evaluating Scheme Code
+
+The following keystrokes and commands provide various ways of sending
+code to a Guile client process for evaluation.
+
+@table @kbd
+@item M-C-x
+@findex gds-eval-defun
+Evaluate the ``top level defun'' that the cursor is in, in other words
+the smallest balanced expression which includes the cursor and whose
+opening parenthesis is in column 0 (@code{gds-eval-defun}).
+
+@item C-x C-e
+@findex gds-eval-last-sexp
+Evaluate the expression that ends just before the cursor
+(@code{gds-eval-last-sexp}). This is designed so that it is easy to
+evaluate an expression that you have just finished typing.
+
+@item C-c C-e
+@findex gds-eval-expression
+Read a Scheme expression using the minibuffer, and evaluate that
+expression (@code{gds-eval-expression}).
+
+@item C-c C-r
+@findex gds-eval-region
+Evaluate the Scheme code in the marked region of the current buffer
+(@code{gds-eval-region}). Note that GDS does not check whether the
+region contains a balanced expression, or try to expand the region so
+that it does; it uses the region exactly as it is.
+@end table
+
+
+@node Setting and Managing Breakpoints
+@subsection Setting and Managing Breakpoints
+
+You can create a breakpoint in GDS by typing @kbd{C-x @key{SPC}} in a
+Scheme mode buffer. To create a breakpoint on calls to a procedure
+--- i.e. the equivalent of calling @code{break-in} --- place the
+cursor on the procedure's name and type @kbd{C-x @key{SPC}}. To
+create breakpoints on a particular expression, or on the series of
+expressions in a particular region --- i.e. as with @code{break-at}
+--- select the expression or region in the usual way and type @kbd{C-x
+@key{SPC}}. In general, GDS assumes that you want a @code{break-at}
+breakpoint if there is an active region, and a @code{break-in}
+breakpoint otherwise.
+
+When you create a breakpoint like this, two things happen. Firstly,
+if the current buffer is associated with a Guile client program, the
+new breakpoint definition is immediately sent to that client (or, if
+the client cannot accept input immediately, it is held in readiness to
+pass to the client at the next possible opportunity). This allows the
+new breakpoint to take effect as soon as possible in the relevant
+client program.
+
+Secondly, it is added to GDS's @emph{global} list of all breakpoints.
+This list holds the breakpoint information that will be given to any
+client program that asks for it by calling @code{set-gds-breakpoints}.
+The fact that this list is global, rather than client-specific, means
+that the breakpoints you have set will automatically be recreated if
+the program you are debugging has to be stopped and restarted ---
+which in my experience happens often.@footnote{An important point here
+is that there is nothing that unambiguously relates two subsequent
+runs of the same client program, which might allow GDS to pass on
+breakpoint settings more precisely.}
+
+(The only possible downside of this last point is that if you are
+debugging two programs in parallel, which have some code in common,
+you might not want a common code breakpoint in one program to be set
+in the other program as well. But this feels like a small concern in
+comparison to the benefit of breakpoints persisting as just described.)
+
+
+@node Access to Guile Help and Completion
+@subsection Access to Guile Help and Completion
+
+The following keystrokes provide fast and convenient access to Guile's
+built in help, and to completion with respect to the set of defined and
+accessible symbols.
+
+@table @kbd
+@item C-h g
+@findex gds-help-symbol
+Get Guile help for a particular symbol, with the same results as if
+you had typed @code{(help SYMBOL)} into the Guile REPL
+(@code{gds-help-symbol}). The symbol to query defaults to the word at
+or before the cursor but can also be entered or edited in the
+minibuffer. The available help is popped up in a temporary Emacs
+window.
+
+@item C-h C-g
+@findex gds-apropos
+List all accessible Guile symbols matching a given regular expression,
+with the same results as if you had typed @code{(apropos REGEXP)} into
+the Guile REPL (@code{gds-apropos}). The regexp to query defaults to
+the word at or before the cursor but can also be entered or edited in
+the minibuffer. The list of matching symbols is popped up in a
+temporary Emacs window.
+
+@item M-@key{TAB}
+@findex gds-complete-symbol
+Try to complete the symbol at the cursor by matching it against the
+set of all defined and accessible bindings in the associated Guile
+process (@code{gds-complete-symbol}). If there are any extra
+characters that can be definitively added to the symbol at point, they
+are inserted. Otherwise, if there are any completions available, they
+are popped up in a temporary Emacs window, where one of them can be
+selected using either @kbd{@key{RET}} or the mouse.
+@end table
+
+
+@node Associating Buffers with Clients
+@subsection Associating Buffers with Clients
+
+The first time that you use one of GDS's evaluation, help or completion
+commands from a given Scheme mode buffer, GDS will ask which Guile
+client program you want to use for the operation, or if you want to
+start up a new ``utility'' client. After that GDS considers the buffer
+to be ``associated'' with the selected client, and so sends all further
+requests to that client, but you can override this by explicitly
+associating the buffer with a different client, or by removing the
+default association.
+
+@table @kbd
+@item M-x gds-associate-buffer
+Associate (or re-associate) the current buffer with a particular Guile
+client program. The available clients are listed, and you can also
+choose to start up a new ``utility'' client for this buffer to associate
+with.
+
+@item M-x gds-dissociate-buffer
+Dissociate the current buffer from its client, if any. This means that
+the next time you use an evaluation, help or completion command, GDS
+will ask you again which client to send the request to.
+@end table
+
+When a buffer is associated with a client program, the buffer's modeline
+shows whether the client is currently able to accept instruction from
+GDS. This is done by adding one of the following suffixes to the
+``Scheme'' major mode indicator:
+
+@table @asis
+@item :ready
+The client program (or one of its threads, if multithreaded) is
+currently ready to accept instruction from GDS. In other words, if you
+send it a help or evaluation request, you should see the result pretty
+much immediately.
+
+@item :running
+The client program is not currently able to accept instruction from
+GDS. This means that it (or all of its threads, if multithreaded) is
+busy, or waiting for input other than from GDS.
+
+@item :debug
+The client program (or one of its threads, if multithreaded) is stopped
+in ``debugging mode'' with GDS displaying the stack for a trap or
+exception. It is waiting for instruction from GDS on what to do next.
+@end table
+
+
+@node An Example GDS Session
+@subsection An Example GDS Session
+
+Create a file, @file{testgds.scm} say, for experimenting with GDS and
+Scheme code, and type this into it:
+
+@lisp
+(use-modules (ice-9 debugging traps)
+ (ice-9 gds-client)
+ (ice-9 debugging example-fns))
+(install-trap (make <procedure-trap>
+ #:behaviour gds-debug-trap
+ #:procedure fact1))
+@end lisp
+
+@noindent
+Now select all of this code and type @kbd{C-c C-r} to send the selected
+region to Guile for evaluation. GDS will ask you which Guile process to
+use; unless you know that you already have another Guile application
+running and connected to GDS, choose the ``Start a new Guile'' option,
+which starts one of the ``utility'' processes described in @ref{How To
+Use GDS}.
+
+The results of the evaluation pop up in a window like this:
+
+@lisp
+(use-modules (ice-9 debugging traps)\n @dots{}
+
+;;; Evaluating subexpression 1 in current module (guile-user)
+ @result{} no (or unspecified) value
+
+;;; Evaluating subexpression 2 in current module (guile-user)
+ @result{} no (or unspecified) value
+
+--:** *Guile Evaluation* (Scheme:ready)--All------------
+@end lisp
+
+@noindent
+this tells you that the evaluation was successful but that the return
+values were unspecified. Its effect was to load a module of example
+functions and set a trap on one of these functions, @code{fact1}, that
+calculates the factorial of its argument.
+
+If you now call @code{fact1}, you can see the trap and GDS's stack
+display in action. To do this add
+
+@lisp
+(fact1 4)
+@end lisp
+
+@noindent
+to your @file{testgds.scm} buffer and type @kbd{C-x C-e} (which
+evaluates the expression that the cursor is just after the end of). The
+result is:
+
+@lisp
+(fact1 4)
+
+;;; Evaluating in current module (guile-user)
+ @result{} 24
+
+--:** *Guile Evaluation* (Scheme:ready)--All------------
+@end lisp
+
+@noindent
+which is correct, but indicates that we forgot the step needed to enable
+the trap mechanism. To do this, type @kbd{C-c C-e} and then enter
+
+@lisp
+(trap-enable 'traps)
+@end lisp
+
+@noindent
+into the minibuffer. (You could equally have typed this into your test
+file and evaluated it from there; we use @kbd{C-c C-e} here to
+demonstrate the minibuffer option and because you typically wouldn't
+want to leave this kind of global setting in the source code that you
+are working on.)
+
+If you now type @kbd{C-x C-e} to evaluate @code{(fact1 4)} again, a GDS
+stack window like the following appears:
+
+@lisp
+Calling procedure:
+=> s [fact1 4]
+ s [primitive-eval (fact1 4)]
+
+
+--:** PID 28729 (Guile-Debug)--All------------
+@end lisp
+
+GDS's most compelling feature is its single-stepping. To get an
+immediate feel for what this is like, make sure your Emacs is prepared
+as described in @ref{GDS Setup}, then type the following code into an
+interactive Guile session.
+
+@lisp
+(fact1 4)
+@end lisp
+
+@noindent
+This will cause the GDS Guile-Debug window to pop up in Emacs, where
+you can then press @kbd{i} once and @kbd{@key{SPC}} repeatedly to
+single-step through the code from the point of the initial trap.
+
+(@kbd{i} is needed as the first keystroke rather than @kbd{@key{SPC}},
+because the aim here is to step through code in the @code{(ice-9
+debugging example-fns)} module, whose source file is
+@file{@dots{}/ice-9/debugging/example-fns.scm}, but the initial
+@code{(fact1 4)} call comes from the Guile session, whose ``source
+file'' Guile presents as @file{standard input}. If the user starts by
+pressing @kbd{@key{SPC}} instead of @kbd{i}, the effect is that the
+program runs until it hits the first recursive call @code{(fact1 (- n
+1))}, where it stops because of the trap on @code{fact1} firing again.
+At this point, the source file @emph{is}
+@file{@dots{}/ice-9/debugging/example-fns.scm}, because the recursive
+@code{(fact1 (- n 1))} call comes from code in that file, so further
+pressing of @kbd{@key{SPC}} successfully single-steps through this
+file.)
+
+
+@node GDS Architecture
+@subsection GDS Architecture
+
+Ths following information may be of interest to readers who would like
+to know how GDS works. Please note that understanding the details of
+this subsection is completely optional so far as just using GDS is
+concerned!
+
+GDS consists of three components.
+
+@itemize
+@item
+The GDS @dfn{interface} code is written in Emacs Lisp and runs inside
+Emacs. This code, consisting of the installed files @file{gds.el} and
+@file{gds-server.el}, is responsible for displaying information from
+Guile in Emacs windows, and for responding to Emacs commands and
+keystrokes by sending instructions back to the Guile program being
+debugged.
+
+@item
+The GDS @dfn{server} code is written in Scheme and runs as an Emacs
+inferior process. It acts as a multiplexer between the (possibly
+multiple) Guile programs being debugged and the interface code running
+in Emacs. The server code is the installed file
+@file{gds-server.scm}.
+
+@item
+The GDS @dfn{client} code is written in Scheme (installed file
+@file{gds-client.scm}), and is loaded as a module by each Guile
+program that wants to use GDS for debugging. When a trap occurs whose
+behaviour is @code{gds-debug-trap}, it feeds information about the
+trap context through the server to Emacs, then waits for instruction
+back from the Emacs interface on what to do next.
+@end itemize
+
+@noindent
+Summarized in glorious ASCII art, this looks as follows.
+
+@example
++------------+
+| Program #1 |
+| |
+| +--------+ |
+| | Client |-_
+| +--------+ |-_ +---------------+
++------------+ -_TCP | Emacs |
+ -_ | |
+ -_+--------+ | +-----------+ |
+ _| Server |-----| Interface | |
++------------+ _- +--------+ | +-----------+ |
+| Program #2 | _- +---------------+
+| | _- TCP
+| +--------+ _-
+| | Client |-|
+| +--------+ |
++------------+
+@end example
+
+@noindent
+@cindex TCP, use of
+The communication between the client and server components is over a
+TCP connection, which has two implications. Firstly, that GDS is
+independent of whatever other interfaces the programs being debugged
+have, whether graphical or through standard input and output.
+Secondly, that the server and Emacs interface can be on a different
+computer from the programs being debugged (only theoretically, though,
+because GDS doesn't yet provide an interface to connect to any server
+other than the default, on localhost at TCP port 8333). The data
+exchanged between client and server components, and between server and
+interface components, is in the form of sexps that are organized so as
+to be directly readable by both Scheme and Emacs Lisp.
+
+
+@subsubsection Security Note
+
+@cindex Security
+GDS currently has no authentication between its client and server
+components, so in an untrusted environment the use of TCP probably
+raises important security issues. If you are thinking of using GDS in
+such an environment, please consider any such issues carefully before
+proceeding!
+
+
@c Local Variables:
@c TeX-master: "guile.texi"
@c End: