The debugger is an interactive command loop that allows a user to examine the function call stack. The debugger is invoked when:
serious-condition
is signaled, and it is not handled, or
error
is called, and the condition it signals is not handled,
or
break
or
invoke-debugger
functions.
When you enter the TTY debugger, it looks something like this:
debugger invoked on a TYPE-ERROR in thread 11184: The value 3 is not of type LIST. restarts (invokable by number or by possibly-abbreviated name): 0: [ABORT ] Reduce debugger level (leaving debugger, returning to toplevel). 1: [TOPLEVEL] Restart at toplevel READ/EVAL/PRINT loop. (CAR 1 3)[:EXTERNAL] 0]
The first group of lines describe what the error was that put us in
the debugger. In this case car
was called on 3
. After
restarts is a list of all the ways that we can restart
execution after this error. In this case, both options return to
top-level. After printing its banner, the debugger prints the current
frame and the debugger prompt.
When the debugger is invoked by a condition, ANSI mandates that the
value of *debugger-hook*
, if any, be called with two arguments:
the condition that caused the debugger to be invoked and the previous
value of *debugger-hook*
. When this happens,
*debugger-hook*
is bound to NIL to prevent recursive
errors. However, ANSI also mandates that *debugger-hook*
not be
invoked when the debugger is to be entered by the break
function. For users who wish to provide an alternate debugger
interface (and thus catch break
entries into the debugger),
SBCL provides sb-ext:*invoke-debugger-hook*
, which is invoked
during any entry into the debugger.
This is either
nil
or a designator for a function of two arguments, to be run when the debugger is about to be entered. The function is run with*invoke-debugger-hook*
bound tonil
to minimize recursive errors, and receives as arguments the condition that triggered debugger entry and the previous value of*invoke-debugger-hook*
This mechanism is an
sbcl
extension similar to the standard*debugger-hook*
. In contrast to*debugger-hook*
, it is observed byinvoke-debugger
even when called bybreak
.