trace {function-name|tracing-desc}* => trace-result
tracing-desc ::= (function-dspec {keyword form}*)
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.
A function-dspec as described in Function dspecs, which apart from symbols, can specify methods, setf
functions and subfunctions.
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 *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. For example, :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.
For detailed information about the current tracing state, call tracing-state.
For information about problems with tracing and their resolution, see Troubleshooting tracing.
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-new-instances-on-access
trace-on-access
*trace-output*
*trace-print-circle*
*trace-print-length*
*trace-print-level*
*trace-print-pretty*
*trace-verbose*
*traced-arglist*
*traced-results*
tracing-enabled-p
tracing-state
untrace
LispWorks User Guide and Reference Manual - 20 Sep 2017