mirror of
https://github.com/PDP-10/its.git
synced 2026-01-13 15:27:28 +00:00
273 lines
11 KiB
Plaintext
Executable File
273 lines
11 KiB
Plaintext
Executable File
This file is the documentation for the Lisp Trace package. It is
|
|
admittedly out of date, but nonetheless better than nothing. Improve
|
|
it!
|
|
|
|
08/01/72
|
|
|
|
The Lisp Trace package consists of three main functions,
|
|
Trace, untrace, and remtrace, all of which are fexprs.
|
|
|
|
A call to Trace has the following form:
|
|
(Trace <Trace specs>)
|
|
a "Trace spec" in turn is either an atom (the name
|
|
of the function to be Traced) or a list of this form:
|
|
(<function name> <options>)
|
|
where the options are as follows:
|
|
|
|
Break <pred> causes a break after printing the entry
|
|
Trace (if any) but before applying the
|
|
Traced function to its arguments, if
|
|
and only if <pred> evaluates to non-nil.
|
|
|
|
Cond <pred> causes Trace information to be printed
|
|
for function entry and/or exit if and
|
|
only if <pred> evaluates to non-nil.
|
|
|
|
Entrycond <pred> causes Trace information to be printed for
|
|
function entry if and only if <pred> evaluates to
|
|
non-nil. If both cond and entrycond are used, the
|
|
<pred> specified for cond is evaluated first; and
|
|
both <pred>'s must evaluate to non-nil for
|
|
entry Trace information to be printed. If the
|
|
<pred> for cond evaluates to nil, then the <pred> for
|
|
entrycond will not be evaluated.
|
|
|
|
Exitcond <pred> causes Trace information to be printed for
|
|
function exit if and only if <pred> evaluates to
|
|
non-nil. If both cond and exitcond are used, both must
|
|
evaluate to non-nil for exit Trace information to be
|
|
printed. Note that the <pred> for cond is
|
|
not re-evaluated on exit; rather, its value on entry
|
|
is saved. If this value is nil, then the <pred>
|
|
for exitcond will not be evaluated.
|
|
|
|
Wherein <fn> causes the function to be Traced only
|
|
when called from the specified function.
|
|
One can give several Trace specs to Trace,
|
|
all specifying the same function but with
|
|
different wherein options, so that the
|
|
function is Traced in different ways when
|
|
called from different functions. Note that
|
|
if the function specified by the wherein
|
|
option is already being Traced itself, the
|
|
wherein option probably will not work as
|
|
desired, probably. (Then again, it might.)
|
|
Note that <fn> must be an interpreted function,
|
|
since the wherein Trace involves altering
|
|
the calling function as well as the called.
|
|
|
|
Argpdl <pdl> specifies an atom <pdl> whose value Trace
|
|
initially sets to nil. When the function is
|
|
Traced, a list of the current recursion
|
|
level for the function, the function's
|
|
name, and a list of the arguments is consed
|
|
onto the <pdl> when the function is entered,
|
|
and cdr'ed back off when the function is
|
|
exited. (Actually, this consing/cdring is done by
|
|
means of lambda-binding, so that if an error or
|
|
other interrupt occurs the <pdl> will be reset by
|
|
unbinding.) The <pdl> can be inspected from a
|
|
breakpoint, for example, and used to
|
|
determine the very recent history of the
|
|
function. This option can be used with or
|
|
without printed Trace output. Each function
|
|
can be given its own pdl, or one pdl may
|
|
serve several functions.
|
|
|
|
Entry <list> specifies a list of arbitrary s-expressions
|
|
whose values are to be printed along with
|
|
the usual entry Trace. The list of
|
|
resultant values, when printed, is preceded
|
|
by a \\ to separate them from the other
|
|
information.
|
|
|
|
Exit <list> similar to entry, but specifies expressions
|
|
whose values are printed with the exit Trace.
|
|
Again, the list of values printed
|
|
is preceded by \\.
|
|
|
|
Arg specify that the function's arguments,
|
|
value resultant value, both, or neither are to
|
|
both be Traced. If not specified, the default
|
|
nil is both. Any "options" following one of
|
|
these four are assumed to be arbitrary
|
|
s-expressions whose values are to be printed
|
|
on both entry and exit to the function.
|
|
However, if arg is specified, the values are
|
|
printed only on entry, and if value, only on
|
|
exit. Note that since arg, value, both, nil,
|
|
swallow all following expressions for this
|
|
purpose, whichever one is used should be the
|
|
last option specified. Any such values
|
|
printed will be preceded by a // and will
|
|
follow any values specified by entry or exit
|
|
options.
|
|
|
|
|
|
If the variable arglist is used in any of the expressions
|
|
given for the cond, break, entry, exit, or after-the-arg-
|
|
value-both-or-nil options, when those expressions are
|
|
evaluated the value of arglist will effectively be a list
|
|
of the arguments given to the Traced function. Thus
|
|
(Trace (foo break (null (car arglist))))
|
|
would cause a break in foo iff the first argument to
|
|
foo is nil. Similarly, the variable fnvalue will effectively
|
|
be the resulting value of the Traced function; since the value
|
|
of the function is of course available only on exit
|
|
from the function, this should only be used with the exit and
|
|
exitcond options. Also, the variable recurlev, on both entry and
|
|
exit, will effectively have as its value a number indicating the
|
|
current recursion level (as would be printed by Trace). This
|
|
allows conditional breaks and Traces based on the depth
|
|
of recursion. The recursion level is incremented by means of
|
|
lambda-binding; thus if an error or other interrupt occurs,
|
|
the recursion level will be reset by unbinding.
|
|
(Note that the word "effectively" is used in describing the
|
|
values of the above "variables" since these variables are
|
|
not actually used; Trace actually performs a sublis on the
|
|
expressions for the options mentioned above, substituting
|
|
certain non-interned atoms for any and all appearances of
|
|
the special "variables" mentioned above. Therefore, do
|
|
not try to use these variables for anything but obtaining
|
|
their values when using them in expressions for the above
|
|
options.)
|
|
|
|
In addition to using the variable arglist, expressions
|
|
for Trace options may refer to the actual names of
|
|
the function's arguments if the function is interpreted rather
|
|
than compiled. Furthermore, such argument variables may
|
|
be examined from breakpoints.
|
|
|
|
|
|
Trace uses the Prin1 current at the time of printing the trace
|
|
for its printouts. Thus, in order to have your Trace output
|
|
passed through Grind, you might perform (setq prin1 'Sprint);
|
|
for debugging Macsyma internals, (Fasload Funpr Fasl Dsk Libmax)
|
|
(setq prin1 'Funprint). You can also use the Grind option
|
|
(Trace (foo Grind)), but of course this uses the system grind.
|
|
|
|
Examples of calls to Trace:
|
|
|
|
[1] to Trace function foo, printing both arguments on entry
|
|
and result on exit:
|
|
(Trace foo) or (Trace (foo)) or (Trace (foo both)).
|
|
|
|
[2] to Trace function foo only when called from function bar,
|
|
and then only if (cdr x) is nil:
|
|
(Trace (foo wherein bar cond (null (cdr x))))
|
|
or (Trace (foo cond (null (cdr x)) wherein bar)).
|
|
As this example shows, the order of the options makes no
|
|
difference, except for arg, value, both, or nil, which must
|
|
be last.
|
|
|
|
[3] to Trace function quux, printing the resultant value
|
|
on exiting but no arguments on entry, printing the value
|
|
of (car x) on entry, of foo1, foo2, and (foo3 bar) on exit,
|
|
and of zxcvbnm and (qwerty shrdlu) on both entry and exit:
|
|
(Trace (quux entry ((car x)) exit (foo1 foo2 (foo3 bar))
|
|
value zxcvbnm (qwerty shrdlu))).
|
|
|
|
[4] to Trace function foo only when called by functions bar
|
|
and baz, printing args on entry and result on exit, printing
|
|
the value of (quux barf barph) on exit from foo when called
|
|
by baz only, and conditionally breaking when called by bar if
|
|
a equals b:
|
|
(Trace (foo wherein bar break (equal a b))
|
|
(foo wherein baz exit ((quux barf barph)))).
|
|
|
|
[5] to Trace functions phoo and fu, never printing anything
|
|
for either, but saving all arguments for both on a common pdl
|
|
called foopdl, and breaking inside phoo if x is nil:
|
|
(Trace (phoo argpdl foopdl break (null x) cond nil nil)
|
|
(fu argpdl foopdl cond nil nil)).
|
|
The "cond nil" prevents anything at all from being printed.
|
|
The second nil in each <Trace spec> specifies that no args
|
|
or value are to be printed; although the cond nil would
|
|
prevent the printout anyway, specifying this too prevents
|
|
Trace from even setting up the mechanisms to do this (which
|
|
it would, against the possibility that someday nil might not
|
|
evaluate to nil.)
|
|
|
|
[6] to Trace function foobar, printing args on entry and
|
|
result on exit, plus the value of moby-expr on exit, and
|
|
pretty-printing the output:
|
|
(Trace (foobar grind exit (moby-expr))).
|
|
|
|
[7] to Trace function ghoti, one of whose arguments is
|
|
fish, printing all arguments only if fish
|
|
is non-nil, and printing on exit only if the result is not
|
|
a number:
|
|
(Trace (ghoti entrycond fish
|
|
exitcond (not (numberp fnvalue)))).
|
|
|
|
[8] to Trace function ssehc, printing Trace output only if
|
|
draob is non-atomic, and even then on entry only if pohsib is
|
|
a negative number, breaking when the recursion level is either
|
|
3 or greater than 7:
|
|
(Trace (ssehc cond draob
|
|
entrycond (and (numberp pohsib) (minusp pohsib))
|
|
break (and neeuq (or (equal recurlev 3)
|
|
(lessp 7 recurlev))))).
|
|
|
|
|
|
Trace returns as its value a list of names of all functions
|
|
set to Trace; for any functions Traced with the wherein
|
|
option, say (Trace (foo wherein bar)), instead of returning
|
|
just the name it returns a 3-list (foo wherein bar).
|
|
If Trace finds a <Trace spec> it doesn't like, instead of the
|
|
function's name it returns a list whose car is ? and whose
|
|
cdr indicates what Trace didn't like. (This should be slightly
|
|
more helpful than the oold Trace, which simply returned nil.)
|
|
A list of possible error indications:
|
|
|
|
(? wherein foo) Trace couldn't find an expr, fexpr, or
|
|
macro property for the function specified by the
|
|
wherein option; or the function specified was not
|
|
atomic.
|
|
|
|
(? Argpdl foo) the item following the argpdl option was
|
|
not a non-nil pname-type atom.
|
|
|
|
(? Foo not function) indicates that the function specified
|
|
to be Traced was non-atomic, or had no functional
|
|
property. (Valid functional properties are expr,
|
|
fexpr, subr, fsubr, lsubr, and macro.)
|
|
|
|
(? Foo) foo is not a valid option.
|
|
|
|
Thus a call to Trace such as
|
|
(Trace (foo wherein (nil)) (bar argpdl nil))
|
|
would return, without setting up any Traces,
|
|
((? wherein (nil)) (? argpdl nil)).
|
|
|
|
If you attempt to specify to Trace a function already
|
|
being Traced, Trace calls untrace before setting up the new
|
|
Trace. If an error occurs, causing (? <random>) to be
|
|
returned, the function for which the error occurred may or
|
|
may not have been untraced. Beware!
|
|
|
|
it is possible to call Trace with no arguments. (Trace)
|
|
returns as its value a list of all functions currently
|
|
being Traced.
|
|
|
|
|
|
|
|
|
|
Untrace is used to undo the effects of Trace and restore
|
|
functions to their normal (?) untraced state. The argument
|
|
to untrace for a given function should be essentially what
|
|
Trace returned for it; i.e. If Trace returned foo, use
|
|
(untrace foo); if Trace returned (foo wherein bar) use
|
|
(untrace (foo wherein bar)). Untrace will take multiple
|
|
untrace specifications, e.g. (Untrace foo quux (bar
|
|
wherein baz) fuphoo). Calling untrace with no arguments
|
|
will untrace all functions currently being Traced.
|
|
|
|
|
|
|
|
Remtrace, oddly enough, expunges the entire Trace package.
|
|
It takes no arguments.
|
|
|
|
|
|
|