|
Allegro CL version 11.0 |
This document is based on a design document prepared by Hans Muller, Cris Perdue, Dave Morein, all (at the time they wrote it) of Sun Microsystems. Many of their suggestions have been included in the Allegro CL debugger.
This document describes many of the internals of the Allegro CL debugger. (The standard interface to the debugger is described in debugging.html.) While most users will have no need to concern themselves with debugger internals, certain application writers may wish to make use of the information in this document to facilitate error handling and debugging in applications.
Note that the symbols naming functions, variables, etc. in this document do not have their own description pages. All relevant documentation is in this document. All symbols are in the debugger
package (nicknamed debug
). Some are present in any image that contains the debugger. Others are only present when (require :sundebug)
is evaluated (loading the sundebug
module). If you intend to use these functions, be sure to evaluate
(require :sundebug)
If you are building an application using these functions, be sure the :sundebug
is included.
This document specifies a set of functions that form the foundation for the debugger and inspector.
Many of the functions in this module take a frame-descriptor as an argument. For a variety of reasons, not everything that looks like a frame descriptor is actually valid. You can use frame-reference-eq. to test the validity of a frame descriptor. It is recommended you validate frame desciptors with that function prior to passing them to the various other functions.
A frame in this specification represents an event in Lisp execution which is recorded on the stack. The function frame-type permits testing as to what a frame represents. The types of frames include
:function
: A compiled or interpreted function application.:eval
: The frame where evaluation of an s-expression starts.:interpreter
: An interpreter frame (for which frame-interpreter-p is true).:binding
: The frame where variable binding starts.:catch
: Either an interpreted or compiled catch frame.:special-form
: The frame where evaluation of a special operator starts (the frame name comes from the old term for special operators).Binding frames corresponding to binding events which are not associated directly with function invocation. For example, interpretation of LET and LET* forms would be represented as binding frames. In-line lambda expressions, such as
((let ((x 2) (y 3)) (foo x y)))
are represented as :binding frames.
The following frame interface functions apply to both compiled and interpreted function frames:
When a frame is passed in as an argument to one of these functions, the interpreted lexical environment of the frame is accessed if the frame represents the interpretation of an s-expression; otherwise, the compiled lexical environment of the frame is accessed.
The stack frame filter is a mechanism that can be used by the programmer to customize the presentation of the stack backtrace. The filter will elide frames based on frame type and, if the frame represents a function application, the function package or function name. Sometimes it is desirable to hide all of the functions in some package except a few important ones. An exception can be created by unhiding a function whose home package is hidden.
The top-level commands :hide and :unhide provide the user interface to frame filtering and use these functions.
The function frame-visible-p is used to determine if a frame is to be displayed or not.
function, package: debug
Arguments: &rest package-names
This function makes the specified packages (the names are typically keywords) invisible, meaning they will not be displayed in stack backtraces (unless all frames are displayed, see the :all
argument to :zoom). If no arguments are supplied then this function returns a list of all of the hidden packages.
function, package: debug
Arguments: &rest package-names
Similar to hide-packages except this function makes internal symbols the specified packages (the names are typically keywords) invisible, rather than all symbols. If no arguments are supplied then this function returns a list of all of the hidden packages where internals are hidden.
function, package: debug
Arguments: &rest functions
This function makes the specified functions invisible, meaning they will not be displayed in stack backtraces (unless all frames are displayed, see the :all
argument to :zoom). If no arguments are supplied then this function returns a list of all of the hidden functions.
function, package: debug
Arguments: &rest frame-types
This function makes the specified frame types invisible, meaning they will not be displayed in stack backtraces (unless all frames are displayed, see the :all
argument to :zoom). See frame-type for a list of frame types. If no arguments are supplied then this function returns a list of all of the hidden frame-types.
function, package: debug
Arguments: &rest package-names
This function makes the specified packages visible, meaning they will be displayed in a backtrace even when it is not displaying all frames (see the :all
argument to :zoom). If no arguments are supplied then this function makes all packages visible.
function, package: debug
Arguments: &rest package-names
Similar to unhide-packages except this function makes internal symbols the specified packages (the names are typically keywords) visible, rather than all symbols. If no arguments are supplied then this function makes the internals of all packages visible.
function, package: debug
Arguments: &rest functions
This function makes the specified functions visible, meaning they will be displayed in a backtrace even when it is not displaying all frames (see the :all
argument to :zoom). If no arguments are supplied then this function makes all functions visible.
function, package: debug
Arguments: &rest types
This function makes the specified types of stack frames visible, meaning they will be displayed in a backtrace even when it is not displaying all frames (see the :all
argument to :zoom). If no arguments are supplied then this function makes all types of stack frames. See frame-type for a list of frame types.
function, package: debug
Arguments: frame
Returns true or nil
as frame is visible (i.e. not hidden) or not (i.e. hidden). This function tests a frame with the following algorithm:
- If the frame-type for this frame is hidden then return NIL.
- If the frame-type for this frame is :function then
- If this function has been hidden then return NIL
- If (this function's package has been hidden AND
this function has NOT been :unhidden) then return NIL
- Otherwise return T
function, package: debug
Arguments:
The window debugger must be informed whenever the filter (i.e. what is and is not hidden) parameters are changed so that it can update the backtrace display. This function returns the function that is called after any change has been made to the frame filter parameters, i.e. when one of the hide- and unhide- (i.e hide-packages, hide-functions, hide-frames, unhide-packages, unhide-functions, and unhide-frames) functions has been called. The value returned by this function can be changed with setf. The function returned by this function could be defined like this:
(my-frame-filter-hook name args)
Where name is a keyword that represents the hide/unhide filter function that was called and args is the list of arguments passed to the filter function.
Stack frames are referred to by "frame descriptors" (also known as "frame references"), which are implemented as structs. Descriptors may be compared with frame-reference-eq. Descriptors must not be modified or generated inside of these functions. For all practical purposes, frame descriptors behave like pointers. A frame descriptor contains information identifying the process or thread it is referring to.
The term "variables" in this document includes both parameters and other local variables. Where an index argument is specified in frame variable access primitives, it is assumed to be zero-based. It is permissible to change the order by which parameters and other locals are accessed by frame-var-value. Frame variables are enumerated starting with requireds, then optionals, then extra-args, then the rest arg, then keywords, then locals, which may also include closed-over variables. Whether a keyword is supplied or not depends on whether it was given as an argument.
Note that some variables may be shown but not bound, and the values of some variables may be out of date because of compiler optimizations.
function, package: debug
Arguments: value
Some functions which return LISP values can possibly fail in such a way that it is known that the information requested is not retrievable. To cover this eventuality, this predicate and none-p have been defined. In this document UNKNOWN refers to an implementation-specific value which indicates that the answer to a query made through one of the functions in this interface is unknown, but that it may exist. NONE refers to an implementation-specific value which indicates that the answer to a particular query does not exist. The actual values of UNKNOWN and NONE are never directly accessed or manipulated by debugger tools. Instead, their presence is detected using this predicate and none-p.
The functions which may return these values include:
function, package: debug
Arguments: value
Some functions which return LISP values can possibly fail in such a way that it is known that the information requested is not retrievable. To cover this eventuality, this predicate and unknown-p have been defined. In this document UNKNOWN refers to an implementation-specific value which indicates that the answer to a query made through one of the functions in this interface is unknown, but that it may exist. NONE refers to an implementation-specific value which indicates that the answer to a particular query does not exist. The actual values of UNKNOWN and NONE are never directly accessed or manipulated by debugger tools. Instead, their presence is detected using this predicate and unknown-p.
The functions which may return these values include:
function, package: debug
Arguments:
The function break-hook returns the current value of the break hook variable (excl::*break-hook*
), and (setf (break-hook) value)
sets the break hook to value
. The semantics of the break hook variable are:
When this variable is null, and a break or error occurs (whether internally or externally generated), the break is processed in the LISP's usual manner.
When it is not null, it should be a function object and, upon a break or error, is FUNCALLed with the following argument list:
Arguments frame-descriptor source continue-format-string args condition
The arguments of the function are as follows:
:break
, :error
, :warn
, etc., depending upon where the break originated.nil
. If it is not null, then the rest of the arguments to the break hook function are assumed to have the same meaning which they would have to cerror. If continue-format-string is nil
, then the error is not assumed to be continuable, and args are processed as if they were passed in from a break, error, or warn. condition is the condition signaled.After gaining control, the debugger will adjust the state of its screen display, output the error message, output the continue message (for continuable errors), and then call excl::read-eval-print-loop (an internal function that implements the standard read-eval-print-loop) or read-eval-in-context-print-loop if it's available.
function, package: debug
Arguments: frame-descriptor
This function allows easy identification of "bogus" frame references. It returns a non-nil
value if and only if frame-descriptor refers to a LISP stack frame. If possible, this is an exact answer. If not possible, then this function at least performs some rudimentary range checking on frame-descriptor to reject pointers which are clearly wrong.
function, package: debug
Arguments: r1 r2
Returns non-nil
if and only if the stack frame corresponding to r1 is the same as the stack frame corresponding to r2.
function, package: debug
Arguments: &optional process visible-only-p
Returns a reference to the oldest frame on the stack corresponding to process. If process is not supplied, then it defaults to the process of the caller. If visible-only-p is true, the oldest frame that is not hidden is found.
function, package: debug
Arguments: &optional process visible-only-p
Returns a reference to the newest frame on the stack corresponding to process. If process is not supplied, then it defaults to the process of the caller. If visible-only-p is true, the newest frame that is not hidden is found.
function, package: debug
Arguments: &optional stack-group
Returns a reference to the most recent break frame, that is, the frame which called the current invocation of the debugger in the stack corresponding to stack-group. If stack-group is not supplied, then it defaults to the stack group of the caller. This function, as well as oldest-frame, return valid results at any time after the break hook function object gains control.
function, package: debug
Arguments: frame-descriptor
This function returns the reference of frame called from frame frame-descriptor.
function, package: debug
Arguments: frame-descriptor
This function returns the reference of frame which called frame frame-descriptor.
function, package: debug
Arguments: frame-descriptor
This function returns the function name corresponding to frame frame-descriptor or NONE in the case of an anonymous lambda. If frame-descriptor is a binding frame, and a special operator can be associated with the frame (e.g. let, let*), then this function returns the name of the special operator. If frame-descriptor is an :eval
frame, then if the expression being evaluated is a function application, then this function returns the name of the function (if any), or NONE in the case of an anonymous lambda. If the expression being evaluated is atomic, then returns NONE.
If the function represents a runtime-system operation (an operation in the core or kernel of the lisp) then the name returned will be one of sys::..context-saving-runtime-operation
, sys::..lisp-breakpoint-runtime-handler
, or sys::..runtime-operation
.
If frame-descriptor points to an invalid frame, this function signals an error. You can check whether a frame is valid with frame-reference-p.
function, package: debug
Arguments: frame-descriptor
This function returns the type of the frame frame-descriptor. The types of frames are:
:function
: A compiled or interpreted function application.:eval
: The frame where evaluation of an s-expression starts.:interpreter
: An interpreter frame (for which frame-interpreter-p is true).:binding
: The frame where variable binding starts.:special-form
: The frame where evaluation of a special operator starts (the frame name comes from the old term for special operators).function, package: debug
Arguments: frame-descriptor
Returns non-nil
if and only if the frame referred to by frame-descriptor corresponds to part of the internal mechanism of the interpreter.
function, package: debug
Arguments: frame-descriptor
Returns a non-nil
value if and only if there exists an interpreted environment corresponding to frame-descriptor. This would normally be true for those :function
frames which represent applications of interpreted functions, and for :binding
frames which represent interpretation of let and similar forms.
function, package: debug
Arguments: frame-descriptor
Returns the total number of variables in the frame referred to by frame-descriptor, including all parameters and other local variables. This function is used by the debugger to obtain a legal bound for parameter n in its calls to frame-var-name, and frame-var-type.
function, package: debug
Arguments: frame-descriptor n
Gets or sets with setf the value of variable number n in stack frame frame-descriptor. n refers to the variable number and could refer either to a parameter or to another local variable.
function, package: debug
Arguments: frame-descriptor n
Returns the name of variable n in stack frame frame-descriptor. If variable n has no name, then a value which satisfies NONE-P is returned. If variable n is known to have a name, but it cannot be retrieved, then a value which satisfies UNKNOWN-P is returned.
function, package: debug
Arguments: frame-descriptor n
Returns the "type" of a variable n in stack frame frame-descriptor. The set of variable types expected, with associated meanings is:
:required
: a required parameter.:optional
: an optional parameter.:keyword
: a keyword parameter.:local
: a local variable allocated on the frame.:rest
: a rest parameter.:extra-arg
: an argument in excess of the number of allowed arguments (improperly) supplied to a function which does no argument count checking.If the type cannot be determined, then a value of NONE is returned.
function, package: debug
Arguments: frame-descriptor
This function returns the expression being evaluated by the interpreter in the frame corresponding to frame-descriptor, which must be an :eval
frame.
If frame-descriptor points to an invalid frame, this function signals an error. You can check whether a frame is valid with frame-reference-p.
function, package: debug
Arguments: frame-descriptor
Returns the actual arguments passed the frame referred to by frame-descriptor.
If frame-descriptor points to an invalid frame, this function signals an error. You can check whether a frame is valid with frame-reference-p.
function, package: debug
Arguments: frame-descriptor function &rest actuals
Retries the frame referred to by frame-descriptor, invoking the supplied function and using actuals as arguments. There is no default way to use the frame's existing arguments; to use the existing arguments, use frame-get-actuals to supply the current arguments. If unable to retry the frame, then a value of nil
is returned. Note that the function referenced in the frame is not looked at.
function, package: debug
Arguments: frame-descriptor &rest values
This function returns one or more values from the frame referred to by frame-descriptor. The form of the command is
(frame-return frame value1 value2 ... valuen)
If function A calls B with args C and D,
(defun A (x y) ... (B C D) ...)
and breaks, we would like to say
(frame-return "B" 'E))
This cuts the stack back to "B" and returns 'E to the caller of "B" [in this case, to "A"] If this function fails, it returns 2 values: nil
and an error message which explains why it failed. Note: the error message is not output, just returned.
If frame-descriptor points to an invalid frame, this function signals an error. You can check whether a frame is valid with frame-reference-p.
function, package: debug
Arguments: frame-descriptor
Returns non-nil
if frame-return will succeed if applied to frame-descriptor. nil
is returned if the frame is not valid (see frame-reference-p).
function, package: debug
Arguments: frame-descriptor
Returns non-nil
if frame-retry will succeed if applied to frame-descriptor. nil
is returned if the frame is not valid (see frame-reference-p).
function, package: debug
Arguments: frame-descriptor
Returns non-nil
if and only if the frame referred to by frame-descriptor is a valid context for eval-form-in-context.
function, package: debug
Arguments: frame-descriptor
Returns the formal parameter list for the frame corresponding to frame-descriptor, or :unknown
if this cannot be determined.
function, package: debug
Arguments: frame-descriptor
Returns a best-guess at the list of actual arguments to the function frame corresponding to frame-descriptor. It may be wrong in that optional arguments which weren't passed in by the user will be returned.
If frame-descriptor points to an invalid frame, this function signals an error. You can check whether a frame is valid with frame-reference-p.
function, package: debug
Arguments: frame-descriptor
This function tries to find the source for the function for the frame frame-descriptor, reading the source file and returning a copy of the source as its value. If source-file recording is not turned on (see source-file-recording.html), or if the source cannot otherwise be determined, nil
is returned.
If frame-descriptor points to an invalid frame, this function signals an error. You can check whether a frame is valid with frame-reference-p.
function, package: debug
Arguments: &optional process
Returns the current debugger break level of process (the current process, which is the value of *current-process*, if unsupplied). Break level 0 corresponds to normal operation (no break).
function, package: debug
Arguments: &optional process n break-level
Pops control to the previous break or the top level of process process (the current process, which is the value of *current-process*, if unsupplied). If n is specified and greater than 1, then multiple levels are popped. In case of an error, this routine returns nil
, although, if it returns at all, something has to be wrong. This function returns nil
if an attempt was made to pop past the top-level.
break-level is the number of break-levels in the process to be popped from. If not given, it is calculated. When break-level is one (the target process is at break-level 0) a process-reset is done instead of a debug-pop on that process.
function, package: debug
Arguments: &optional process
Unwinds the stack of process process (the current process, which is the value of *current-process*, if unsupplied) to top-level. Returns nil
and an error message string in the case of an unrecoverable error.
function, package: debug
Arguments: &optional process &rest args
Continues from the most recent error (which must be continuable) of process process (the current process, which is the value of *current-process*, if unsupplied). Returns the values nil
and an error message string if the error cannot be continued.
function, package: debug
Arguments: &optional process
Returns a string that corresponds to the message output by error. process is the process where the error occurred (the current process, which is the value of *current-process*, if unsupplied).
function, package: debug
Arguments: &optional process
returns the message that was generated from the continue-format-string to cerror argument (if any). process is the process where the error occurred (the current process, which is the value of *current-process*, if unsupplied).
function, package: debug
Arguments: &optional process
Returns non-nil
if and only if there is a "most recent error", and it is continuable. This function could be defined like this:
(defun error-continuable-p ()
(most-recent-continuable-error-string))
process is the process where the error occurred (the current process, which is the value of *current-process*, if unsupplied).
function, package: debug
Arguments:
Similar to excl::read-eval-print-loop, this function evaluates with respect to an environment. The environment is set separately via the set-context function.
function, package: debug
Arguments: frame-descriptor
Returns the function object associated with frame frame-descriptor.
If frame-descriptor points to an invalid frame, this function signals an error. You can check whether a frame is valid with frame-reference-p.
function, package: debug
Arguments: frame-descriptor &key function
Returns a form that attempts to reproduce the call to frame frame-descriptor, if possible. Some of the elements of the form may contain unknowns if argument saving is turned off. If function is true, then a funcall-style form is returned, using the actual function object instead of trying to use its name in a normal lisp function call.
If frame-descriptor points to an invalid frame, this function signals an error. You can check whether a frame is valid with frame-reference-p.
function, package: debug
Arguments: dest frame-descriptor &optional mode func-style output-function
The return value is undefined; this function is called for its side effects. Prints a description of frame frame-descriptor in the desired mode to the stream dest. dest is a stream suitable as the :stream argument to write.
mode may be :brief, :moderate, or :verbose (see :brief, :moderate, and :verbose modes of :zoom in debugging.html).
If output-function is supplied, it must be a function of two arguments; the object that is being written, and the destination. The output-function is used only for brief or moderate modes; it is not used for verbose mode.
If func-style is non-nil
, then the function object is used instead of the name of the function.
If frame-descriptor points to an invalid frame, this function signals an error. You can check whether a frame is valid with frame-reference-p.
Where environment structs are returned by dynamic interface functions, the bindings shown are the current value of the bindings established by the frame which was passed in as an argument. An environment struct contains all necessary information to identify these bindings, possibly including CLtL2-style augmentable environment objects. An environment struct is denoted by environment in the descriptions below.
function, package: debug
Arguments: form &optional environment
Evaluates form from within the context of environment environment.
If the environment struct includes a compiled function's frame, then the compiled environment includes bindings for any variables whose names can be determined from local name info, or else dummy names are generated to identify each variable in the compiled function. An attempt is made to match the variable names within a compiled function to the names given to those variables by the disassembler.
If the environment struct contains an interpreted environment, then its bindings are used as well. If the form performs a setf or setq, the environment is changed if possible to reflect the setf or setq.
After the form is evaluated, the environments are restored, and the value returned from the form is returned.
function, package: debug
Arguments: frame-descriptor
Returns an environment struct as seen for frame reference frame-descriptor.
If frame-descriptor points to an invalid frame, this function signals an error. You can check whether a frame is valid with frame-reference-p.
function, package: debug
Arguments: environment
Returns a non-nil
value if and only if environment is an environment struct.
function, package: debug
Arguments: environment
Set the context for read-eval-in-context-print-loop. environment must be an environment struct. See get-context.
function, package: debug
Arguments: environment
Get the context for read-eval-in-context-print-loop. environment must be an environment struct. See set-context.
Copyright (c) Franz Inc. Lafayette, CA., USA. All rights reserved.
|
Allegro CL version 11.0 |