|
|
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.