All Manuals > LispWorks® User Guide and Reference Manual > 33 The COMMON-LISP Package

trace Macro

Summary

Invoke the Common Lisp tracing facility on the named functions.

Package

common-lisp

Signature

trace {tracing-desc}* => trace-result

tracing-desc ::= function-name | complex-tracing-desc

complex-tracing-desc ::= (function-dspec {trace-keyword form}*)

function-name ::= symbol | (setf symbol)

Arguments
tracing-desc
Specifies the function definition that is to be traced and specifies any additional options that are required.
function-name
A symbol whose symbol-function is to be traced, or a setf function name. Functions, macros and generic functions may be specified this way.
function-dspec
A function-dspec as described in 7.5.1 Function dspecs, which apart from symbols, can specify methods, setf functions and subfunctions.
trace-keyword
One of :after, :allocation, :before, :backtrace, :eval-after, :eval-before, :break, :break-on-exit, :entrycond, :exitcond, :inside, :process, :trace-output, :step or :when.
form
A form.
Values
trace-result
A list of traced dspecs.
Description

The macro trace invokes the tracing facility (see 5 The Trace 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.

Each tracing-desc specifies a function (or a macro or a method) to be traced via function-name or function-dspec. 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.

Each trace-keyword is followed by a form with a specific meaning, as described next.

: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:

:quick
Like the :bq debugger command.
t
Like the :b debugger command.
:verbose
Like the :b :verbose debugger command.
:bug-form
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.

Values
trace-result
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.
Notes

For detailed information about the current tracing state, call tracing-state.

For information about problems with tracing and their resolution, see 5.7 Troubleshooting tracing.

Examples: 1
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
Examples: 2

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 > 
Examples: 3

To trace a method:

(defmethod foo (x) x) 
(trace ((method foo (t))))
Examples: 4

To trace a setf function:

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
See also

trace in the Common Lisp HyperSpec
5 The Trace Facility
*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 - 01 Dec 2021 19:30:30