|
|
1.1 root 1: .\" Copyright (c) 1980 Regents of the University of California.
2: .\" All rights reserved. The Berkeley software License Agreement
3: .\" specifies the terms and conditions for redistribution.
4: .\"
5: .\" @(#)ch11.n 6.1 (Berkeley) 4/29/86
6: .\"
7: ." $Header: ch11.n 1.1 83/01/31 07:08:25 jkf Exp $
8: .Lc The\ Joseph\ Lister\ Trace\ Package 11
9: .de Tf
10: .sp 2v
11: .ti -.5i
12: \fB\\$1\fP -
13: ..
14: .pp
15: The Joseph Lister\*[\(dg\*] Trace package is an
16: important tool for the interactive debugging of a Lisp
17: program.
18: .(f
19: \*[\(dg\*]\fILister, Joseph\fP\ \ \ \
20: 1st Baron Lister of Lyme Regis,
21: 1827-1912; English surgeon: introduced antiseptic surgery.
22: .)f
23: It allows you to examine selected calls to a function or functions, and
24: optionally to stop execution of the Lisp program to examine the values
25: of variables.
26: .pp
27: The trace package is a set of Lisp programs located in the Lisp program
28: library (usually in the file /usr/lib/lisp/trace.l).
29: Although not normally loaded in the Lisp system, the package will
30: be loaded in when the first call to \fItrace\fP is made.
31: .Lf trace "[ls_arg1 ...]"
32: .Wh
33: the form of the ls_arg\fIi\fP is described below.
34: .Re
35: a list of the function sucessfully modified for tracing.
36: If no arguments are given to
37: .i trace ,
38: a list of all functions currently being traced is returned.
39: .Se
40: The function definitions of the functions to trace are modified.
41: .sp 2v
42: .in 0
43: The ls_arg\fIi\fP can have one of the following forms:
44: .in .75i
45: .Tf "foo"
46: when foo is entered and exited, the trace information will be printed.
47: .Tf "(foo break)"
48: when foo is entered and exited the trace information will be printed.
49: Also, just after the trace information for foo is printed upon entry,
50: you will be put in a special break loop.
51: The prompt is `T>' and you may type any Lisp expression, and see its
52: value printed.
53: The
54: .i i th
55: argument to the function just called can be accessed as (arg \fIi\fP).
56: To leave the trace loop, just type ^D or (tracereturn)
57: and execution will continue.
58: Note that ^D will work only on UNIX systems.
59: .Tf "(foo if expression)"
60: when foo is entered and the expression evaluates to non-nil, then the
61: trace information will be printed for both exit and entry.
62: If expression evaluates to nil, then no trace information will be
63: printed.
64: .Tf "(foo ifnot expression)"
65: when foo is entered and the expression evaluates to nil, then the
66: trace information will be printed for both entry and exit.
67: If both \fBif\fP and
68: .b ifnot
69: are specified, then the
70: .b if
71: expression must evaluate
72: to non nil AND the
73: .b ifnot
74: expression must evaluate to nil for the trace
75: information to be printed out.
76: .Tf "(foo evalin expression)"
77: when foo is entered and after the entry trace information is printed,
78: expression will be evaluated.
79: Exit trace information will be printed when foo exits.
80: .Tf "(foo evalout expression)"
81: when foo is entered, entry trace information will be printed.
82: When foo exits, and before the exit trace information is printed,
83: expression will be evaluated.
84: .Tf "(foo evalinout expression)"
85: this has the same effect as (trace (foo evalin expression evalout expression)).
86: .Tf "(foo lprint)"
87: this tells
88: .i trace
89: to use the level printer when printing the arguments to
90: and the result of a call to foo.
91: The level printer prints only the top levels of list structure.
92: Any structure
93: below three levels is printed as a &.
94: This allows you to trace functions with massive arguments or results.
95: .sp 2v
96: .pp
97: The following trace options permit one to have greater control over each
98: action which takes place when a function is traced.
99: These options are only meant to be used by people who need special hooks
100: into the trace package.
101: Most people should skip reading this section.
102: .in .75i
103: .Tf "(foo traceenter tefunc)"
104: this tells
105: .i trace
106: that the function to be called when foo is entered is
107: tefunc.
108: tefunc should be a lambda of two arguments, the first argument will be
109: bound to the name of the function being traced, foo in this case.
110: The second argument will be bound to the list of arguments to which
111: foo should be applied.
112: The function tefunc should print some sort of "entering foo" message.
113: It should not apply foo to the arguments, however.
114: That is done later on.
115: .Tf "(foo traceexit txfunc)"
116: this tells
117: .i trace
118: that the function to be called when foo is exited is
119: txfunc.
120: txfunc should be a lambda of two arguments, the first argument will be
121: bound to the name of the function being traced, foo in this case.
122: The second argument will be bound to the result of the call to foo.
123: The function txfunc should print some sort of "exiting foo" message.
124: .Tf "(foo evfcn evfunc)"
125: this tells
126: .i trace
127: that the form evfunc should be evaluated to get the value
128: of foo applied to its arguments.
129: This option is a bit different from the other special options since evfunc
130: will usually be an expression, not just the name of a function, and that
131: expression will be specific to the evaluation of function foo.
132: The argument list to be applied will be available as T-arglist.
133: .Tf "(foo printargs prfunc)"
134: this tells
135: .i trace
136: to used prfunc to print the arguments to be
137: applied to the function foo.
138: prfunc should be a lambda of one argument.
139: You might want to use this option if you wanted a print function which could
140: handle circular lists.
141: This option will work only if you do not specify your own
142: .b traceenter
143: function.
144: Specifying the option
145: .b lprint
146: is just a simple way of changing the printargs
147: function to the level printer.
148: .Tf "(foo printres prfunc)"
149: this tells
150: .i trace
151: to use prfunc to print the result of evaluating foo.
152: prfunc should be a lambda of one argument.
153: This option will work only if you do not specify your own
154: .b traceexit
155: function.
156: Specifying the option
157: .b lprint
158: changes printres to the level printer.
159: .sp 2v
160: .pp
161: You may specify more than one option for each function traced.
162: For example:
163: .sp 1v
164: .ti .5i
165: \fI(trace (foo if\ (eq 3 (arg 1)) break lprint) (bar evalin (print xyzzy)))\fP
166: .sp 1v
167: This tells
168: .i trace
169: to trace two more functions, foo and bar.
170: Should foo be called with the first argument
171: .i eq
172: to 3, then the entering foo message will be printed with the level printer.
173: Next it will enter a trace break loop, allowing you to evaluate any
174: lisp expressions.
175: When you exit the trace break loop, foo will be applied to its arguments
176: and the resulting value will be printed, again using the level printer.
177: Bar is also traced, and each time bar is entered, an entering bar message
178: will be printed and then the value of xyzzy will be printed.
179: Next bar will be applied to its arguments and the result will be printed.
180: If you tell
181: .i trace
182: to trace a function which is already traced, it will first
183: .i untrace
184: it. Thus if you want to specify more than one trace option for
185: a function, you must do it all at once.
186: The following is
187: .i not
188: equivalent to the preceding call to
189: .i trace
190: for foo:
191: .sp 1v
192: \fI(trace (foo if (eq 3 (arg 1))) (foo break) (foo lprint))\fP
193: .sp 1v.
194: In this example, only the last option, lprint, will be in effect.
195: .pp
196: If the symbol $tracemute is given a non nil value, printing of the
197: function name and arguments on entry and exit will be surpressed.
198: This is particularly useful if the function you are tracing fails
199: after many calls to it. In this case you would tell
200: .i trace
201: to
202: trace the function, set $tracemute to t, and begin the computation.
203: When an error occurs you can use
204: .i tracedump
205: to print out the current trace frames.
206: .pp
207: Generally the trace package has its own internal names for the the lisp
208: functions it uses, so that you can feel free to trace system functions like
209: .i cond
210: and not worry about adverse interaction with the actions of the trace
211: package.
212: You can trace any type of function: lambda, nlambda, lexpr or macro whether
213: compiled or interpreted and you can even trace array references (however
214: you should not attempt to store in an array which has been traced).
215: .pp
216: When tracing compiled code keep in mind that many function calls are translated
217: directly to machine language or other equivalent function calls.
218: A full list of open coded functions is listed at the beginning of the
219: liszt compiler source.
220: .i Trace
221: will do a \fI(sstatus\ translink\ nil)\fP to insure that the
222: new traced definitions it defines are called instead of the old untraced ones.
223: You may notice that compiled code will run slower after this is done.
224: .Lf traceargs "s_func [x_level]"
225: .Wh
226: if x_level is missing it is assumed to be 1.
227: .Re
228: the arguments to the x_level\fIth\fP call to traced
229: function s_func are returned.
230: .Lf tracedump ""
231: .Se
232: the currently active trace frames are printed on the terminal.
233: returns a list of functions untraced.
234: .Lf untrace "[s_arg1 ...]"
235: .Re
236: a list of the functions which were untraced.
237: .No
238: if no arguments are given, all functions are untraced.
239: .Se
240: the old function definitions of all
241: traced functions are restored
242: except in the case where it appears that
243: the current definition of a function was not created by trace.
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.