mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 03:40:34 +02:00
api-debug.texi refactors
* doc/ref/api-debug.texi (Programmatic Error Handling): Rename from "Debug on Error". Reorganize subsections according to when the error is handled. * doc/ref/api-options.texi: Adapt xref.
This commit is contained in:
parent
9866cfe484
commit
659c1e2927
2 changed files with 90 additions and 44 deletions
|
@ -16,7 +16,7 @@ infrastructure that builds on top of those calls.
|
||||||
|
|
||||||
@menu
|
@menu
|
||||||
* Evaluation Model:: Evaluation and the Scheme stack.
|
* Evaluation Model:: Evaluation and the Scheme stack.
|
||||||
* Debug on Error:: Debugging when an error occurs.
|
* Programmatic Error Handling:: Debugging when an error occurs.
|
||||||
* Traps::
|
* Traps::
|
||||||
* Debugging Examples::
|
* Debugging Examples::
|
||||||
@end menu
|
@end menu
|
||||||
|
@ -277,8 +277,23 @@ a convenience to the user.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
@node Debug on Error
|
@node Programmatic Error Handling
|
||||||
@subsection Debugging when an error occurs
|
@subsection Programmatic Error Handling
|
||||||
|
|
||||||
|
For better or for worse, all programs have bugs, and dealing with bugs
|
||||||
|
is part of programming. This section deals with that class of bugs that
|
||||||
|
causes an exception to be raised -- from your own code, from within a
|
||||||
|
library, or from Guile itself.
|
||||||
|
|
||||||
|
@menu
|
||||||
|
* Catching Exceptions:: Handling errors after the stack is unwound.
|
||||||
|
* Capturing Stacks:: Capturing the stack at the time of error.
|
||||||
|
* Pre-Unwind Debugging:: Debugging before the exception is thrown.
|
||||||
|
* Debug Options:: A historical interface to debugging.
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
@node Catching Exceptions
|
||||||
|
@subsubsection Catching Exceptions
|
||||||
|
|
||||||
A common requirement is to be able to show as much useful context as
|
A common requirement is to be able to show as much useful context as
|
||||||
possible when a Scheme program hits an error. The most immediate
|
possible when a Scheme program hits an error. The most immediate
|
||||||
|
@ -290,8 +305,6 @@ the error is detected by C code) that signals the error, and is passed
|
||||||
automatically to the handler procedure of the innermost applicable
|
automatically to the handler procedure of the innermost applicable
|
||||||
@code{catch} or @code{with-throw-handler} expression.
|
@code{catch} or @code{with-throw-handler} expression.
|
||||||
|
|
||||||
@subsubsection Intercepting basic error information
|
|
||||||
|
|
||||||
Therefore, to catch errors that occur within a chunk of Scheme code, and
|
Therefore, to catch errors that occur within a chunk of Scheme code, and
|
||||||
to intercept basic information about those errors, you need to execute
|
to intercept basic information about those errors, you need to execute
|
||||||
that code inside the dynamic context of a @code{catch} or
|
that code inside the dynamic context of a @code{catch} or
|
||||||
|
@ -311,12 +324,32 @@ this means you need something like this:
|
||||||
@end lisp
|
@end lisp
|
||||||
|
|
||||||
@noindent
|
@noindent
|
||||||
The @code{catch} here can also be @code{with-throw-handler}; see @ref{Throw
|
The @code{catch} here can also be @code{with-throw-handler}; see
|
||||||
Handlers} for information on the when you might want to use
|
@ref{Throw Handlers} for information on the when you might want to use
|
||||||
@code{with-throw-handler} instead of @code{catch}. The @code{#t} means that the
|
@code{with-throw-handler} instead of @code{catch}.
|
||||||
catch is applicable to all kinds of error; if you want to restrict your catch to
|
|
||||||
just one kind of error, you can put the symbol for that kind of error instead of
|
For example, to print out a message and return #f when an error occurs,
|
||||||
@code{#t}. The equivalent to this in C would be something like this:
|
you might use:
|
||||||
|
|
||||||
|
@smalllisp
|
||||||
|
(define (catch-all thunk)
|
||||||
|
(catch #t
|
||||||
|
thunk
|
||||||
|
(lambda (key . parameters)
|
||||||
|
(format (current-error-port)
|
||||||
|
"Uncaught throw to '~a: ~a\n" key parameters)
|
||||||
|
#f)))
|
||||||
|
|
||||||
|
(catch-all
|
||||||
|
(lambda () (error "Not a vegetable: tomato")))
|
||||||
|
=| Uncaught throw to 'misc-error: (#f ~A (Not a vegetable: tomato) #f)
|
||||||
|
@result{} #f
|
||||||
|
@end smalllisp
|
||||||
|
|
||||||
|
The @code{#t} means that the catch is applicable to all kinds of error.
|
||||||
|
If you want to restrict your catch to just one kind of error, you can
|
||||||
|
put the symbol for that kind of error instead of @code{#t}. The
|
||||||
|
equivalent to this in C would be something like this:
|
||||||
|
|
||||||
@lisp
|
@lisp
|
||||||
SCM my_body_proc (void *body_data)
|
SCM my_body_proc (void *body_data)
|
||||||
|
@ -350,6 +383,7 @@ Again, as with the Scheme version, @code{scm_c_catch} could be replaced
|
||||||
by @code{scm_c_with_throw_handler}, and @code{SCM_BOOL_T} could instead
|
by @code{scm_c_with_throw_handler}, and @code{SCM_BOOL_T} could instead
|
||||||
be the symbol for a particular kind of error.
|
be the symbol for a particular kind of error.
|
||||||
|
|
||||||
|
@node Capturing Stacks
|
||||||
@subsubsection Capturing the full error stack
|
@subsubsection Capturing the full error stack
|
||||||
|
|
||||||
The other interesting information about an error is the full Scheme
|
The other interesting information about an error is the full Scheme
|
||||||
|
@ -458,17 +492,6 @@ SCM my_preunwind_proc (void *handler_data,
|
||||||
@}
|
@}
|
||||||
@end lisp
|
@end lisp
|
||||||
|
|
||||||
@noindent
|
|
||||||
Note that you don't have to wait until after the @code{catch} or
|
|
||||||
@code{scm_c_catch} has returned. You can also do whatever you like with
|
|
||||||
the stack immediately after it has been captured in the pre-unwind
|
|
||||||
handler, or in the normal (post-unwind) handler. (Except that for the
|
|
||||||
latter case in C you will need to change @code{handler_data} in the
|
|
||||||
@code{scm_c_catch(@dots{})} call to @code{&captured_stack}, so that
|
|
||||||
@code{my_handler_proc} has access to the captured stack.)
|
|
||||||
|
|
||||||
@subsubsection Displaying or interrogating the captured stack
|
|
||||||
|
|
||||||
Once you have a captured stack, you can interrogate and display its
|
Once you have a captured stack, you can interrogate and display its
|
||||||
details in any way that you want, using the @code{stack-@dots{}} and
|
details in any way that you want, using the @code{stack-@dots{}} and
|
||||||
@code{frame-@dots{}} API described in @ref{Examining the Stack} and
|
@code{frame-@dots{}} API described in @ref{Examining the Stack} and
|
||||||
|
@ -477,37 +500,60 @@ details in any way that you want, using the @code{stack-@dots{}} and
|
||||||
If you want to print out a backtrace in the same format that the Guile
|
If you want to print out a backtrace in the same format that the Guile
|
||||||
REPL does, you can use the @code{display-backtrace} procedure to do so.
|
REPL does, you can use the @code{display-backtrace} procedure to do so.
|
||||||
You can also use @code{display-application} to display an individual
|
You can also use @code{display-application} to display an individual
|
||||||
application frame -- that is, a frame that satisfies the
|
frame in the Guile REPL format.
|
||||||
@code{frame-procedure?} predicate -- in the Guile REPL format.
|
|
||||||
|
|
||||||
@subsubsection What the Guile REPL does
|
@node Pre-Unwind Debugging
|
||||||
|
@subsubsection Pre-Unwind Debugging
|
||||||
|
|
||||||
The Guile REPL code (in @file{system/repl/repl.scm} and related files)
|
Instead of saving a stack away and waiting for the @code{catch} to
|
||||||
uses a @code{catch} with a pre-unwind handler to capture the stack when
|
return, you can handle errors directly, from within the pre-unwind
|
||||||
an error occurs in an expression that was typed into the REPL, and saves
|
handler.
|
||||||
the captured stack in a fluid (@pxref{Fluids and Dynamic States}) called
|
|
||||||
@code{the-last-stack}. You can then use the @code{(backtrace)} command,
|
For example, to show a backtrace when an error is thrown, you might want
|
||||||
which is basically equivalent to @code{(display-backtrace (fluid-ref
|
to use a procedure like this:
|
||||||
the-last-stack))}, to print out this stack at any time until it is
|
|
||||||
overwritten by the next error that occurs.
|
@lisp
|
||||||
|
(define (with-backtrace thunk)
|
||||||
|
(with-throw-handler #t
|
||||||
|
thunk
|
||||||
|
(lambda args (backtrace))))
|
||||||
|
(with-backtrace (lambda () (error "Not a vegetable: tomato")))
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
Since we used @code{with-throw-handler} here, we didn't actually catch
|
||||||
|
the error. @xref{Throw Handlers}, for more information. However, we did
|
||||||
|
print out a context at the time of the error, using the built-in
|
||||||
|
procedure, @code{backtrace}.
|
||||||
|
|
||||||
@deffn {Scheme Procedure} backtrace [highlights]
|
@deffn {Scheme Procedure} backtrace [highlights]
|
||||||
@deffnx {C Function} scm_backtrace_with_highlights (highlights)
|
@deffnx {C Function} scm_backtrace_with_highlights (highlights)
|
||||||
@deffnx {C Function} scm_backtrace ()
|
@deffnx {C Function} scm_backtrace ()
|
||||||
Display a backtrace of the stack saved by the last error
|
Display a backtrace of the current stack to the current output port. If
|
||||||
to the current output port. If @var{highlights} is given
|
@var{highlights} is given it should be a list; the elements of this list
|
||||||
it should be a list; the elements of this list will be
|
will be highlighted wherever they appear in the backtrace.
|
||||||
highlighted wherever they appear in the backtrace.
|
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
You can also use the @code{(debug)} command to explore the saved stack
|
The Guile REPL code (in @file{system/repl/repl.scm} and related files)
|
||||||
using an interactive command-line-driven debugger. See @ref{Interactive
|
uses a @code{catch} with a pre-unwind handler to capture the stack when
|
||||||
Debugging} for more information about this.
|
an error occurs in an expression that was typed into the REPL, and debug
|
||||||
|
that stack interactively in the context of the error.
|
||||||
|
|
||||||
@deffn {Scheme Procedure} debug
|
These procedures are available for use by user programs, in the
|
||||||
Invoke the Guile debugger to explore the context of the last error.
|
@code{(system repl error-handling)} module.
|
||||||
|
|
||||||
|
@lisp
|
||||||
|
(use-modules (system repl error-handling))
|
||||||
|
@end lisp
|
||||||
|
|
||||||
|
@deffn {Scheme Procedure} call-with-error-handling thunk @\
|
||||||
|
[#:on-error on-error='debug] @\
|
||||||
|
[#:post-error post-error='catch] @\
|
||||||
|
[#:pass-keys pass-keys='(quit)] @\
|
||||||
|
[#:trap-handler trap-handler='debug]
|
||||||
|
foo
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
@node Debug Options
|
||||||
@subsubsection Debug options
|
@subsubsection Debug options
|
||||||
|
|
||||||
The behavior when an error is the @code{backtrace} procedure and of the
|
The behavior when an error is the @code{backtrace} procedure and of the
|
||||||
|
|
|
@ -382,8 +382,8 @@ For more information on reader options, @xref{Scheme Read}.
|
||||||
|
|
||||||
For more information on print options, @xref{Scheme Write}.
|
For more information on print options, @xref{Scheme Write}.
|
||||||
|
|
||||||
Finally, for more information on debugger options, @xref{Debug on
|
Finally, for more information on debugger options, @xref{Debug
|
||||||
Error}.
|
Options}.
|
||||||
|
|
||||||
@subsubsection Examples of option use
|
@subsubsection Examples of option use
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue