-@node The Debugger
+@node Debugger
@comment node-name, next, previous, up
-@chapter The Debugger
+@chapter Debugger
@cindex Debugger
-The SBCL debugger (as the CMUCL debugger it was derived from) has very
-good support for source-level debugging of compiled code. Although
-some other debuggers allow access of variables by name, this seems to
-be the first Lisp debugger that:
-
-@itemize
-
-@item
-Tells you when a variable doesn't have a value because it hasn't been
-initialized yet or has already been deallocated, or
-
-@item
-Can display the precise source location corresponding to a code
-location in the debugged program.
-
-@end itemize
-
-These features allow the debugging of compiled code to be made almost
-indistinguishable from interpreted code debugging.
-
+This chapter documents the debugging facilities of SBCL, including
+the debugger, single-stepper and @code{trace}, and the effect of
+@code{(optimize debug)} declarations.
@menu
-* Starting the Debugger::
-* The Debugger Command Loop::
-* Controlling Printing in the Debugger::
+* Debugger Entry::
+* Debugger Command Loop::
* Stack Frames::
* Variable Access::
* Source Location Printing::
* Exiting Commands::
* Information Commands::
* Function Tracing::
+* Single Stepping::
+* Enabling and Disabling the Debugger::
@end menu
-@node Starting the Debugger
+@node Debugger Entry
@comment node-name, next, previous, up
-@section Starting the Debugger
-
-The debugger is an interactive command loop that allows a user to examine
-the function call stack. The debugger is invoked when:
-
-@itemize
-
-@item
-A @code{serious-condition} is signaled, and it is not handled, or
-
-@item
-@code{error} is called, and the condition it signals is not handled,
-or
+@section Debugger Entry
-@item
-the debugger is explicitly entered with the Lisp @code{break} or
-@code{invoke-debugger} functions.
+@menu
+* Debugger Banner::
+* Debugger Invocation::
+@end menu
-@end itemize
+@node Debugger Banner
+@comment node-name, next, previous, up
+@subsection Debugger Banner
-When you enter the TTY debugger, it looks something like this:
+When you enter the debugger, it looks something like this:
@example
debugger invoked on a TYPE-ERROR in thread 11184:
The value 3 is not of type LIST.
+
+You can type HELP for debugger help, or (SB-EXT:QUIT) to exit from SBCL.
+
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]
+(CAR 1 3)
0]
@end example
The first group of lines describe what the error was that put us in
-the debugger. In this case @code{car} was called on @code{3}. After
-@samp{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.
+the debugger. In this case @code{car} was called on @code{3}, causing
+a @code{type-error}.
+
+This is followed by the ``beginner help line'', which appears only if
+@code{sb-ext:*debug-beginner-help-p*} is true (default).
+
+Next comes a listing of the active restart names, along with their
+descriptions -- the ways we can restart execution after this error. In
+this case, both options return to top-level. Restarts can be selected
+by entering the corresponding number or name.
+
+The current frame appears right underneath the restarts, immediately
+followed by the debugger prompt.
+
+@node Debugger Invocation
+@comment node-name, next, previous, up
+@subsection Debugger Invocation
+
+The debugger is invoked when:
+
+@itemize
+
+@item
+@code{error} is called, and the condition it signals is not handled.
+
+@item
+@code{break} is called, or @code{signal} is called with a condition
+that matches the current @code{*break-on-signals*}.
+
+@item
+the debugger is explicitly entered with the @code{invoke-debugger}
+function.
+
+@end itemize
When the debugger is invoked by a condition, ANSI mandates that the
value of @code{*debugger-hook*}, if any, be called with two arguments:
the condition that caused the debugger to be invoked and the previous
value of @code{*debugger-hook*}. When this happens,
-@code{*debugger-hook*} is bound to NIL to prevent recursive
-errors. However, ANSI also mandates that @code{*debugger-hook*} not be
-invoked when the debugger is to be entered by the @code{break}
-function. For users who wish to provide an alternate debugger
-interface (and thus catch @code{break} entries into the debugger),
-SBCL provides @code{sb-ext:*invoke-debugger-hook*}, which is invoked
-during any entry into the debugger.
+@code{*debugger-hook*} is bound to NIL to prevent recursive errors.
+However, ANSI also mandates that @code{*debugger-hook*} not be invoked
+when the debugger is to be entered by the @code{break} function. For
+users who wish to provide an alternate debugger interface (and thus
+catch @code{break} entries into the debugger), SBCL provides
+@code{sb-ext:*invoke-debugger-hook*}, which is invoked during any
+entry into the debugger.
@include var-sb-ext-star-invoke-debugger-hook-star.texinfo
-
-@node The Debugger Command Loop
+@node Debugger Command Loop
@comment node-name, next, previous, up
-@section The Debugger Command Loop
-@cindex Evaluation, in the debugger
-
-The debugger is an interactive read-eval-print loop much like the normal
-top-level, but some symbols are interpreted as debugger commands instead
-of being evaluated. A debugger command starts with the symbol name of
-the command, possibly followed by some arguments on the same line. Some
-commands prompt for additional input. Debugger commands can be
-abbreviated by any unambiguous prefix: @command{help} can be typed as
-@samp{h}, @samp{he}, etc. For convenience, some commands have
-ambiguous one-letter abbreviations: @samp{f} for @command{frame}.
-@comment FIXME: what does that last bit mean?
-
-The package is not significant in debugger commands; any symbol with the
-name of a debugger command will work. If you want to show the value of
-a variable that happens also to be the name of a debugger command, you
-can use the @command{list-locals} command or the @code{sb-debug:var}
-function, or you can wrap the variable in a @code{progn} to hide it from
+@section Debugger Command Loop
+
+The debugger is an interactive read-eval-print loop much like the
+normal top level, but some symbols are interpreted as debugger
+commands instead of being evaluated. A debugger command starts with
+the symbol name of the command, possibly followed by some arguments on
+the same line. Some commands prompt for additional input. Debugger
+commands can be abbreviated by any unambiguous prefix: @command{help}
+can be typed as @samp{h}, @samp{he}, etc.
+
+The package is not significant in debugger commands; any symbol with
+the name of a debugger command will work. If you want to show the
+value of a variable that happens also to be the name of a debugger
+command you can wrap the variable in a @code{progn} to hide it from
the command loop.
The debugger prompt is ``@code{@var{frame}]}'', where @var{frame} is
the number of the current frame. Frames are numbered starting from
zero at the top (most recent call), increasing down to the bottom.
-The current frame is the frame that commands refer to. The current
-frame also provides the lexical environment for evaluation of
-non-command forms.
-
- The debugger evaluates forms in the lexical environment of the
-functions being debugged. The debugger can only access variables.
-You can't @code{go} or @code{return-from} into a function, and you
-can't call local functions. Special variable references are evaluated
-with their current value (the innermost binding around the debugger
-invocation) -- you don't get the value that the special had in the
-current frame. For more information on debugger variable access, see
-@ref{Variable Access}.
+The current frame is the frame that commands refer to.
+It is possible to override the normal printing behaviour in the
+debugger by using the @code{sb-ext:*debug-print-variable-alist*}.
-@node Controlling Printing in the Debugger
-@comment node-name, next, previous, up
-@section Controlling Printing in the Debugger
-
-In the debugger, it is possible to override the printing behaviour of
-the REPL.
-
-@defvr {Variable} sb-debug:*debug-print-variable-alist*
-
-An association list describing new bindings for special variables
-(typically *PRINT-FOO* variables) to be used within the debugger, e.g.
-@lisp
-((*PRINT-LENGTH* . 10) (*PRINT-LEVEL* . 6) (*PRINT-PRETTY* . NIL))
-@end lisp
-The variables in the @code{car} position are bound to the values in
-the @code{cdr} during the execution of some debug commands. When
-evaluating arbitrary expressions in the debugger, the normal values of
-the printer control variables are in effect. @c FIXME: is this correct?
-@code{*debug-print-variable-alist*} does not contain any bindings
-initially.
-
-@end defvr
+@include var-sb-ext-star-debug-print-variable-alist-star.texinfo
@node Stack Frames
@comment node-name, next, previous, up
@item
@dfn{variables} (@pxref{Variable Access}), which are the values being operated
-on;
+on.
@item
@dfn{arguments} to the call (which are really just particularly
-interesting variables), and
+interesting variables).
@item
-a current location (@pxref{Source Location Printing}), which is the place in
-the program where the function was running when it stopped to call
-another function, or because of an interrupt or error.
+a current source location (@pxref{Source Location Printing}), which is
+the place in the program where the function was running when it
+stopped to call another function, or because of an interrupt or error.
@end itemize
-
@menu
* Stack Motion::
* How Arguments are Printed::
* Function Names::
-* Funny Frames::
* Debug Tail Recursion::
* Unknown Locations and Interrupts::
@end menu
function and the values of its arguments in the style of a Lisp
function call:
-@deffn {Debugger Command} up
+@deffn {Debugger Command} @nopkg{up}
Move up to the next higher frame. More recent function calls are
considered to be higher on the stack.
@end deffn
-@deffn {Debugger Command} down
+@deffn {Debugger Command} @nopkg{down}
Move down to the next lower frame.
@end deffn
-@deffn {Debugger Command} top
+@deffn {Debugger Command} @nopkg{top}
Move to the highest frame, that is, the frame where the debugger was
entered.
@end deffn
-@deffn {Debugger Command} bottom
+@deffn {Debugger Command} @nopkg{bottom}
Move to the lowest frame.
@end deffn
-@deffn {Debugger Command} frame [@var{n}]
+@deffn {Debugger Command} @nopkg{frame} [@var{n}]
Move to the frame with the specified number. Prompts for the number if not
supplied. The frame with number 0 is the frame where the debugger
was entered.
then @samp{#<unavailable-arg>} will be printed instead of the argument
value.
-@vindex *debug-print-variable-alist*
-Printing of argument values is controlled by
-@code{*debug-print-variable-alist*}. @xref{Controlling Printing in
-the Debugger}.
+ Note that inline expansion and open-coding affect what frames
+are present in the debugger, see @ref{Debugger Policy Control}.
+@comment FIXME: link here to section about open coding once it exists.
+@c @ref{open-coding}
@node Function Names
@comment node-name, next, previous, up
@subsection Function Names
-If a function is defined by @code{defun}, @code{labels}, or
-@code{flet}, then the debugger will print the actual function name
-after the open parenthesis, like:
-
-@example
-(STRING-UPCASE "test case" :START 0 :END NIL)
-((SETF AREF) #\a "for" 1)
-@end example
-
-Otherwise, the function name is a string, and will be printed in
-quotes:
-
-@example
-("DEFUN MYFUN" BAR)
-("DEFMACRO DO" (DO ((I 0 (1+ I))) ((= I 13))) NIL)
-("SETQ *GC-NOTIFY-BEFORE*")
-@end example
-
-This string name is derived from the @code{def@var{mumble}} form
-that encloses or expanded into the lambda, or the outermost enclosing
-form if there is no @code{def@var{mumble}}.
+If a function is defined by @code{defun} it will appear in backtrace
+by that name. Functions defined by @code{labels} and @code{flet} will
+appear as @code{(FLET <name>)} and @code{(LABELS <name>)} respectively.
+Anonymous lambdas will appear as @code{(LAMDBA <lambda-list>)}.
+@menu
+* Entry Point Details::
+@end menu
-@node Funny Frames
+@node Entry Point Details
@comment node-name, next, previous, up
-@subsection Funny Frames
+@subsubsection Entry Point Details
@cindex External entry points
@cindex Entry points, external
@cindex Block compilation, debugger implications
@cindex Optional, stack frame kind
@cindex Cleanup, stack frame kind
-Sometimes the evaluator introduces new functions that are used to
+Sometimes the compiler introduces new functions that are used to
implement a user function, but are not directly specified in the
-source. The main place this is done is for checking argument type and
-syntax. Usually these functions do their thing and then go away, and
-thus are not seen on the stack in the debugger. But when you get some
-sort of error during lambda-list processing, you end up in the
-debugger on one of these funny frames.
-
-These funny frames are flagged by printing
-``@code{[@var{keyword}]}'' after the parentheses. For example,
-this call:
-
-@lisp
-(car 'a 'b)
-@end lisp
-
-will look like this:
-
-@example
-(CAR 2 A)[:EXTERNAL]
-@end example
-
-And this call:
-
-@lisp
-(string-upcase "test case" :end)
-@end lisp
-
-would look like this:
-
-@example
-("SB!INT:&MORE processing" "test case" 1053984 1)[:OPTIONAL]
-@end example
-
-As you can see, these frames have only a vague resemblance to the
-original call. Fortunately, the error message displayed when you
-enter the debugger will usually tell you what problem is (in these
-cases, too many arguments and odd keyword arguments.) Also, if you go
-down the stack to the frame for the calling function, you can display
-the original source. @xref{Source Location Printing}.
-
-@c FIXME: is the block-compilation part correct for SBCL?
-
-With recursive or block compiled functions, an @code{:EXTERNAL} frame
-may appear before the frame representing the first call to the
-recursive function or entry to the compiled block. This is a
-consequence of the way the compiler does block compilation: there is
-nothing odd with your program. You will also see @code{:CLEANUP}
-frames during the execution of @code{unwind-protect} cleanup
-code. Note that inline expansion and open-coding affect what frames
-are present in the debugger, see @ref{Debugger Policy Control}.
-@comment FIXME: link here to section about open coding once it exists.
-@c @ref{open-coding}
-
+source. This is mostly done for argument type and count checking.
+
+@c FIXME: the following bits talked about block-compilation, but
+@c we don't currently support it...
+
+@c With recursive
+@c or block compiled
+@c functions, an additional @code{:EXTERNAL} frame
+@c may appear before the frame representing the first call to the
+@c recursive function
+@c or entry to the compiled block.
+@c This is a
+@c consequence of the way the compiler works: there is
+@c nothing odd with your program. You will also see @code{:CLEANUP}
+@c frames during the execution of @code{unwind-protect} cleanup
+@c code.
+
+With recursive functions, an additional @code{external} frame may
+appear before the frame representing the first call to the recursive
+function. This is a consequence of the way the compiler works: there
+is nothing odd with your program. You may also see @code{cleanup}
+frames during the execution of @code{unwind-protect} cleanup code, and
+@code{optional} for variable argument entry points.
@node Debug Tail Recursion
@comment node-name, next, previous, up
@cindex Tail recursion
@cindex Recursion, tail
-Both the compiler and the interpreter are ``properly tail recursive.''
-If a function call is in a tail-recursive position, the stack frame
-will be deallocated @emph{at the time of the call}, rather than after
-the call returns. Consider this backtrace:
+The compiler is ``properly tail recursive.'' If a function call is in
+a tail-recursive position, the stack frame will be deallocated
+@emph{at the time of the call}, rather than after the call returns.
+Consider this backtrace:
@example
(BAR ...)
@end lisp
Usually the elimination of tail-recursive frames makes debugging more
-pleasant, since theses frames are mostly uninformative. If there is
-any doubt about how one function called another, it can usually be
+pleasant, since these frames are mostly uninformative. If there is any
+doubt about how one function called another, it can usually be
eliminated by finding the source location in the calling frame.
@xref{Source Location Printing}.
@comment FIXME: reinstate this link once the chapter is in the manual.
@c For a more thorough discussion of tail recursion, @ref{tail-recursion}.
-
@node Unknown Locations and Interrupts
@comment node-name, next, previous, up
@subsection Unknown Locations and Interrupts
X#1 = 2
@end example
-@deffn {Debugger Command} list-locals [@var{prefix}]
+@deffn {Debugger Command} @nopkg{list-locals} [@var{prefix}]
This command prints the name and value of all variables in the current
frame whose name has the specified @var{prefix}. @var{prefix} may be
a string or a symbol. If no @var{prefix} is given, then all available
name unique.
@end deffn
-@defun sb-debug:var @var{name} &optional @var{identifier}
+@defun @sbdebug{var} @var{name} &optional @var{identifier}
This function returns the value of the variable in the current frame
with the specified @var{name}. If supplied, @var{identifier}
determines which value to return when there are ambiguous variables.
compiled code. These commands display the source location for the
current frame:
-@deffn {Debugger Command} source [@var{context}]
+@deffn {Debugger Command} @nopkg{source} [@var{context}]
This command displays the file that the current frame's function was
defined from (if it was defined from a file), and then the source form
responsible for generating the code that the current frame was
If the heuristic doesn't work, the displayed source will be wrong, but will
probably be near the actual source. If the ``shape'' of the top-level form in
the source file is too different from the original form, then an error will be
-signaled. When the heuristic is used, the the source location commands are
+signaled. When the heuristic is used, the source location commands are
noticeably slowed.
Source location printing can also be confused if (after the source was
@item The block start location may be the same as the true location.
-@item The block start location will never be later in the the
+@item The block start location will never be later in the
program's flow of control than the true location.
@item No conditional control structures (such as @code{if},
information, and lifetime information that tells the debugger when
arguments are available (even when @code{speed} is @code{3} or the
argument is set).
-
+
@item > 2
Any level greater than @code{2} gives level @code{2} and in addition
disables tail-call optimization, so that the backtrace will contain
the command @command{return} can be used to continue execution by
returning a value from the current stack frame.
+@item > (max speed space compilation-speed)
+If @code{debug} is greater than all of @code{speed}, @code{space} and
+@code{compilation-speed} the code will be steppable (@pxref{Single Stepping}).
+
@end table
As you can see, if the @code{speed} quality is @code{3}, debugger performance is
These commands get you out of the debugger.
-@deffn {Debugger Command} toplevel
+@deffn {Debugger Command} @nopkg{toplevel}
Throw to top level.
@end deffn
-@deffn {Debugger Command} restart [@var{n}]
+@deffn {Debugger Command} @nopkg{restart} [@var{n}]
Invokes the @var{n}th restart case as displayed by the @code{error}
command. If @var{n} is not specified, the available restart cases are
reported.
@end deffn
-@deffn {Debugger Command} continue
+@deffn {Debugger Command} @nopkg{continue}
Calls @code{continue} on the condition given to @code{debug}. If there is no
restart case named @var{continue}, then an error is signaled.
@end deffn
-@deffn {Debugger Command} abort
+@deffn {Debugger Command} @nopkg{abort}
Calls @code{abort} on the condition given to @code{debug}. This is
useful for popping debug command loop levels or aborting to top level,
as the case may be.
@end deffn
-@deffn {Debugger Command} return @var{value}
+@deffn {Debugger Command} @nopkg{return} @var{value}
Returns @var{value} from the current stack frame. This command is
available when the @code{debug} optimization quality is greater than
both @code{speed} and @code{space}. Care must be taken that the value
is of the same type as SBCL expects the stack frame to return.
@end deffn
+@deffn {Debugger Command} @nopkg{restart-frame}
+Restarts execution of the current stack frame. This command is
+available when the @code{debug} optimization quality is greater than
+both @code{speed} and @code{space} and when the frame is for is a global
+function. If the function is redefined in the debugger before the frame
+is restarted, the new function will be used.
+@end deffn
@node Information Commands
@comment node-name, next, previous, up
Most of these commands print information about the current frame or
function, but a few show general information.
-@deffn {Debugger Command} help
-@deffnx {Debugger Command} ?
+@deffn {Debugger Command} @nopkg{help}
+@deffnx {Debugger Command} @nopkg{?}
Displays a synopsis of debugger commands.
@end deffn
-@deffn {Debugger Command} describe
+@deffn {Debugger Command} @nopkg{describe}
Calls @code{describe} on the current function and displays the number of
local variables.
@end deffn
-@deffn {Debugger Command} print
+@deffn {Debugger Command} @nopkg{print}
Displays the current function call as it would be displayed by moving to
this frame.
@end deffn
-@deffn {Debugger Command} error
+@deffn {Debugger Command} @nopkg{error}
Prints the condition given to @code{invoke-debugger} and the active
proceed cases.
@end deffn
-@deffn {Debugger Command} backtrace [@var{n}]
-Displays all the frames from the current to the bottom. Only shows
-@var{n} frames if specified. The printing is controlled by @code{*debug-print-variable-alist*}.
+@deffn {Debugger Command} @nopkg{backtrace} [@var{n}]
+Displays all the frames from the current to the bottom. Only shows
+@var{n} frames if specified. The printing is controlled by
+@code{*debug-print-variable-alist*}.
@end deffn
-@comment FIXME (rudi 2004-03-31): sbcl doesn't support breakpoints
-@comment and stepping as of version 0.8.9. The `list-locations'
-@comment command works, but executing a function leads to an error
-@comment when a breakpoint is hit. When stepping works, the
-@comment commented-out section below should be reinstated and the
-@comment example output updated to correspont to sbcl's behaviour.
+@c The new instrumentation based single stepper doesn't support
+@c the following commands, but BREAKPOINT at least should be
+@c resurrectable via (TRACE FOO :BREAK T).
-@c @node Breakpoint Commands, , Information Commands, The Debugger
-@c @comment node-name, next, previous, up
-@c @section Breakpoint Commands
@c @cindex Breakpoints
@c SBCL supports setting of breakpoints inside compiled functions and
-@c stepping of compiled code. Breakpoints can only be set at at known
+@c stepping of compiled code. Breakpoints can only be set at known
@c locations (@pxref{Unknown Locations and Interrupts}), so these
@c commands are largely useless unless the @code{debug} optimize quality
@c is at least @code{2} (@pxref{Debugger Policy Control}). These
@c is specified, delete all breakpoints.
@c @end deffn
-@c @deffn {Debugger Command} step
-@c Step to the next possible breakpoint location in the current function.
-@c This always steps over function calls, instead of stepping into them.
-@c @end deffn
-
-
@c @menu
@c * Breakpoint Example::
@c @end menu
@comment 0.8.9) in a state of flux. When it's sorted out, revive the
@comment cmucl documentation.
+@node Single Stepping
+@comment node-name, next, previous, up
+@section Single Stepping
+@cindex Stepper
+@cindex Single Stepping
+
+SBCL includes an instrumentation based single-stepper for compiled
+code, that can be invoked via the @code{step} macro, or from within
+the debugger. @xref{Debugger Policy Control}, for details on enabling
+stepping for compiled code.
+
+The following debugger commands are used for controlling single stepping.
+
+@deffn {Debugger Command} @nopkg{start}
+Selects the @code{continue} restart if one exists and starts single stepping.
+None of the other single stepping commands can be used before stepping has
+been started either by using @code{start} or by using the standard
+@code{step} macro.
+@end deffn
+
+@deffn {Debugger Command} @nopkg{step}
+Steps into the current form. Stepping will be resumed when the next
+form that has been compiled with stepper instrumentation is evaluated.
+@end deffn
+
+@deffn {Debugger Command} @nopkg{next}
+Steps over the current form. Stepping will be disabled until evaluation of
+the form is complete.
+@end deffn
+
+@deffn {Debugger Command} @nopkg{out}
+Steps out of the current frame. Stepping will be disabled until the
+topmost stack frame that had been stepped into returns.
+@end deffn
+
+@deffn {Debugger Command} @nopkg{stop}
+Stops the single stepper and resumes normal execution.
+@end deffn
+
+@include macro-common-lisp-step.texinfo
+
+@node Enabling and Disabling the Debugger
+@comment node-name, next, previous, up
+@section Enabling and Disabling the Debugger
+
+@cindex debugger, enabling
+@cindex debugger, disabling
+@cindex disabling debugger
+@cindex ldb, enabling
+@cindex ldb, disabling
+@cindex disabling ldb
+
+In certain contexts (e.g., non-interactive applications), it may be
+desirable to turn off the SBCL debugger (and possibly re-enable it).
+The functions here control the debugger.
+@include fun-sb-ext-disable-debugger.texinfo
+@include fun-sb-ext-enable-debugger.texinfo