Next Prev Up Top Contents Index

trace

Macro
Summary

Invoke the Common Lisp tracing facility on the named functions.

Package

common-lisp

Signature

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 )
Arguments

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.

dspec

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).

tracing-desc

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:

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

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.

Description

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, then invoking the function foo by

(funcall (symbol-function 'foo) ...)

will not produce any trace output.

Note: for detailed information about the current tracing state, call tracing-state.

Example 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
Example 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 >
Example 3

To trace a method:

(defmethod foo (x) x) 
(trace ((method foo (t))))
Example 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
*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*
tracing-state
untrace

LispWorks Reference Manual - 25 Jul 2003

Next Prev Up Top Contents Index