The debugger programmers interface is exported from from the
DEBUG-INTERNALSor
DIpackage. This is a CMU extension that allows debugging tools to be written without detailed knowledge of the compiler or run-time system.
Some of the interface routines take a code-location as an argument. As described in the section on code-locations, some code-locations are unknown. When a function calls for a
basic-code-location, it takes either type, but when it specifically names the argument
code-location, the routine will signal an error if you give it an unknown code-location.
Some of these operations fail depending on the availability debugging information. In the most severe case, when someone saved a Lisp image stripping all debugging data structures, no operations are valid. In this case, even backtracing and finding frames is impossible. Some interfaces can simply return values indicating the lack of information, or their return values are naturally meaningful in light missing data. Other routines, as documented below, will signal
serious-conditions when they discover awkward situations. This interface does not provide for programs to detect these situations other than by calling a routine that detects them and signals a condition. These are serious-conditions because the program using the interface must handle them before it can correctly continue execution. These debugging conditions are not errors since it is no fault of the programmers that the conditions occur.
The debug internals interface signals conditions when it can't adhere to its contract. These are serious-conditions because the program using the interface must handle them before it can correctly continue execution. These debugging conditions are not errors since it is no fault of the programmers that the conditions occur. The interface does not provide for programs to detect these situations other than calling a routine that detects them and signals a condition.
This condition inherits from serious-condition, and all debug-conditions inherit from this. These must be handled, but they are not programmer errors.
This condition indicates there is absolutely no debugging information available.
This condition indicates the system cannot return values from a frame since its debug-function lacks debug information details about returning values.
This condition indicates that a function was not compiled with debug-block information, but this information is necessary necessary for some requested operation.
Similar to no-debug-blocks, except that variable information was requested.
Similar to no-debug-blocks, except that lambda list information was requested.
This condition indicates a debug-variable has
:invalidor
:unknownvalue in a particular frame.
This condition indicates a user supplied debug-variable name identifies more than one valid variable in a particular frame.
These are programmer errors resulting from misuse of the debugging tools' programmers' interface. You could have avoided an occurrence of one of these by using some routine to check the use of the routine generating the error.
This condition inherits from error, and all user programming errors inherit from this condition.
This error results from a signalled debug-condition occurring without anyone handling it.
This error indicates the invalid use of an unknown-code-location.
This error indicates an attempt to use a debug-variable in conjunction with an inappropriate debug-function; for example, checking the variable's validity using a code-location in the wrong debug-function will signal this error.
This error indicates you called a function returned by
preprocess-for-evalon a frame other than the one for which the function had been prepared.
Debug-variables represent the constant information about where the system stores argument and local variable values. The system uniquely identifies with an integer every instance of a variable with a particular name and package. To access a value, you must supply the frame along with the debug-variable since these are particular to a function, not every instance of a variable on the stack.
This function returns the name of the
debug-variable. The name is the name of the symbol used as an identifier when writing the code.
This function returns the package name of the
debug-variable. This is the package name of the symbol used as an identifier when writing the code.
This function returns the symbol from interning
debug-variable-namein the package named by
debug-variable-package.
This function returns the integer that makes
debug-variable's name and package name unique with respect to other
debug-variable's in the same function.
This function returns three values reflecting the validity of
debug-variable's value at
basic-code-location:
- :valid
- The value is known to be available.
- :invalid
- The value is known to be unavailable.
- :unknown
- The value's availability is unknown.
This function returns the value stored for
debug-variablein
frame. The value may be invalid. This is
SETF'able.
This function returns the value stored for
debug-variablein
frame. If the value is not
:valid, then this signals an
invalid-valueerror.
Frames describe a particular call on the stack for a particular thread. This is the environment for name resolution, getting arguments and locals, and returning values. The stack conceptually grows up, so the top of the stack is the most recently called function.
top-frame,
frame-down,
frame-up, and
frame-debug-functioncan only fail when there is absolutely no debug information available. This can only happen when someone saved a Lisp image specifying that the system dump all debugging data.
This function never returns the frame for itself, always the frame before calling
top-frame.
This returns the frame immediately below
frameon the stack. When
frameis the bottom of the stack, this returns
nil.
This returns the frame immediately above
frameon the stack. When
frameis the top of the stack, this returns
nil.
This function returns the debug-function for the function whose call
framerepresents.
This function returns the code-location where
frame's debug-function will continue running when program execution returns to
frame. If someone interrupted this frame, the result could be an unknown code-location.
This function returns an a-list for all active catches in
framemapping catch tags to the code-locations at which the catch re-enters.
This evaluates
formin
frame's environment. This can signal several different debug-conditions since its success relies on a variety of inexact debug information:
invalid-value,
ambiguous-variable-name,
frame-function-mismatch preprocess-for-eval.
Debug-functions represent the static information about a function determined at compile time—argument and variable storage, their lifetime information, etc. The debug-function also contains all the debug-blocks representing basic-blocks of code, and these contains information about specific code-locations in a debug-function.
This executes the forms in a context with
block-varbound to each debug-block in
debug-functionsuccessively.
Result-formis an optional form to execute for a return value, and
do-debug-function-blocksreturns
nilif there is no
result-form. This signals a
no-debug-blockscondition when the
debug-functionlacks debug-block information.
This function returns a list representing the lambda-list for
debug-function. The list has the following structure:
(required-var1 required-var2 ... (:optional var3 suppliedp-var4) (:optional var5) ... (:rest var6) (:rest var7) ... (:keyword keyword-symbol var8 suppliedp-var9) (:keyword keyword-symbol var10) ... )Each
varnis a debug-variable; however, the symbol
:deletedappears instead whenever the argument remains unreferenced throughout
debug-function.
If there is no lambda-list information, this signals a
lambda-list-unavailablecondition.
This macro executes each
formin a context with
varbound to each debug-variable in
debug-function. This returns the value of executing
result(defaults to
nil). This may iterate over only some of
debug-function's variables or none depending on debug policy; for example, possibly the compilation only preserved argument information.
This function returns whether there is any variable information for
debug-function. This is useful for distinguishing whether there were no locals in a function or whether there was no variable information. For example, if
do-debug-function-variablesexecutes its forms zero times, then you can use this function to determine the reason.
This function returns a list of debug-variables in
debug-functionhaving the same name and package as
symbol. If
symbolis uninterned, then this returns a list of debug-variables without package names and with the same name as
symbol. The result of this function is limited to the availability of variable information in
debug-function; for example, possibly
debug-functiononly knows about its arguments.
This function returns a list of debug-variables in
debug-functionwhose names contain
name-prefix-stringas an initial substring. The result of this function is limited to the availability of variable information in
debug-function; for example, possibly
debug-functiononly knows about its arguments.
This function returns a function of one argument that evaluates
formin the lexical context of
basic-code-location. This allows efficient repeated evaluation of
format a certain place in a function which could be useful for conditional breaking. This signals a
no-debug-variablescondition when the code-location's debug-function has no debug-variable information available. The returned function takes a frame as an argument. See also
eval-in-frame.
This function returns a debug-function that represents debug information for
function.
This function returns the kind of function
debug-functionrepresents. The value is one of the following:
- :optional
- This kind of function is an entry point to an ordinary function. It handles optional defaulting, parsing keywords, etc.
- :external
- This kind of function is an entry point to an ordinary function. It checks argument values and count and calls the defined function.
- :top-level
- This kind of function executes one or more random top-level forms from a file.
- :cleanup
- This kind of function represents the cleanup forms in an unwind-protect.
- nil
- This kind of function is not one of the above; that is, it is not specially marked in any way.
This function returns the Common Lisp function associated with the
debug-function. This returns
nilif the function is unavailable or is non-existent as a user callable function object.
This function returns the name of the function represented by
debug-function. This may be a string or a cons; do not assume it is a symbol.
Debug-blocks contain information pertinent to a specific range of code in a debug-function.
This macro executes each
formin a context with
code-varbound to each code-location in
debug-block. This returns the value of executing
result(defaults to
nil).
This function returns the list of possible code-locations where execution may continue when the basic-block represented by
debug-blockcompletes its execution.
This function returns whether
debug-blockrepresents elsewhere code. This is code the compiler has moved out of a function's code sequence for optimization reasons. Code-locations in these blocks are unsuitable for stepping tools, and the first code-location has nothing to do with a normal starting location for the block.
A breakpoint represents a function the system calls with the current frame when execution passes a certain code-location. A break point is active or inactive independent of its existence. They also have an extra slot for users to tag the breakpoint with information.
This function creates and returns a breakpoint. When program execution encounters the breakpoint, the system calls
hook-function.
hook-functiontakes the current frame for the function in which the program is running and the breakpoint object.
whatand
kinddetermine where in a function the system invokes
hook-function.
whatis either a code-location or a debug-function.
kindis one of
:code-location,
:function-start, or
:function-end. Since the starts and ends of functions may not have code-locations representing them, designate these places by supplying
whatas a debug-function and
kindindicating the
:function-startor
:function-end. When
whatis a debug-function and
kindis
:function-end, then hook-function must take two additional arguments, a list of values returned by the function and a function-end-cookie.
infois information supplied by and used by the user.
function-end-cookieis a function. To implement function-end breakpoints, the system uses starter breakpoints to establish the function-end breakpoint for each invocation of the function. Upon each entry, the system creates a unique cookie to identify the invocation, and when the user supplies a function for this argument, the system invokes it on the cookie. The system later invokes the function-end breakpoint hook on the same cookie. The user may save the cookie when passed to the function-end-cookie function for later comparison in the hook function.
This signals an error if
whatis an unknown code-location.
Note: Breakpoints in interpreted code or byte-compiled code are not implemented. Function-end breakpoints are not implemented for compiled functions that use the known local return convention (e.g. for block-compiled or self-recursive functions.)
This function causes the system to invoke the
breakpoint's hook-function until the next call to
deactivate-breakpointor
delete-breakpoint. The system invokes breakpoint hook functions in the opposite order that you activate them.
This function stops the system from invoking the
breakpoint's hook-function.
This returns whether
breakpointis currently active.
This function returns the
breakpoint's function the system calls when execution encounters
breakpoint, and it is active. This is
SETF'able.
This function returns
breakpoint's information supplied by the user. This is
SETF'able.
This function returns the
breakpoint's kind specification.
This function returns the
breakpoint's what specification.
This function frees system storage and removes computational overhead associated with
breakpoint. After calling this,
breakpointis useless and can never become active again.
Code-locations represent places in functions where the system has correct information about the function's environment and where interesting operations can occur—asking for a local variable's value, setting breakpoints, evaluating forms within the function's environment, etc.
Sometimes the interface returns unknown code-locations. These represent places in functions, but there is no debug information associated with them. Some operations accept these since they may succeed even with missing debug data. These operations' argument is named
basic-code-locationindicating they take known and unknown code-locations. If an operation names its argument
code-location, and you supply an unknown one, it will signal an error. For example,
frame-code-locationmay return an unknown code-location if someone interrupted Lisp in the given frame. The system knows where execution will continue, but this place in the code may not be a place for which the compiler dumped debug information.
This function returns the debug-function representing information about the function corresponding to the code-location.
This function returns the debug-block containing code-location if it is available. Some debug policies inhibit debug-block information, and if none is available, then this signals a
no-debug-blockscondition.
This function returns the number of top-level forms before the one containing
code-locationas seen by the compiler in some compilation unit. A compilation unit is not necessarily a single file, see the section on debug-sources.
This function returns the number of the form corresponding to
code-location. The form number is derived by walking the subforms of a top-level form in depth-first order. While walking the top-level form, count one in depth-first order for each subform that is a cons. See
form-number-translations.
This function returns
code-location's debug-source.
This function returns whether
basic-code-locationis unknown. It returns
nilwhen the code-location is known.
This function returns whether the two code-locations are the same.
Debug-sources represent how to get back the source for some code. The source is either a file (
compile-fileor
load), a lambda-expression (
compile,
defun,
defmacro), or a stream (something particular to CMUCL,
compile-from-stream).
When compiling a source, the compiler counts each top-level form it processes, but when the compiler handles multiple files as one block compilation, the top-level form count continues past file boundaries. Therefore
code-location-top-level-form-offsetreturns an offset that does not always start at zero for the code-location's debug-source. The offset into a particular source is
code-location-top-level-form-offsetminus
debug-source-root-number.
Inside a top-level form, a code-location's form number indicates the subform corresponding to the code-location.
This function returns an indication of the type of source. The following are the possible values:
- :file
- from a file (obtained by compile-file if compiled).
- :lisp
- from Lisp (obtained by compile if compiled).
- :stream
- from a non-file stream (CMUCL supports compile-from-stream).
This function returns the actual source in some sense represented by debug-source, which is related to
debug-source-from:
- :file
- the pathname of the file.
- :lisp
- a lambda-expression.
- :stream
- some descriptive string that's otherwise useless.
This function returns the universal time someone created the source. This may be
nilif it is unavailable.
This function returns the time someone compiled the source. This is
nilif the source is uncompiled.
This returns the number of top-level forms processed by the compiler before compiling this source. If this source is uncompiled, this is zero. This may be zero even if the source is compiled since the first form in the first file compiled in one compilation, for example, must have a root number of zero—the compiler saw no other top-level forms before it.
These two functions provide a mechanism for converting the rather obscure (but highly compact) representation of source locations into an actual source form:
This function returns the file position of each top-level form as a vector if
debug-sourceis from a
:file. If
debug-source-fromis
:lispor
:stream, or the file is byte-compiled, then the result is
nil.
This function returns a table mapping form numbers (see
code-location-form-number) to source-paths. A source-path indicates a descent into the top-level-form
form, going directly to the subform corresponding to a form number.
tlf-numberis the top-level-form number of
form.
This function returns the subform of
formindicated by the source-path.
Formis a top-level form, and
pathis a source-path into it.
Contextis the number of enclosing forms to return instead of directly returning the source-path form. When
contextis non-zero, the form returned contains a marker,
#:****HERE****, immediately before the form indicated by
path.