trace { function-name | tracing-desc }* => trace-result
tracing-desc
::= (
dspec
{
keyword
form
}*)
dspec ::= function-name |
(method generic-function-name [qualifier ] (class* ))
keyword ::= :after| :allocation | :before | :backtrace |
:eval-after | :eval-before | :break |
:break-on-exit | :entrycond | :exitcond |
:inside | :process | :trace-output | :step |
:when
qualifier
::= :after | :before | :around
function-name
::=
symbol
| (setf
symbol
)
A symbol whose symbol-function is to be traced, or a setf function name. Functions, macros and generic functions may be specified this way.
Specifies the functional definition which is to be traced. This either has the same form as above, or specifies a method by the name of its generic function and by a list of classes to specialize the arguments to the method. In this latter case the list of classes must correspond exactly to the classes of the specialized parameters of an existing method, and then only this method is traced (as opposed to the corresponding generic function).
Specifies the functional definition which is to be traced and specifies any additional options that are required.
:after
is followed by a list of forms; these are evaluated upon returning from the function. The values of these forms are also printed out by the tracer. The forms are evaluated after printing out the results of the function call, and if they modify
hcl:*traced-results*
then the values received by the caller of the function are correspondingly altered (see also
hcl:*traced-results*
).
:allocation
-- if non-
nil
, the memory allocation made during a function-call is printed upon exit from the function. This allocation is counted in bytes. If it is any other symbol (except
nil
),
trace
uses the symbol to accumulate the amount of allocation made between entering and exiting the function. Upon exit from the function, the symbol contains the number of bytes allocated during the function-call. For example,
(trace (print :entrycond nil
:exitcond nil
:allocation $$print-allocation))
results in
$$print-allocation
containing the sum of the allocation made inside
print
.
Note that if the function is called again,
trace
continues to use
$$print-allocation
as an accumulator of memory allocation. It adds to the present value rather than re-initializing it each time the function is called.
:backtrace
generates a backtrace on each call to the traced function. It is followed by a keyword that can be any of the following values:
Like the
:bq
debugger command.
Like the
:b
debugger command.
Like the
:b :verbose
debugger command.
Like the
:bug-form
debugger command.
:before
is followed by a list of forms; these are evaluated upon entering the function and their values are printed out by the tracer. The forms are evaluated after printing out the arguments to the function, and if they alter
hcl:*traced-arglist*
then the values received by the body of the function are changed accordingly (see also *traced-arglist*).
:eval-after
and
:eval-before
are similar to
:after
and
:before
, without output.
:break
is followed by a form. This is evaluated after printing the standard information caused by entering the function, and after executing any
:before
forms; if it returns
nil
then tracing continues normally, otherwise
break
is called. This provides a way of entering the debugger through the tracer.
:break-on-exit
is followed by a form. This is evaluated after printing the standard information caused by returning from the function, and before executing any
:after
forms; if it returns
nil
then tracing continues normally, otherwise
break
is called. This provides a second way of entering the debugger through the tracer.
:entrycond
controls the printing of the standard entry message (including the function's arguments). If the form following it evaluates to give a non-
nil
value when the function is entered, then the entry message is printed (but otherwise it is not). If this option is not present then the standard entry message is always printed upon calling the function. See also the
:when
option.
:exitcond
controls the printing of the standard exit message (including the function's results). If the form following it evaluates to give a non-
nil
value when the function is exited, then the exit message is printed (but otherwise it is not). If this option is not present then the standard exit message is always printed upon returning from the function. See also the
:when
option.
:inside
restricts the tracing to within one of the functions given as an argument. A single symbolic function name is treated as a list of one element, i.e.
:inside format
is equivalent to
:inside (format)
.
:process
may be used to restrict the tracing to a particular process. If it is followed by a process then the function is only traced when it is invoked from within that process. If it is followed by
t
then it is traced from all processes -- this is the default. In any other cases the function is not traced at all.
:trace-output
should be followed by a stream. All the output from tracing the function is sent to this stream. By default output from the tracer is sent to
*trace-output*
. Use of this argument allows you to dispatch traced output from different functions to different places.
:step
, when non-
nil
, invokes the stepper (for evaluated functions).
:when
overrides all other keywords. It is followed by an expression, and tracing only occurs when that expression evaluates to non-
nil
. It is useful if you want to combine
:entrycond
and
:exitcond
.
If
trace
is called with no arguments then it returns a list of the names of all the functions currently being traced. When called with one or more arguments, it returns the symbols of the functions specified in those arguments.
trace
is the macro used to invoke the tracing facility. This is a useful debugging tool that enables information about selected calls to be generated by the system. The standard way of invoking
trace
is to call it with the names of the functions, macros and methods that are to be monitored in this way. Calls to these produce a record of the function that was called, the arguments it received and the results it produced.
The arguments to
trace
each specify a function (or a macro or a method) to be traced. They may also contain further instructions to control how the tracing output is displayed, or to cause particular actions to occur when the functions is called or exited. If
trace
is called with a function that is already being traced, then the new tracing specification for that function replaces the old version.
Note:
trace
works by tracing function names, not function objects. Therefore tracing function objects, for example by
(trace #'foo)
will not yield any trace output. Also, if the symbol
foo
is traced, invoking the function
foo
by
(funcall (symbol-function 'foo) ...)
USER 1 > (defvar *number-of-calls-to-max* 0)
*NUMBER-OF-CALLS-TO-MAX*
USER 2 > (trace (max :after
((incf *number-of-calls-to-max*))))
(MAX)
USER 3 > (dotimes (i 2) (max i 1))
0 MAX > (0 1)
0 MAX < (1)
1
0 MAX > (1 1)
0 MAX < (1)
2
NIL
USER 4 > *number-of-calls-to-max*
2
USER 5 > (trace (max
:entrycond
(> (length compiler:*traced-arglist*)
2)
:exitcond nil))
(MAX)
USER 6 > (max 2 3 (max 4 5))
0 MAX > (2 3 5)
5
This example illustrates the use of
:inside
.
CL-USER 2 > (defun outer ()
(inner))
OUTER
CL-USER 3 > (defun inner ()
10)
INNER
CL-USER 4 > (trace (inner :inside outer))
;; only trace when inside OUTER
(INNER)
CL-USER 5 > (inner)
;; no tracing occurs since we are not inside OUTER
10
CL-USER 6 > (outer) ;; INNER is traced inside OUTER
0 INNER > NIL
0 INNER < (10)
10
CL-USER 7 >
CL-USER 56 > (defvar *a* 0)
*A*
CL-USER 57 > (defun (setf foo) (x y) (set y x))
(SETF FOO)
CL-USER 58 > (trace (setf foo))
((SETF FOO))
CL-USER 59 > (setf (foo '*a*) 42)
0 (SETF FOO) > (42 *A*)
>> X : 42
>> Y : *A*
0 (SETF FOO) < (42)
42
*disable-trace*
*max-trace-indent*
*trace-indent-width*
*trace-level*
*trace-print-circle*
*trace-print-length*
*trace-print-level*
*trace-print-pretty*
*trace-verbose*
*traced-arglist*
*traced-results*
untrace