1\chapter{Debugging Tools} 2 3\section{The Debug Module} 4 5\index{trace}\index{break} 6 {\bf debug} is a loadable option. This module provides a 7basic debugging tool which provides a breakpoint function, and 8functions for breaking and tracing functions and methods 9selected by the user. debug is loaded automatically if one of the 10functions tr, trst or br is called. 11 12\subsection{Overview of Functionality} 13 14 The function breakpoint allows the user to set a breakpoint 15anywhere within his code. Whenever a breakpoint is called a 16continuable break loop is entered. This allows the user to 17examine or modify variables, view a backtrace, and continue 18execution. 19 20 Tracing gives a record of the sequence of calls made to a set 21of functions specified by the user. When a traced function is 22entered a message is printed giving the function name, level of 23recursion, and values of any arguments. Upon function exit 24another message is printed, giving the value returned by the 25function. 26 27 Breaking a function means that the system enters a continuable 28break loop both before and after evaluation of the body of the 29function. Within the break loop the user may inspect and change 30values of parameters and non-local variables, and then continue 31execution. A break on entry occurs after the function's formal 32parameters have been bound to the actual arguments but before 33any of the forms in the function body have been evaluated. The 34break on exit occurs after the body of the broken function has 35been evaluated. 36 37\subsection{Using Break and Trace} 38 39 40\de{tr}{(tr [NAME: id]): list}{macro} 41{ If no arguments are given then a list is returned which 42 indicates which functions are currently being traced. 43 Otherwise, each argument is treated as a reference to a 44 function, and if possible, the function is set up for 45 tracing. The list which is returned represents the 46 functions which have been added to the set of functions 47 being traced. 48} 49 50\de{trst}{(trst [NAME: id]): list}{macro} 51{ If no arguments are given then a list is returned which 52 indicates which functions are currently being traced. 53 Otherwise, each argument is treated as a reference to a 54 function, and if possible, the function is set up for 55 tracing. The list which is returned represents the 56 functions which have been added to the set of functions 57 being traced. Trst can be used only for functions which are 58 not compiled. Additionally to the entry and exit messages, 59 for each $setq$ assignment inside the function the variable name 60 and the value are printed. 61} 62 63\de{br}{(br [NAME: id, method-specification]): list}{macro} 64{ If no arguments are given then a list is returned which 65 indicates which functions are currently broken. NAME is 66 treated as a reference to a function, and if possible, the 67 function is set up for breaking. Subsequent arguments will 68 be processed. The list which is returned represents the 69 functions which have been added to the set of broken 70 functions. 71} 72 73\de{untr}{(untr [NAME:id]): list}{macro} 74{ If no arguments are given then tracing is removed for each 75 traced function. NAME is treated as a reference to a 76 function, and if possible, tracing is disabled for this 77 function. Subsequent arguments will be processed. The list 78 which is returned contains the names of the functions for 79 which tracing has been removed. 80} 81 82\de{unbr}{(unbr [NAME:id,]): list}{macro} 83{ If no arguments are given then breaking is turned off for 84 each broken function. NAME is treated as a reference to a 85 function, and if possible, breaking is disabled for this 86 function. The list which is returned contains the names of 87 the functions for which breaking has been removed. 88} 89 90 91\subsection{Sample Session} 92 93 94 Trace and break printout goes to the standard output channel. 95Because multiple nested calls are usually shown, indentation and 96vertical bars are used to line up function entry and return 97messages for the same function. 98 99\begin{verbatim} 100(de add3 (a1 a2 a3) 101 (+ a1 (add2 a2 a3))) 102\end{verbatim} 103\begin{verbatim} 104(de add2 (a1 a2) 105 (+ a1 a2)) 106\end{verbatim} 107\begin{verbatim} 108(de fact (n) 109 (cond ((zerop n) 1) 110 (t (times n (fact (sub1 n)))))) 111\end{verbatim} 112\begin{verbatim} 1131 lisp> (br add3) 114In a break, t prints backTrace; c Continues; 115q Quits a level; a Aborts to top. 116(ADD3) 1172 lisp> (tr 'add3) 118***** (QUOTE ADD3) is not a valid method-specification. 119NIL 1203 lisp> (tr add3 add2) 121(ADD2 ADD3) 1224 lisp> (add3 5 6 7) 123ADD3 entry: 124| A1: 5 125| A2: 6 126| A3: 7 127| ADD3 entry BREAK: 128| NMODE Break loop 1295 lisp break (1)> c % Continue 130| | ADD2 entry: 131| | | A1: 6 132| | | A2: 7 133| | ADD2 value = 13 134| ADD3 exit BREAK, value = 18: 135| NMODE Break loop 1366 lisp break (1)> c 137ADD4 value = 18 13818 139\end{verbatim} 140\begin{verbatim} 1411 lisp> (tr fact) 142(FACT) 1432 lisp> (fact 4) 144FACT entry: 145| N: 4 146| FACT reentry (# 2): 147| | % (# 2) represents the depth of recursion 148| | N: 3 149| | FACT reentry (# 3): 150| | | N: 2 151| | | FACT reentry (# 4): 152| | | | N: 1 153| | | | FACT reentry (# 5): 154| | | | | N: 0 155| | | | FACT value (# 5) = 1 156| | | FACT value (# 4) = 1 157| | FACT value (# 3) = 2 158| FACT value (# 2) = 6 159FACT value = 24 16024 1613 lisp> (trace) 162(FACT ADD2 ADD3 ADD4) 1634 lisp> (untrace) 164(ADD4 ADD3 ADD2 FACT) 1655 lisp> (restr) 166T 167\end{verbatim} 168 169 170 Tracing a macro will happen at macroexpand time. The value 171returned will be the macroexpanded form, and thus is quite 172useful in determining if your macro expanded properly. Note 173that when code is complied the application of a macro is 174expanded and this expansion replaces the the application. 175 176\begin{verbatim} 1771 lisp> (trace plus) 178(PLUS) 1792 lisp> (plus 2 9 -3 7 8) 180PLUS entry: 181| ARG1 :(PLUS 2 9 -3 7 ...) 182PLUS value = (PLUS2 2 (PLUS2 9 (PLUS2 -3 (PLUS2 7 8)))) 18323 184\end{verbatim} 185\begin{verbatim} 186(de fact (n) 187 (cond ((zerop n) 1) 188 (t (breakpoint "Fact; n<>0 branch of cond, n=%p" n) 189 (times n (fact (sub1 n)))))) 190\end{verbatim} 191\begin{verbatim} 1921 lisp> (fact 2) 193User Breakpoint: Fact; n<>0 branch of cond, n=2 194NMODE Break loop 1952 lisp break (1)> c 196User Breakpoint: Fact; n<>0 branch of cond, n=1 197NMODE Break loop 1983 lisp break (1)> c 1992 200\end{verbatim} 201 202\subsection{Redefining a Broken or Traced Function} 203 204 The basic definition of a function is the definition without 205any of the break or tracing side effects. This basic definition 206may be accessed by the function getd. The basic definition may 207also be redefined by using the function putd without interfering 208with the break/trace side effects, as long as the parameter list 209stays the same. If you intend to change the number or order of 210parameters you should first remove the break/trace wrappers from 211it with untrace and/or unbr. 212 213 214