mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-08 22:50:27 +02:00
Removing material about breakpoint-related features that aren't
actually present in the 1.8.x series... * api-debug.texi (Breakpoints): Removed. * scheme-debugging.texi (Debugging Features): Breakpoint-related text removed. (Intro to Breakpoints, Breakpoints Overview, Source Breakpoints, Procedural Breakpoints, Setting Breakpoints, break! trace! trace-subtree!, Accessing Breakpoints, Breakpoint Behaviours, Enabling and Disabling, Deleting Breakpoints, Breakpoint Information, Other Breakpoint Types, Single Stepping, Run To Frame Exit, Continue Execution, New Tracing, Tracing Compared): Removed. (Old Tracing): Text moved to parent Tracing node. (Tracing): Removed introductory statement about two tracing implementations. (Display Backtrace): Remove ref to Backtrace Format node. (Backtrace Format): Removed (as it was empty). (Interactive Debugger, Frame Selection, Frame Information, Frame Evaluation): Merge textual improvements from CVS HEAD. (Leave Debugger): Removed. (Interactive Debugger): Document quit command here, as in CVS HEAD.
This commit is contained in:
parent
953204a37e
commit
2b4c5ec18a
3 changed files with 58 additions and 799 deletions
|
@ -1,3 +1,29 @@
|
|||
2007-10-23 Neil Jerram <neil@ossau.uklinux.net>
|
||||
|
||||
Removing material about breakpoint-related features that aren't
|
||||
actually present in the 1.8.x series...
|
||||
|
||||
* api-debug.texi (Breakpoints): Removed.
|
||||
|
||||
* scheme-debugging.texi (Debugging Features): Breakpoint-related
|
||||
text removed.
|
||||
(Intro to Breakpoints, Breakpoints Overview, Source Breakpoints,
|
||||
Procedural Breakpoints, Setting Breakpoints, break! trace!
|
||||
trace-subtree!, Accessing Breakpoints, Breakpoint Behaviours,
|
||||
Enabling and Disabling, Deleting Breakpoints, Breakpoint
|
||||
Information, Other Breakpoint Types, Single Stepping, Run To Frame
|
||||
Exit, Continue Execution, New Tracing, Tracing Compared): Removed.
|
||||
(Old Tracing): Text moved to parent Tracing node.
|
||||
(Tracing): Removed introductory statement about two tracing
|
||||
implementations.
|
||||
(Display Backtrace): Remove ref to Backtrace Format node.
|
||||
(Backtrace Format): Removed (as it was empty).
|
||||
(Interactive Debugger, Frame Selection, Frame Information, Frame
|
||||
Evaluation): Merge textual improvements from CVS HEAD.
|
||||
(Leave Debugger): Removed.
|
||||
(Interactive Debugger): Document quit command here, as in CVS
|
||||
HEAD.
|
||||
|
||||
2007-10-02 Ludovic Courtès <ludo@gnu.org>
|
||||
|
||||
* slib.texi (SLIB installation): Don't recommend using the site
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
|
||||
@menu
|
||||
* Interactive Debugging:: Functions intended for interactive use.
|
||||
* Breakpoints::
|
||||
* Source Properties:: Remembering the source of an expression.
|
||||
* Using Traps::
|
||||
* Capturing the Stack or Innermost Stack Frame::
|
||||
|
@ -36,86 +35,6 @@ the backtrace.
|
|||
Invoke the Guile debugger to explore the context of the last error.
|
||||
@end deffn
|
||||
|
||||
@node Breakpoints
|
||||
@subsection Breakpoints
|
||||
|
||||
@deffn {Generic Function} set-breakpoint! behaviour . location-args
|
||||
Set a breakpoint with behaviour @var{behaviour} at the location
|
||||
specified by @var{location-args}.
|
||||
|
||||
The form of the @var{location-args} depends upon what methods for
|
||||
@code{set-breakpoint!} have been provided by the implementations of
|
||||
subclasses of the @code{<breakpoint>} base class.
|
||||
@end deffn
|
||||
|
||||
@deffn {Generic Function} get-breakpoint . location-args
|
||||
Find and return the breakpoint instance at the location specified by
|
||||
@var{location-args}.
|
||||
|
||||
The form of the @var{location-args} depends upon what methods for
|
||||
@code{get-breakpoint} have been provided by the implementations of
|
||||
subclasses of the @code{<breakpoint>} base class.
|
||||
@end deffn
|
||||
|
||||
@deffn {Method} set-breakpoint! behaviour (proc <procedure>)
|
||||
Set a breakpoint with behaviour @var{behaviour} before applications of
|
||||
the procedure @var{proc}.
|
||||
@end deffn
|
||||
|
||||
@deffn {Method} set-breakpoint! behaviour x-as-read (x-pairified <pair>)
|
||||
Set a breakpoint with behaviour @var{behaviour} on the source expression
|
||||
@var{x-pairified}, storing @var{x-as-read} for use in messages
|
||||
describing the breakpoint.
|
||||
@end deffn
|
||||
|
||||
@deffn {Method} set-breakpoint! behaviour (number <integer>)
|
||||
Change the behaviour of existing breakpoint number @var{number} to
|
||||
@var{behaviour}.
|
||||
@end deffn
|
||||
|
||||
@deffn {Accessor} bp-behaviour breakpoint
|
||||
Get or set the behaviour of the breakpoint instance @var{breakpoint}.
|
||||
@end deffn
|
||||
|
||||
@deffn {Accessor} bp-enabled? breakpoint
|
||||
Get or set the enabled state of the specified @var{breakpoint}.
|
||||
@end deffn
|
||||
|
||||
@deffn {Procedure} enable-breakpoint! . location-args
|
||||
@deffnx {Procedure} disable-breakpoint! . location-args
|
||||
Enable or disable the breakpoint at the location specified by
|
||||
@var{location-args}.
|
||||
@end deffn
|
||||
|
||||
@deffn {Generic Function} bp-delete! breakpoint
|
||||
Delete breakpoint @var{breakpoint}. This means (1) doing whatever is
|
||||
needed to prevent the breakpoint from triggering again, and (2) removing
|
||||
it from the global list of current breakpoints.
|
||||
@end deffn
|
||||
|
||||
@deffn {Procedure} delete-breakpoint! . location-args
|
||||
Delete the breakpoint at the location specified by @var{location-args}.
|
||||
@end deffn
|
||||
|
||||
@deffn {Generic Function} bp-describe breakpoint port
|
||||
Print a description of @var{breakpoint} to the specified @var{port}.
|
||||
@var{port} can be @code{#t} for standard output, or else any output
|
||||
port.
|
||||
@end deffn
|
||||
|
||||
@deffn {Procedure} describe-breakpoint . location-args
|
||||
Print (to standard output) a description of the breakpoint at location
|
||||
specified by @var{location-args}.
|
||||
@end deffn
|
||||
|
||||
@deffn {Procedure} all-breakpoints
|
||||
Return a list of all current breakpoints, ordered by breakpoint number.
|
||||
@end deffn
|
||||
|
||||
@deffn {Procedure} describe-all-breakpoints
|
||||
Print a description of all current breakpoints to standard output.
|
||||
@end deffn
|
||||
|
||||
|
||||
@node Source Properties
|
||||
@subsection Source Properties
|
||||
|
|
|
@ -12,24 +12,8 @@ Guile includes debugging tools to help you work out what is going wrong
|
|||
when a program signals an error or behaves differently to how you would
|
||||
expect. This chapter describes how to use these tools.
|
||||
|
||||
Broadly speaking, Guile's debugging support allows you to do two things:
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
specify @dfn{breakpoints} --- points in the execution of a program where
|
||||
execution should pause so you can see what is going on
|
||||
|
||||
@item
|
||||
examine in detail the ``scene of the crime'' --- in other words, the
|
||||
execution context at a breakpoint, or when the last error occurred.
|
||||
@end itemize
|
||||
|
||||
@noindent
|
||||
The details are more complex and more powerful @dots{}
|
||||
|
||||
@menu
|
||||
* Debug Last Error:: Debugging the most recent error.
|
||||
* Intro to Breakpoints:: Setting and manipulating them.
|
||||
* Interactive Debugger:: Using the interactive debugger.
|
||||
* Tracing:: Tracing program execution.
|
||||
@end menu
|
||||
|
@ -105,504 +89,6 @@ frame (the @code{evaluate} command --- see @ref{Frame Evaluation}).
|
|||
Use of the interactive debugger, including these commands, is described
|
||||
in @ref{Interactive Debugger}.
|
||||
|
||||
@menu
|
||||
* Backtrace Format:: How to interpret a backtrace.
|
||||
@end menu
|
||||
|
||||
|
||||
@node Backtrace Format
|
||||
@subsubsection How to Interpret a Backtrace
|
||||
|
||||
|
||||
@node Intro to Breakpoints
|
||||
@subsection Intro to Breakpoints
|
||||
|
||||
If you are not already familiar with the concept of breakpoints, the
|
||||
first subsection below explains how they work are why they are useful.
|
||||
|
||||
Broadly speaking, Guile's breakpoint support consists of
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
type-specific features for @emph{creating} breakpoints of various types
|
||||
|
||||
@item
|
||||
relatively generic features for @emph{manipulating} the behaviour of
|
||||
breakpoints once they've been created.
|
||||
@end itemize
|
||||
|
||||
Different breakpoint types are implemented as different classes in a
|
||||
GOOPS hierarchy with common base class @code{<breakpoint>}. The magic
|
||||
of generic functions then allows most of the manipulation functions to
|
||||
be generic by default but specializable (by breakpoint class) if the
|
||||
need arises.
|
||||
|
||||
Generic breakpoint support is provided by the @code{(ice-9 debugger
|
||||
breakpoints)} module, so you will almost always need to use this module
|
||||
in order to access the functionality described here:
|
||||
|
||||
@smalllisp
|
||||
(use-modules (ice-9 debugger breakpoints))
|
||||
@end smalllisp
|
||||
|
||||
@noindent
|
||||
You may like to add this to your @file{.guile} file.
|
||||
|
||||
@menu
|
||||
* Breakpoints Overview::
|
||||
* Source Breakpoints::
|
||||
* Procedural Breakpoints::
|
||||
* Setting Breakpoints::
|
||||
* break! trace! trace-subtree!::
|
||||
* Accessing Breakpoints::
|
||||
* Breakpoint Behaviours::
|
||||
* Enabling and Disabling::
|
||||
* Deleting Breakpoints::
|
||||
* Breakpoint Information::
|
||||
* Other Breakpoint Types::
|
||||
@end menu
|
||||
|
||||
|
||||
@node Breakpoints Overview
|
||||
@subsubsection How Breakpoints Work and Why They Are Useful
|
||||
|
||||
Often, debugging the last error is not enough to tell you what went
|
||||
wrong. For example, the root cause of the error may have arisen a long
|
||||
time before the error was signalled, in which case the execution context
|
||||
of the error is too late to be useful. Or your program might not signal
|
||||
an error at all, just return an unexpected result or have some incorrect
|
||||
side effect.
|
||||
|
||||
In many such cases, it's useful to pause the program at or before the
|
||||
point where you suspect the problem arises. Then you can explore the
|
||||
stack, display the values of key variables, and generally check that the
|
||||
state of the program is as you expect. If all is well, you can let the
|
||||
program continue running normally, or step more slowly through each
|
||||
expression that the Scheme interpreter evaluates. Single-stepping may
|
||||
reveal that the program is going through blocks of code that you didn't
|
||||
intend --- a useful data point for understanding what the underlying
|
||||
problem is.
|
||||
|
||||
Telling Guile where or when to pause a program is called @dfn{setting a
|
||||
breakpoint}. When a breakpoint is hit, Guile's default behaviour is to
|
||||
enter the interactive debugger, where there are now two sets of commands
|
||||
available:
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
all the commands as described for last error debugging (@pxref{Debug
|
||||
Last Error}), which allow you to explore the stack and so on
|
||||
|
||||
@item
|
||||
additional commands for continuing program execution in various ways:
|
||||
@code{next}, @code{step}, @code{finish}, @code{trace-finish} and
|
||||
@code{continue}.
|
||||
@end itemize
|
||||
|
||||
Use of the interactive debugger is described in @ref{Interactive
|
||||
Debugger}.
|
||||
|
||||
|
||||
@node Source Breakpoints
|
||||
@subsubsection Source Breakpoints
|
||||
|
||||
A source breakpoint is a breakpoint that triggers whenever program
|
||||
execution hits a particular source location. A source breakpoint can be
|
||||
conveniently set simply by evaluating code that has @code{##} inserted
|
||||
into it at the position where you want the breakpoint to be.
|
||||
|
||||
For example, to set a breakpoint immediately before evaluation of
|
||||
@code{(= n 0)} in the following procedure definition, evaluate:
|
||||
|
||||
@smalllisp
|
||||
(define (fact1 n)
|
||||
(if ##(= n 0)
|
||||
1
|
||||
(* n (fact1 (- n 1)))))
|
||||
@print{}
|
||||
Set breakpoint 1: standard input:4:9: (= n 0)
|
||||
@end smalllisp
|
||||
|
||||
@noindent
|
||||
Note the message confirming that you have set a breakpoint. If you
|
||||
don't see this, something isn't working.
|
||||
|
||||
@code{##} is provided by the @code{(ice-9 debugger breakpoints source)} module,
|
||||
so you must use this module before trying to set breakpoints in this
|
||||
way:
|
||||
|
||||
@smalllisp
|
||||
(use-modules (ice-9 debugger breakpoints source))
|
||||
@end smalllisp
|
||||
|
||||
@noindent
|
||||
You may like to add this to your @file{.guile} file.
|
||||
|
||||
The default behaviour for source breakpoints is @code{debug-here}
|
||||
(@pxref{Breakpoint Behaviours}), which means to enter the command line
|
||||
debugger when the breakpoint is hit. So, if you now use @code{fact1},
|
||||
that is what happens.
|
||||
|
||||
@smalllisp
|
||||
guile> (fact1 3)
|
||||
Hit breakpoint 1: standard input:4:9: (= n 0)
|
||||
Frame 3 at standard input:4:9
|
||||
(= n 0)
|
||||
debug>
|
||||
@end smalllisp
|
||||
|
||||
|
||||
@node Procedural Breakpoints
|
||||
@subsubsection Procedural Breakpoints
|
||||
|
||||
A procedural breakpoint is a breakpoint that triggers whenever Guile is
|
||||
about to apply a specified procedure to its (already evaluated)
|
||||
arguments. To set a procedural breakpoint, call @code{break!} with the
|
||||
target procedure as a single argument. For example:
|
||||
|
||||
@smalllisp
|
||||
(define (fact1 n)
|
||||
(if (= n 0)
|
||||
1
|
||||
(* n (fact1 (- n 1)))))
|
||||
|
||||
(break! fact1)
|
||||
@print{}
|
||||
Set breakpoint 1: [fact1]
|
||||
@result{}
|
||||
#<<procedure-breakpoint> 808b0b0>
|
||||
@end smalllisp
|
||||
|
||||
Alternatives to @code{break!} are @code{trace!} and
|
||||
@code{trace-subtree!}. The difference is that these three calls create
|
||||
a breakpoint in the same place but with three different behaviours,
|
||||
respectively @code{debug-here}, @code{trace-here} and
|
||||
@code{trace-subtree}. Breakpoint behaviours are documented fully later
|
||||
(@pxref{Breakpoint Behaviours}), but to give a quick taste, here's an
|
||||
example of running code that includes a procedural breakpoint with the
|
||||
@code{trace-here} behaviour.
|
||||
|
||||
@smalllisp
|
||||
(trace! fact1)
|
||||
@print{}
|
||||
Set breakpoint 1: [fact1]
|
||||
@result{}
|
||||
#<<procedure-breakpoint> 808b0b0>
|
||||
|
||||
(fact1 4)
|
||||
@print{}
|
||||
| [fact1 4]
|
||||
| | [fact1 3]
|
||||
| | | [fact1 2]
|
||||
| | | | [fact1 1]
|
||||
| | | | | [fact1 0]
|
||||
| | | | | 1
|
||||
| | | | 2
|
||||
| | | 6
|
||||
| | 24
|
||||
| 24
|
||||
@result{}
|
||||
24
|
||||
@end smalllisp
|
||||
|
||||
To set and use procedural breakpoints, you will need to use the
|
||||
@code{(ice-9 debugger breakpoints procedural)} module:
|
||||
|
||||
@smalllisp
|
||||
(use-modules (ice-9 debugger breakpoints procedural))
|
||||
@end smalllisp
|
||||
|
||||
@noindent
|
||||
You may like to add this to your @file{.guile} file.
|
||||
|
||||
|
||||
@node Setting Breakpoints
|
||||
@subsubsection Setting Breakpoints
|
||||
|
||||
In general, that is. We've already seen how to set source and
|
||||
procedural breakpoints conveniently in practice. This section explains
|
||||
how those conveniences map onto a more general mechanism.
|
||||
|
||||
The general mechanism for setting breakpoints is the generic function
|
||||
@code{set-breakpoint!}. Different kinds of breakpoints define
|
||||
subclasses of the class @code{<breakpoint>} and provide their own
|
||||
methods for @code{set-pbreakpoint!}.
|
||||
|
||||
For example, @code{(ice-9 debugger breakpoints procedural)} implements
|
||||
the @code{<procedure-breakpoint>} subclass and provides a
|
||||
@code{set-breakpoint!} method that takes a procedure argument:
|
||||
|
||||
@smalllisp
|
||||
(set-breakpoint! @var{behavior} fact1)
|
||||
@print{}
|
||||
Set breakpoint 1: [fact1]
|
||||
@result{}
|
||||
#<<procedure-breakpoint> 808b0b0>
|
||||
@end smalllisp
|
||||
|
||||
A non-type-specific @code{set-breakpoint!} method is provided by the
|
||||
generic module @code{(ice-9 debugger breakpoints)}. It allows you to
|
||||
change the behaviour of an existing breakpoint that is identified by
|
||||
its breakpoint number.
|
||||
|
||||
@smalllisp
|
||||
(set-breakpoint! @var{behavior} 1)
|
||||
@end smalllisp
|
||||
|
||||
@node break! trace! trace-subtree!
|
||||
@subsubsection break! trace! trace-subtree!
|
||||
|
||||
We have already talked above about the use of @code{break!},
|
||||
@code{trace!} and @code{trace-subtree!} for setting procedural
|
||||
breakpoints. Now that @code{set-breakpoint!} has been introduced, we
|
||||
can reveal that @code{break!}, @code{trace!} and @code{trace-subtree!}
|
||||
are in fact just wrappers for @code{set-breakpoint!} that specify
|
||||
particular breakpoint behaviours, respectively @code{debug-here},
|
||||
@code{trace-here} and @code{trace-subtree}.
|
||||
|
||||
@smalllisp
|
||||
(break! . @var{args})
|
||||
@equiv{} (set-breakpoint! debug-here . @var{args})
|
||||
(trace! . @var{args})
|
||||
@equiv{} (set-breakpoint! trace-here . @var{args})
|
||||
(trace-subtree! . @var{args})
|
||||
@equiv{} (set-breakpoint! trace-subtree . @var{args})
|
||||
@end smalllisp
|
||||
|
||||
This means that these three procedures can be used to set the
|
||||
corresponding behaviours for any type of breakpoint for which a
|
||||
@code{set-breakpoint!} method exists, not just procedural ones.
|
||||
|
||||
|
||||
@node Accessing Breakpoints
|
||||
@subsubsection Accessing Breakpoints
|
||||
|
||||
Information about the state and behaviour of a breakpoint is stored in
|
||||
an instance of the appropriate breakpoint class. To access and change
|
||||
that information, therefore, you need to get hold of the desired
|
||||
breakpoint instance.
|
||||
|
||||
The generic function @code{get-breakpoint} meets this need: For every
|
||||
@code{set-breakpoint!} method there is a corresponding
|
||||
@code{get-breakpoint} method. Note especially the useful
|
||||
type-independent case:
|
||||
|
||||
@smalllisp
|
||||
(get-breakpoint 1)
|
||||
@result{}
|
||||
#<<procedure-breakpoint> 808b0b0>
|
||||
@end smalllisp
|
||||
|
||||
|
||||
@node Breakpoint Behaviours
|
||||
@subsubsection Breakpoint Behaviours
|
||||
|
||||
A breakpoint's @dfn{behaviour} determines what happens when that
|
||||
breakpoint is hit. Several kinds of behaviour are generally useful.
|
||||
|
||||
@table @code
|
||||
@item debug-here
|
||||
Enter the command line debugger. This gives the opportunity to explore
|
||||
the stack, evaluate expressions in any of the pending stack frames,
|
||||
change breakpoint properties or set new breakpoints, and continue
|
||||
program execution when you are done.
|
||||
|
||||
@item trace-here
|
||||
Trace the current stack frame. For expressions being evaluated, this
|
||||
shows the expression. For procedure applications, it shows the
|
||||
procedure name and its arguments @emph{post-evaluation}. For both
|
||||
expressions and applications, the indentation of the tracing indicates
|
||||
whether the traced items are mutually tail recursive.
|
||||
|
||||
@item trace-subtree
|
||||
Trace the current stack frame, and enable tracing for all future
|
||||
evaluations and applications until the current stack frame is exited.
|
||||
@code{trace-subtree} is a great preliminary exploration tool when all
|
||||
you know is that there is a bug ``somewhere in XXX or in something that
|
||||
XXX calls''.
|
||||
|
||||
@item (at-exit @var{thunk})
|
||||
Don't do anything now, but arrange for @var{thunk} to be executed when
|
||||
the current stack frame is exited. For example, the operation that most
|
||||
debugging tools call ``finish'' is @code{(at-exit debug-here)}.
|
||||
|
||||
@item (at-next @var{count} @var{thunk})
|
||||
@dots{} arrange for @var{thunk} to be executed when beginning the
|
||||
@var{count}th next evaluation or application with source location in the
|
||||
current file.
|
||||
|
||||
@item (at-entry @var{count} @var{thunk})
|
||||
@dots{} arrange for @var{thunk} to be executed when beginning the
|
||||
@var{count}th next evaluation (regardless of source location).
|
||||
|
||||
@item (at-apply @var{count} @var{thunk})
|
||||
@dots{} arrange for @var{thunk} to be executed just before performing
|
||||
the @var{count}th next application (regardless of source location).
|
||||
|
||||
@item (at-step @var{count} @var{thunk})
|
||||
Synthesis of @code{at-entry} and @code{at-apply}; counts both
|
||||
evaluations and applications.
|
||||
@end table
|
||||
|
||||
Every breakpoint instance has a slot in which its behaviour is stored.
|
||||
If you have a breakpoint instance in hand, you can change its behaviour
|
||||
using the @code{bp-behaviour} accessor.
|
||||
|
||||
An @dfn{accessor} supports the setting of a property like this:
|
||||
|
||||
@smalllisp
|
||||
(set! (bp-behaviour @var{breakpoint}) @var{new-behaviour})
|
||||
@end smalllisp
|
||||
|
||||
@noindent
|
||||
See the GOOPS manual for further information on accessors.
|
||||
|
||||
Alternatively, if you know how to specify the @var{location-args} for
|
||||
the breakpoint in question, you can change its behaviour using
|
||||
@code{set-breakpoint!}. For example:
|
||||
|
||||
@smalllisp
|
||||
;; Change behaviour of breakpoint number 2.
|
||||
(set-breakpoint! @var{new-behaviour} 2)
|
||||
|
||||
;; Change behaviour of procedural breakpoint on [fact1].
|
||||
(set-breakpoint! @var{new-behaviour} fact1)
|
||||
@end smalllisp
|
||||
|
||||
In all cases, the behaviour that you specify should be either a single
|
||||
thunk, or a list of thunks, to be called when the breakpoint is hit.
|
||||
|
||||
The most common behaviours above are exported as thunks from the
|
||||
@code{(ice-9 debugger behaviour)} module. So, if you use this module, you can
|
||||
use those behaviours directly like this:
|
||||
|
||||
@smalllisp
|
||||
(use-modules (ice-9 debugger behaviour))
|
||||
(set-breakpoint! trace-subtree 2)
|
||||
(set! (bp-behaviour (get-breakpoint 3)) debug-here)
|
||||
@end smalllisp
|
||||
|
||||
@noindent
|
||||
You can also use the list option to combine common behaviours:
|
||||
|
||||
@smalllisp
|
||||
(set-breakpoint! (list trace-here debug-here) 2)
|
||||
@end smalllisp
|
||||
|
||||
@noindent
|
||||
Or, for more customized behaviour, you could build and use your own
|
||||
thunk like this:
|
||||
|
||||
@smalllisp
|
||||
(define (my-behaviour)
|
||||
(trace-here)
|
||||
(at-exit (lambda ()
|
||||
(display "Exiting frame of my-behaviour bp\n")
|
||||
... do something unusual ...)))
|
||||
|
||||
(set-breakpoint my-behaviour 2)
|
||||
@end smalllisp
|
||||
|
||||
|
||||
@node Enabling and Disabling
|
||||
@subsubsection Enabling and Disabling
|
||||
|
||||
Independently of its behaviour, each breakpoint also keeps track of
|
||||
whether it is currently enabled. This is a straightforward convenience
|
||||
to allow breakpoints to be temporarily switched off without losing all
|
||||
their carefully constructed properties.
|
||||
|
||||
If you have a breakpoint instance in hand, you can enable or disable it
|
||||
using the @code{bp-enabled?} accessor.
|
||||
|
||||
Alternatively, you can enable or disable a breakpoint via its location
|
||||
args by using @code{enable-breakpoint!} or @code{disable-breakpoint!}.
|
||||
|
||||
@smalllisp
|
||||
(disable-breakpoint! fact1) ; disable the procedural breakpoint on fact1
|
||||
(enable-breakpoint! 1) ; enable breakpoint 1
|
||||
@end smalllisp
|
||||
|
||||
@code{enable-breakpoint!} and @code{disable-breakpoint!} are implemented
|
||||
using @code{get-breakpoint} and @code{bp-enabled?}, so any
|
||||
@var{location-args} that are valid for @code{get-breakpoint} will work
|
||||
also for these procedures.
|
||||
|
||||
|
||||
@node Deleting Breakpoints
|
||||
@subsubsection Deleting Breakpoints
|
||||
|
||||
Given a breakpoint instance in hand, you can deactivate it and remove
|
||||
it from the global list of current breakpoints by calling
|
||||
@code{bp-delete!}.
|
||||
|
||||
Alternatively, you can delete a breakpoint by its location args:
|
||||
|
||||
@smalllisp
|
||||
(delete-breakpoint! 1) ; delete breakpoint 1
|
||||
@end smalllisp
|
||||
|
||||
@code{delete-breakpoint!} is implemented using @code{get-breakpoint} and
|
||||
@code{bp-delete!}, so any @var{location-args} that are valid for
|
||||
@code{get-breakpoint} will work also for @code{delete-breakpoint!}.
|
||||
|
||||
There is no way to reinstate a deleted breakpoint. Final destruction of
|
||||
the breakpoint instance is determined by the usual garbage collection
|
||||
rules.
|
||||
|
||||
|
||||
@node Breakpoint Information
|
||||
@subsubsection Breakpoint Information
|
||||
|
||||
To get Guile to print a description of a breakpoint instance, use
|
||||
@code{bp-describe}:
|
||||
|
||||
@smalllisp
|
||||
(bp-describe (get-breakpoint 1) #t) ; #t specifies standard output
|
||||
@print{}
|
||||
Breakpoint 1: [fact1]
|
||||
enabled? = #t
|
||||
behaviour = #<procedure trace-here ()>
|
||||
@end smalllisp
|
||||
|
||||
Following the usual model, @code{describe-breakpoint} is also provided:
|
||||
|
||||
@smalllisp
|
||||
(describe-breakpoint 1)
|
||||
@print{}
|
||||
Breakpoint 1: [fact1]
|
||||
enabled? = #t
|
||||
behaviour = #<procedure trace-here ()>
|
||||
@end smalllisp
|
||||
|
||||
Finally, two stragglers. @code{all-breakpoints} returns a list of all
|
||||
current breakpoints. @code{describe-all-breakpoints} combines
|
||||
@code{bp-describe} and @code{all-breakpoints} by printing a description
|
||||
of all current breakpoints to standard output.
|
||||
|
||||
@node Other Breakpoint Types
|
||||
@subsubsection Other Breakpoint Types
|
||||
|
||||
Besides source and procedural breakpoints, Guile includes an early
|
||||
implementation of a third class of breakpoints: @dfn{range} breakpoints.
|
||||
These are breakpoints that trigger when program execution enters (or
|
||||
perhaps exits) a defined range of source locations.
|
||||
|
||||
Sadly, these don't yet work well. The apparent problem is that the
|
||||
extra methods for @code{set-breakpoint!} and @code{get-breakpoint} cause
|
||||
some kind of explosion in the time taken by GOOPS to construct its
|
||||
method cache and to dispatch calls involving these generic functions.
|
||||
But we haven't really investigated enough to be sure that this is the
|
||||
real issue.
|
||||
|
||||
If you're interested in looking and/or investigating anyway, please feel
|
||||
free to check out and play with the @code{(ice-9 debugger breakpoints
|
||||
range)} module.
|
||||
|
||||
The other kind of breakpoint that we'd like to have is watchpoints, but
|
||||
this hasn't been implemented at all yet. Watchpoints may turn out to be
|
||||
impractical for performance reasons.
|
||||
|
||||
|
||||
@node Interactive Debugger
|
||||
@subsection Using the Interactive Debugger
|
||||
|
@ -625,19 +111,21 @@ debug>
|
|||
@end lisp
|
||||
|
||||
@noindent
|
||||
``debug>'' is the debugger's prompt, and a useful reminder that you are
|
||||
not in the normal Guile REPL. The available commands are described in
|
||||
detail in the following subsections.
|
||||
``debug>'' is the debugger's prompt, and a reminder that you are not
|
||||
in the normal Guile REPL. In case you find yourself in the debugger by
|
||||
mistake, the @code{quit} command will return you to the REPL.
|
||||
|
||||
@deffn {Debugger Command} quit
|
||||
Exit the debugger.
|
||||
@end deffn
|
||||
|
||||
The other available commands are described in the following subsections.
|
||||
|
||||
@menu
|
||||
* Display Backtrace:: backtrace.
|
||||
* Frame Selection:: up, down, frame.
|
||||
* Frame Information:: info args, info frame, position.
|
||||
* Frame Evaluation:: evaluate.
|
||||
* Single Stepping:: step, next.
|
||||
* Run To Frame Exit:: finish, trace-finish.
|
||||
* Continue Execution:: continue.
|
||||
* Leave Debugger:: quit.
|
||||
@end menu
|
||||
|
||||
|
||||
|
@ -666,7 +154,7 @@ option @code{depth} determines the maximum number of frames printed.
|
|||
@end deffn
|
||||
|
||||
The format of the displayed backtrace is the same as for the
|
||||
@code{backtrace} procedure --- see @ref{Backtrace Format} for details.
|
||||
@code{backtrace} procedure.
|
||||
|
||||
|
||||
@node Frame Selection
|
||||
|
@ -701,13 +189,13 @@ Frame 1 at standard input:36:14
|
|||
|
||||
@deffn {Debugger Command} up [n]
|
||||
Move @var{n} frames up the stack. For positive @var{n}, this
|
||||
advances toward the outermost frame, to higher frame numbers, to
|
||||
advances toward the outermost frame, to lower frame numbers, to
|
||||
frames that have existed longer. @var{n} defaults to one.
|
||||
@end deffn
|
||||
|
||||
@deffn {Debugger Command} down [n]
|
||||
Move @var{n} frames down the stack. For positive @var{n}, this
|
||||
advances toward the innermost frame, to lower frame numbers, to frames
|
||||
advances toward the innermost frame, to higher frame numbers, to frames
|
||||
that were created more recently. @var{n} defaults to one.
|
||||
@end deffn
|
||||
|
||||
|
@ -721,100 +209,48 @@ frame to select; it must be a stack-frame number.
|
|||
@node Frame Information
|
||||
@subsubsection Frame Information
|
||||
|
||||
[to be completed]
|
||||
The following commands return detailed information about the currently
|
||||
selected frame.
|
||||
|
||||
@deffn {Debugger Command} {info frame}
|
||||
All about selected stack frame.
|
||||
Display a verbose description of the selected frame. The information
|
||||
that this command provides is equivalent to what can be deduced from the
|
||||
one line summary for the frame that appears in a backtrace, but is
|
||||
presented and explained more clearly.
|
||||
@end deffn
|
||||
|
||||
@deffn {Debugger Command} {info args}
|
||||
Argument variables of current stack frame.
|
||||
Display the argument variables of the current stack frame. Arguments
|
||||
can also be seen in the backtrace, but are presented more clearly by
|
||||
this command.
|
||||
@end deffn
|
||||
|
||||
@deffn {Debugger Command} position
|
||||
Display the position of the current expression.
|
||||
Display the name of the source file that the current expression comes
|
||||
from, and the line and column number of the expression's opening
|
||||
parenthesis within that file. This information is only available when
|
||||
the @code{positions} read option is enabled (@pxref{Reader options}).
|
||||
@end deffn
|
||||
|
||||
|
||||
@node Frame Evaluation
|
||||
@subsubsection Frame Evaluation
|
||||
|
||||
[to be completed]
|
||||
The @code{evaluate} command is most useful for querying the value of a
|
||||
variable, either global or local, in the environment of the selected
|
||||
stack frame, but it can be used more generally to evaluate any
|
||||
expression.
|
||||
|
||||
@deffn {Debugger Command} evaluate expression
|
||||
Evaluate an expression.
|
||||
The expression must appear on the same line as the command,
|
||||
however it may be continued over multiple lines.
|
||||
@end deffn
|
||||
|
||||
|
||||
@node Single Stepping
|
||||
@subsubsection Single Stepping
|
||||
|
||||
[to be completed]
|
||||
|
||||
@deffn {Debugger Command} step [n]
|
||||
Continue until entry to @var{n}th next frame.
|
||||
@end deffn
|
||||
|
||||
@deffn {Debugger Command} next [n]
|
||||
Continue until entry to @var{n}th next frame in same file.
|
||||
@end deffn
|
||||
|
||||
|
||||
@node Run To Frame Exit
|
||||
@subsubsection Run To Frame Exit
|
||||
|
||||
[to be completed]
|
||||
|
||||
@deffn {Debugger Command} finish
|
||||
Continue until evaluation of the current frame is complete, and
|
||||
print the result obtained.
|
||||
@end deffn
|
||||
|
||||
@deffn {Debugger Command} trace-finish
|
||||
Trace until evaluation of the current frame is complete.
|
||||
@end deffn
|
||||
|
||||
|
||||
@node Continue Execution
|
||||
@subsubsection Continue Execution
|
||||
|
||||
[to be completed]
|
||||
|
||||
@deffn {Debugger Command} continue
|
||||
Continue program execution.
|
||||
@end deffn
|
||||
|
||||
|
||||
@node Leave Debugger
|
||||
@subsubsection Leave Debugger
|
||||
|
||||
[to be completed]
|
||||
|
||||
@deffn {Debugger Command} quit
|
||||
Exit the debugger.
|
||||
Evaluate an expression in the environment of the selected stack frame.
|
||||
The expression must appear on the same line as the command, however it
|
||||
may be continued over multiple lines.
|
||||
@end deffn
|
||||
|
||||
|
||||
@node Tracing
|
||||
@subsection Tracing
|
||||
|
||||
Tracing has already been described as a breakpoint behaviour
|
||||
(@pxref{Breakpoint Behaviours}), but we mention it again here because it
|
||||
is so useful, and because Guile actually now has @emph{two} mechanisms
|
||||
for tracing, and its worth clarifying the differences between them.
|
||||
|
||||
@menu
|
||||
* Old Tracing:: Tracing provided by (ice-9 debug).
|
||||
* New Tracing:: Breakpoint-based tracing.
|
||||
* Tracing Compared:: Differences between old and new.
|
||||
@end menu
|
||||
|
||||
|
||||
@node Old Tracing
|
||||
@subsubsection Tracing Provided by @code{(ice-9 debug)}
|
||||
|
||||
The @code{(ice-9 debug)} module implements tracing of procedure
|
||||
applications. When a procedure is @dfn{traced}, it means that every
|
||||
call to that procedure is reported to the user during a program run.
|
||||
|
@ -926,128 +362,6 @@ there is no need for Guile to create a new stack frame for each
|
|||
iteration. Tracing reveals this optimization in operation.
|
||||
|
||||
|
||||
@node New Tracing
|
||||
@subsubsection Breakpoint-based Tracing
|
||||
|
||||
Guile's newer mechanism implements tracing as an optional behaviour for
|
||||
any kind of breakpoint.
|
||||
|
||||
To trace a procedure (in the same kind of way as the older tracing), use
|
||||
the @code{trace!} procedure to set a procedure breakpoint with
|
||||
@code{trace-here} behaviour:
|
||||
|
||||
@lisp
|
||||
(trace! fact1)
|
||||
@print{}
|
||||
Set breakpoint 1: [fact1]
|
||||
@result{}
|
||||
#<<procedure-breakpoint> 40337bf0>
|
||||
|
||||
(fact1 4)
|
||||
@print{}
|
||||
| [fact1 4]
|
||||
| | [fact1 3]
|
||||
| | | [fact1 2]
|
||||
| | | | [fact1 1]
|
||||
| | | | | [fact1 0]
|
||||
| | | | | 1
|
||||
| | | | 2
|
||||
| | | 6
|
||||
| | 24
|
||||
| 24
|
||||
@result{}
|
||||
24
|
||||
@end lisp
|
||||
|
||||
To trace evaluation of a source expression, evaluate code containing a
|
||||
breakpoint marker @code{##} in the appropriate place, then use
|
||||
@code{set-breakpoint} to change the behaviour of the new breakpoint to
|
||||
@code{trace-here}:
|
||||
|
||||
@lisp
|
||||
(define (fact1 n)
|
||||
(if ##(= n 0)
|
||||
1
|
||||
(* n (fact1 (- n 1)))))
|
||||
@print{}
|
||||
Set breakpoint 4: standard input:13:9: (= n 0)
|
||||
|
||||
(use-modules (ice-9 debugger behaviour))
|
||||
(set-breakpoint! trace-here 4)
|
||||
@print{}
|
||||
Breakpoint 4: standard input:13:9: (= n 0)
|
||||
enabled? = #t
|
||||
behaviour = #<procedure trace-here ()>
|
||||
|
||||
(fact1 4)
|
||||
@print{}
|
||||
| (= n 0)
|
||||
| #f
|
||||
| (= n 0)
|
||||
| #f
|
||||
| (= n 0)
|
||||
| #f
|
||||
| (= n 0)
|
||||
| #f
|
||||
| (= n 0)
|
||||
| #t
|
||||
@result{}
|
||||
24
|
||||
@end lisp
|
||||
|
||||
@noindent
|
||||
(Note --- this example reveals a bug: each occurrence of @code{(= n 0)}
|
||||
should be shown indented with respect to the one before it, as
|
||||
@code{fact1} does not call itself tail-recursively.)
|
||||
|
||||
You can also give a breakpoint the @code{trace-subtree} behaviour, which
|
||||
means to trace the breakpoint location itself plus any evaluations and
|
||||
applications that occur below it in the call stack. In the following
|
||||
example, this allows us to see the evaluated arguments that are being
|
||||
compared by the @code{=} procedure:
|
||||
|
||||
@lisp
|
||||
(set-breakpoint! trace-subtree 4)
|
||||
@print{}
|
||||
Breakpoint 4: standard input:13:9: (= n 0)
|
||||
enabled? = #t
|
||||
behaviour = #<procedure trace-subtree ()>
|
||||
|
||||
(fact1 4)
|
||||
@print{}
|
||||
| (= n 0)
|
||||
| [= 4 0]
|
||||
| #f
|
||||
| (= n 0)
|
||||
| [= 3 0]
|
||||
| #f
|
||||
| (= n 0)
|
||||
| [= 2 0]
|
||||
| #f
|
||||
| (= n 0)
|
||||
| [= 1 0]
|
||||
| #f
|
||||
| (= n 0)
|
||||
| [= 0 0]
|
||||
| #t
|
||||
@result{}
|
||||
24
|
||||
@end lisp
|
||||
|
||||
|
||||
@node Tracing Compared
|
||||
@subsubsection Differences Between Old and New Tracing Mechanisms
|
||||
|
||||
The newer tracing mechanism is more general and so more powerful than
|
||||
the older one: it works for expressions as well as procedure
|
||||
applications, and it implements the useful @code{trace-subtree}
|
||||
behaviour as well as the more traditional @code{trace-here}.
|
||||
|
||||
The older mechanism will probably become obsolete eventually, but it's
|
||||
worth keeping it around for a while until we are sure that the new
|
||||
mechanism is correct and does what programmers need.
|
||||
|
||||
|
||||
@c Local Variables:
|
||||
@c TeX-master: "guile.texi"
|
||||
@c End:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue