document distributed with 4.1BSD
authorNick Cuccia <cuccia@ucbvax.Berkeley.EDU>
Wed, 30 Apr 1986 10:02:49 +0000 (02:02 -0800)
committerNick Cuccia <cuccia@ucbvax.Berkeley.EDU>
Wed, 30 Apr 1986 10:02:49 +0000 (02:02 -0800)
SCCS-vsn: old/lisp/PSD.doc/ch11.n 4.1

usr/src/old/lisp/PSD.doc/ch11.n [new file with mode: 0644]

diff --git a/usr/src/old/lisp/PSD.doc/ch11.n b/usr/src/old/lisp/PSD.doc/ch11.n
new file mode 100644 (file)
index 0000000..7d670ac
--- /dev/null
@@ -0,0 +1,226 @@
+.\" Copyright (c) 1980 Regents of the University of California.
+.\" All rights reserved.  The Berkeley software License Agreement
+.\" specifies the terms and conditions for redistribution.
+.\"
+.\"    @(#)ch11.n      4.1 (Berkeley) %G%
+.\"
+." @(#)ch11.n  34.1 1/29/81
+.Lc The\ Joseph\ Lister\ Trace\ Package 11
+.de Tf
+.sp 2v
+.ti -.5i
+\fB\\$1\fP - 
+..
+.pp
+The Joseph Lister\*[\(dg\*] Trace package is an 
+important tool for the interactive debugging of a Lisp
+program.
+.(f
+\*[\(dg\*]\fILister, Joseph\fP\ \ \ \ 
+1st Baron Lister of Lyme Regis,
+1827-1912; English surgeon: introduced antiseptic surgery.
+.)f
+It allows you to examine selected  calls to a function or functions, and
+optionally to stop execution of the Lisp program to examine the values
+of variables.
+.pp
+The trace package is a set of Lisp programs located in the Lisp program 
+library (usually in the file /usr/lib/lisp/trace.l).
+There are two user callable functions  in the trace package: 
+.i trace  
+and 
+.i untrace .
+The trace package will be loaded automatically when you first use the
+.i trace 
+function. 
+Both 
+.i trace and 
+.i untrace 
+are nlambdas (their arguments are not evaluated).
+The form of a call to 
+.i trace
+is 
+.br
+.tl ''\fB(trace \fIarg1 arg2 ...\fB)\fR''
+where the 
+.i argi
+have one of the following forms:
+.in .75i
+.Tf "foo"
+when foo is entered and exited, the trace information will be printed.
+.Tf "(foo break)"
+when foo is entered and exited the trace information will be printed.
+Also, just after the trace information for foo is printed upon entry,
+you will be put in  a special break loop.
+The prompt is `T>' and you may type any Lisp expression, and see its
+value printed.
+The 
+.i i th 
+argument to the function just called can be accessed as (arg \fIi\fP).
+To leave the trace loop, just type ^D or (tracereturn)
+and execution will continue.
+Note that ^D will work only on UNIX systems.
+.Tf "(foo if expression)"
+when foo is entered and the expression evaluates to non-nil, then the
+trace information will be printed for both exit and entry.
+If expression evaluates to nil, then no trace information will be
+printed.
+.Tf "(foo ifnot expression)"
+when foo is entered and the expression evaluates to nil, then the
+trace information will be printed for both entry and exit.
+If both \fBif\fP and 
+.b ifnot 
+are specified, then the 
+.b if 
+expression must evaluate
+to non nil AND the 
+.b ifnot 
+expression must evaluate to nil for the trace
+information to be printed out.
+.Tf "(foo evalin expression)"
+when foo is entered and after the entry trace information is printed,
+expression will be evaluated. 
+Exit trace information will be printed when foo exits.
+.Tf "(foo evalout expression)"
+when foo is entered, entry trace information will be printed.
+When foo exits, and before the exit trace information is printed,
+expression will be evaluated.
+.Tf "(foo evalinout expression)"
+this has the same effect as (trace (foo evalin expression evalout expression)).
+.Tf "(foo lprint)"
+this tells 
+.i trace 
+to use the level printer when printing the arguments to
+and the result of  a call to foo.
+The level printer prints only the top levels of list structure. 
+Any structure
+below three levels is printed as a &.
+This allows you to trace functions with massive arguments or results.
+.sp 2v
+.pp
+The following trace options permit one to have greater control over each
+action which takes place when a function is traced.
+These options are only meant to be used by people who need special hooks
+into the trace package.
+Most people should skip reading this section.
+.in .75i
+.Tf "(foo traceenter tefunc)"
+this tells 
+.i trace 
+that the function to be called when foo is entered is 
+tefunc.
+tefunc should be a lambda of two arguments, the first argument will be 
+bound to the name of the function being traced, foo in this case.
+The second argument will be bound to the list of arguments to which 
+foo should be applied.
+The function tefunc should print some sort of "entering foo" message.
+It should not apply foo to the arguments, however. 
+That is done later on.
+.Tf "(foo traceexit txfunc)"
+this tells 
+.i trace 
+that the function to be called when foo is exited is
+txfunc.
+txfunc should be a lambda of two arguments, the first argument will be
+bound to the name of the function being traced, foo in this case.
+The second argument will be bound to the result of the call to foo.
+The function txfunc should print some sort of "exiting foo" message.
+.Tf "(foo evfcn evfunc)"
+this tells 
+.i trace 
+that the form evfunc should be evaluated to get the value
+of foo applied to its arguments.  
+This option is a bit different from the other special options since evfunc
+will usually be an expression, not just the name of a function, and that
+expression will be specific to the evaluation of function foo.
+The argument list to be applied will be available as T-arglist.
+.Tf "(foo printargs prfunc)"
+this tells 
+.i trace 
+to used prfunc to print the arguments  to be
+applied to the function foo.
+prfunc should be a lambda of one argument.
+You might want to use this option if you wanted a print function which could
+handle circular lists.
+This option will work only if you do not specify your own 
+.b traceenter 
+function.
+Specifying the option 
+.b lprint 
+is just a simple way of changing the printargs
+function to the level printer.
+.Tf "(foo printres prfunc)"
+this tells 
+.i trace 
+to use prfunc to print the result of evaluating foo.
+prfunc should be a lambda of one argument.
+This option will work only if you do not specify your own 
+.b traceexit 
+function.
+Specifying the option 
+.b lprint 
+changes printres to the level printer.
+.sp 2v
+.pp
+You may specify more than one option for each function traced.  
+For example:
+.sp 1v
+.ti .5i
+\fI(trace (foo if\ (eq 3 (arg 1)) break lprint) (bar evalin (print xyzzy)))\fP
+.sp 1v
+This tells 
+.i trace 
+to trace two more functions, foo and bar.
+Should foo be called with the first argument 
+.i eq
+to 3, then the entering foo message will be printed with the level printer.
+Next it will enter a trace break loop, allowing you to evaluate any 
+lisp expressions.
+When you exit the trace break loop, foo will be applied to its arguments
+and the resulting value will be printed, again using the level printer.
+Bar is also traced, and each time bar is entered, an entering bar message
+will be printed and then the value of xyzzy will be printed.
+Next bar will be applied to its arguments and the result will be printed.
+If you tell 
+.i trace 
+to trace a function which is already traced, it will first
+.i untrace 
+it.  Thus if you want to specify more than one trace option for
+a function, you must do it all at once.
+The following is 
+.i not 
+equivalent to the preceding call to 
+.i trace 
+for foo:
+.sp 1v
+\fI(trace (foo if (eq 3 (arg 1))) (foo break) (foo lprint))\fP
+.sp 1v.
+In this example, only the last option, lprint, will be in effect.
+.pp
+The function 
+.i trace 
+returns a list of functions is was able to trace.
+The function 
+.i untrace 
+untraces those functions its is argument list.
+If the argument list is empty then all functions being traced are untraced.
+.i Untrace 
+returns a list of functions untraced.
+.pp
+Generally the trace package has its own internal names for the the lisp
+functions it uses, so that you can feel free to trace system functions like
+.i cond 
+and not worry about adverse interaction with the actions of the trace
+package.
+You can trace any type of function: lambda, nlambda, lexpr or macro whether
+compiled or interpreted and you can even trace array references (however
+you should not attempt to store in an array which has been traced).
+.pp
+When tracing compiled code keep in mind that many function calls are translated 
+directly to machine language  or other equivalent  function calls.
+A full list of open coded functions is listed at the beginning of the 
+liszt compiler source.
+.i Trace 
+will do a \fI(sstatus\ translink\ nil)\fP to insure that the 
+new traced definitions it defines are called instead of the old untraced ones.
+You may notice that compiled code will run slower after this is done.