Commit | Line | Data |
---|---|---|
0165e2a3 NC |
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 | .\" | |
836163c4 | 5 | .\" @(#)ch11.n 6.1 (Berkeley) %G% |
0165e2a3 | 6 | .\" |
836163c4 NC |
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. |