|
|
1.1 ! root 1: ! 2: ! 3: ! 4: ! 5: ! 6: ! 7: ! 8: CHAPTER 11 ! 9: ! 10: ! 11: The Joseph Lister Trace Package ! 12: ! 13: ! 14: ! 15: ! 16: The Joseph Lister[] Trace package is an important tool ! 17: for the interactive debugging of a Lisp program. It allows ! 18: you to examine selected calls to a function or functions, ! 19: and optionally to stop execution of the Lisp program to ! 20: examine the values of variables. ! 21: ! 22: The trace package is a set of Lisp programs located in ! 23: the Lisp program library (usually in the file ! 24: /usr/lib/lisp/trace.l). Although not normally loaded in the ! 25: Lisp system, the package will be loaded in when the first ! 26: call to _t_r_a_c_e is made. ! 27: ! 28: (trace [ls_arg1 ...]) ! 29: ! 30: WHERE: the form of the ls_arg_i is described below. ! 31: ! 32: RETURNS: a list of the function sucessfully modified ! 33: for tracing. If no arguments are given to ! 34: _t_r_a_c_e, a list of all functions currently being ! 35: traced is returned. ! 36: ! 37: SIDE EFFECT: The function definitions of the functions ! 38: to trace are modified. ! 39: ! 40: ! 41: The ls_arg_i can have one of the following forms: ! 42: ! 43: ! 44: foo - when foo is entered and exited, the trace informa- ! 45: tion will be printed. ! 46: ! 47: ! 48: (foo break) - when foo is entered and exited the trace ! 49: information will be printed. Also, just after the ! 50: trace information for foo is printed upon entry, you ! 51: will be put in a special break loop. The prompt is ! 52: `T>' and you may type any Lisp expression, and see ! 53: its value printed. The _ith argument to the function ! 54: just called can be accessed as (arg _i). To leave the ! 55: trace loop, just type ^D or (tracereturn) and ! 56: ____________________ ! 57: 9 []_L_i_s_t_e_r, _J_o_s_e_p_h 1st Baron Lister of Lyme Regis, ! 58: 1827-1912; English surgeon: introduced antiseptic surgery. ! 59: ! 60: ! 61: ! 62: 9The Joseph Lister Trace Package 11-1 ! 63: ! 64: ! 65: ! 66: ! 67: ! 68: ! 69: ! 70: The Joseph Lister Trace Package 11-2 ! 71: ! 72: ! 73: execution will continue. Note that ^D will work only ! 74: on UNIX systems. ! 75: ! 76: ! 77: (foo if expression) - when foo is entered and the expres- ! 78: sion evaluates to non-nil, then the trace information ! 79: will be printed for both exit and entry. If expres- ! 80: sion evaluates to nil, then no trace information will ! 81: be printed. ! 82: ! 83: ! 84: (foo ifnot expression) - when foo is entered and the ! 85: expression evaluates to nil, then the trace informa- ! 86: tion will be printed for both entry and exit. If ! 87: both if and ifnot are specified, then the if expres- ! 88: sion must evaluate to non nil AND the ifnot expres- ! 89: sion must evaluate to nil for the trace information ! 90: to be printed out. ! 91: ! 92: ! 93: (foo evalin expression) - when foo is entered and after ! 94: the entry trace information is printed, expression ! 95: will be evaluated. Exit trace information will be ! 96: printed when foo exits. ! 97: ! 98: ! 99: (foo evalout expression) - when foo is entered, entry ! 100: trace information will be printed. When foo exits, ! 101: and before the exit trace information is printed, ! 102: expression will be evaluated. ! 103: ! 104: ! 105: (foo evalinout expression) - this has the same effect as ! 106: (trace (foo evalin expression evalout expression)). ! 107: ! 108: ! 109: (foo lprint) - this tells _t_r_a_c_e to use the level printer ! 110: when printing the arguments to and the result of a ! 111: call to foo. The level printer prints only the top ! 112: levels of list structure. Any structure below three ! 113: levels is printed as a &. This allows you to trace ! 114: functions with massive arguments or results. ! 115: ! 116: ! 117: ! 118: The following trace options permit one to have ! 119: greater control over each action which takes place when ! 120: a function is traced. These options are only meant to ! 121: be used by people who need special hooks into the trace ! 122: package. Most people should skip reading this section. ! 123: ! 124: ! 125: (foo traceenter tefunc) - this tells _t_r_a_c_e that the ! 126: ! 127: ! 128: Printed: July 27, 1983 ! 129: ! 130: ! 131: ! 132: ! 133: ! 134: ! 135: ! 136: The Joseph Lister Trace Package 11-3 ! 137: ! 138: ! 139: function to be called when foo is entered is tefunc. ! 140: tefunc should be a lambda of two arguments, the first ! 141: argument will be bound to the name of the function ! 142: being traced, foo in this case. The second argument ! 143: will be bound to the list of arguments to which foo ! 144: should be applied. The function tefunc should print ! 145: some sort of "entering foo" message. It should not ! 146: apply foo to the arguments, however. That is done ! 147: later on. ! 148: ! 149: ! 150: (foo traceexit txfunc) - this tells _t_r_a_c_e that the func- ! 151: tion to be called when foo is exited is txfunc. ! 152: txfunc should be a lambda of two arguments, the first ! 153: argument will be bound to the name of the function ! 154: being traced, foo in this case. The second argument ! 155: will be bound to the result of the call to foo. The ! 156: function txfunc should print some sort of "exiting ! 157: foo" message. ! 158: ! 159: ! 160: (foo evfcn evfunc) - this tells _t_r_a_c_e that the form evfunc ! 161: should be evaluated to get the value of foo applied ! 162: to its arguments. This option is a bit different from ! 163: the other special options since evfunc will usually ! 164: be an expression, not just the name of a function, ! 165: and that expression will be specific to the evalua- ! 166: tion of function foo. The argument list to be ! 167: applied will be available as T-arglist. ! 168: ! 169: ! 170: (foo printargs prfunc) - this tells _t_r_a_c_e to used prfunc ! 171: to print the arguments to be applied to the function ! 172: foo. prfunc should be a lambda of one argument. You ! 173: might want to use this option if you wanted a print ! 174: function which could handle circular lists. This ! 175: option will work only if you do not specify your own ! 176: traceenter function. Specifying the option lprint is ! 177: just a simple way of changing the printargs function ! 178: to the level printer. ! 179: ! 180: ! 181: (foo printres prfunc) - this tells _t_r_a_c_e to use prfunc to ! 182: print the result of evaluating foo. prfunc should be ! 183: a lambda of one argument. This option will work only ! 184: if you do not specify your own traceexit function. ! 185: Specifying the option lprint changes printres to the ! 186: level printer. ! 187: ! 188: ! 189: ! 190: You may specify more than one option for each ! 191: function traced. For example: ! 192: ! 193: ! 194: Printed: July 27, 1983 ! 195: ! 196: ! 197: ! 198: ! 199: ! 200: ! 201: ! 202: The Joseph Lister Trace Package 11-4 ! 203: ! 204: ! 205: (_t_r_a_c_e (_f_o_o _i_f (_e_q _3 (_a_r_g _1)) _b_r_e_a_k _l_p_r_i_n_t) (_b_a_r _e_v_a_l_i_n ! 206: (_p_r_i_n_t _x_y_z_z_y))) ! 207: ! 208: This tells _t_r_a_c_e to trace two more functions, foo and ! 209: bar. Should foo be called with the first argument _e_q ! 210: to 3, then the entering foo message will be printed ! 211: with the level printer. Next it will enter a trace ! 212: break loop, allowing you to evaluate any lisp expres- ! 213: sions. When you exit the trace break loop, foo will be ! 214: applied to its arguments and the resulting value will ! 215: be printed, again using the level printer. Bar is also ! 216: traced, and each time bar is entered, an entering bar ! 217: message will be printed and then the value of xyzzy ! 218: will be printed. Next bar will be applied to its argu- ! 219: ments and the result will be printed. If you tell ! 220: _t_r_a_c_e to trace a function which is already traced, it ! 221: will first _u_n_t_r_a_c_e it. Thus if you want to specify ! 222: more than one trace option for a function, you must do ! 223: it all at once. The following is _n_o_t equivalent to the ! 224: preceding call to _t_r_a_c_e for foo: ! 225: ! 226: (_t_r_a_c_e (_f_o_o _i_f (_e_q _3 (_a_r_g _1))) (_f_o_o _b_r_e_a_k) (_f_o_o ! 227: _l_p_r_i_n_t)) ! 228: ! 229: In this example, only the last option, lprint, will be ! 230: in effect. ! 231: ! 232: If the symbol $tracemute is given a non nil value, ! 233: printing of the function name and arguments on entry ! 234: and exit will be surpressed. This is particularly use- ! 235: ful if the function you are tracing fails after many ! 236: calls to it. In this case you would tell _t_r_a_c_e to ! 237: trace the function, set $tracemute to t, and begin the ! 238: computation. When an error occurs you can use _t_r_a_- ! 239: _c_e_d_u_m_p to print out the current trace frames. ! 240: ! 241: Generally the trace package has its own internal ! 242: names for the the lisp functions it uses, so that you ! 243: can feel free to trace system functions like _c_o_n_d and ! 244: not worry about adverse interaction with the actions of ! 245: the trace package. You can trace any type of function: ! 246: lambda, nlambda, lexpr or macro whether compiled or ! 247: interpreted and you can even trace array references ! 248: (however you should not attempt to store in an array ! 249: which has been traced). ! 250: ! 251: When tracing compiled code keep in mind that many ! 252: function calls are translated directly to machine ! 253: language or other equivalent function calls. A full ! 254: list of open coded functions is listed at the beginning ! 255: of the liszt compiler source. _T_r_a_c_e will do a ! 256: (_s_s_t_a_t_u_s _t_r_a_n_s_l_i_n_k _n_i_l) to insure that the new traced ! 257: definitions it defines are called instead of the old ! 258: ! 259: ! 260: Printed: July 27, 1983 ! 261: ! 262: ! 263: ! 264: ! 265: ! 266: ! 267: ! 268: The Joseph Lister Trace Package 11-5 ! 269: ! 270: ! 271: untraced ones. You may notice that compiled code will ! 272: run slower after this is done. ! 273: ! 274: (traceargs s_func [x_level]) ! 275: ! 276: WHERE: if x_level is missing it is assumed to be 1. ! 277: ! 278: RETURNS: the arguments to the x_level_t_h call to traced ! 279: function s_func are returned. ! 280: ! 281: (tracedump) ! 282: ! 283: SIDE EFFECT: the currently active trace frames are ! 284: printed on the terminal. returns a list ! 285: of functions untraced. ! 286: ! 287: (untrace [s_arg1 ...]) ! 288: ! 289: RETURNS: a list of the functions which were untraced. ! 290: ! 291: NOTE: if no arguments are given, all functions are ! 292: untraced. ! 293: ! 294: SIDE EFFECT: the old function definitions of all traced ! 295: functions are restored except in the case ! 296: where it appears that the current defini- ! 297: tion of a function was not created by ! 298: trace. ! 299: ! 300: ! 301: ! 302: ! 303: ! 304: ! 305: ! 306: ! 307: ! 308: ! 309: ! 310: ! 311: ! 312: ! 313: ! 314: ! 315: ! 316: ! 317: ! 318: ! 319: ! 320: ! 321: ! 322: ! 323: 9 ! 324: ! 325: 9 Printed: July 27, 1983 ! 326: ! 327: ! 328:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.