This minitutorial discusses several topics:
On your way to becoming a skilled Lisp "Hacker" you have the feeling that
there must be a better way to debug you programs than by placing
(break) and (print .. ) scattered about through your code.
After all if MCL can provide all the functionality it does for ~$500.00 (
including trace ) ,
surely there should be some more functionality I
can eek out of the trace facility in LCL ( ~$1500 ) .
If not. I might as well use DTRACE from Touretzky's book, right?
[ Or else maybe by a Mactinosh JUST to write Lisp programs ... don't laugh
this has happened. ]
Alas the trace macro in LCL does have a bunch of "Whiz Bang" options.
Shamelessly, extracting the Macro description from the LCL documentation.
( OIT should have the manual somewhere. I think it is OIT-66 )
trace
Purpose: The macro trace allows you to trace one or more function and to
perform certain actions at the time a function is called or at
the time it returns. It returns as its value a list of
names of all the functions it has traced.
Syntax: trace { trace-spec}* [Macro ]
trace-spec::= function-name |
( {function-name | ( {function-name}+)}
{keyword form}* )
keyword::= :cond
| :entrycond
| :exitcond
| :break
| :exitbreak
| :entry
| :exit
| :step
Remarks You can specify the following keyword-values pairs to trace:
- :cond form
-
If form has a non-nil value, this keyword argument displays
the
the trace output. This keyword argument overrrides the
:exitcond and :entrycond arguments, if the value of this argument
is nil. no trace information is displayed. The default value of
form is non-nil.
- :entrycond form
-
If from has a non-nil value, this keyword argument displayes tracing
information on entry to the traced function. The default value of
form is non-nil.
- :exitcond form
-
If from has a non-nil value, this keyword argument displayes tracing
information on exit from the traced function. The default value of
form is non-nil.
- :break form
-
If from has a non-nil value, this keyword argument calls the Debugger
after the entry trace information his printed but before the traced
function is applied to its arguments. The default value of
form is nil.
- :exitbreak form
-
If from has a non-nil value, this keyword argument calls the Debugger
after the traced function has been executed and the exit trace
information has been printed but before control returns.
The default value of form is nil.
- :entry ( {form}+ )
-
This keyword arguemtn dispalys the values of the forms in the list
on entry to the traced function. The displayed values are preceded
by two backslashes (\\).
- :exit ( {form}+ )
-
This keyword arguemtn dispalys the values of the forms in the list
on entry to the traced function. The displayed values are preceded
by two backslashes (\\).
- :step form
-
If form is non-nil, this keyword aruments calls the Stepper on the
traced function. The Stepper allow you to interactively step through
the evaluation of a function: it is described in the section
"The Stepper" The default value of form is nil.
If a function is already being traced , trace calls untrace before starting
the new trace. Calling untrace restores all functions to their normal state.
First we'll need a function to trace. How about our old friend fact?
> (defun fact (num )
(declare (notinline fact))
(if (= num 0 )
1
(* num (fact (- num 1 )))))
FACT
> (trace fact)
NIL
Now if you enter (fact 4 ) you'll see the familiar trace of
fact.
However we would like to try out some of the more fancy options.
For instance:
> (trace (fact :exitcond nil ))
> (fact 4 )
or
> (trace ( fact :break t ))
> (fact 4 )
or
> (trace ( fact :entry (*trace-arglist*)))
or how about
> (trace (fact :break (evenp (first *trace-arglist*))))
> (fact 4 )
The variable *trace-arglist* always contains the arguments to the function
being traced.
From the trace specification you can either turn stepping on full time. Or
if the form provided to step is a predicate then the stepper will only turn
on when the predicate is true.
> (trace (fact :step (= 2 (first *trace-arglist*))))
Will only drop into the stepper once you reach (fact 2 ).
You think of more examples of your own. If you haven't already you
should try out the minitutorial on Stepping and the debugger.
Back to LCL and Tool Time
Last modified: by Lyman S. Taylor(lyman@cc.gatech.edu)