| 1 | ." $Header: /na/franz/doc/RCS/ch15.n,v 1.1 83/01/31 07:08:47 jkf Exp $ |
| 2 | .Lc The\ FIXIT\ Debugger 15 |
| 3 | .sh 2 Introduction 15 |
| 4 | FIXIT is a debugging environment for |
| 5 | .Fr |
| 6 | users doing program development. This documentation and FIXIT |
| 7 | were written by David S. Touretzky |
| 8 | of Carnegie-Mellon University for MACLisp, and adapted to |
| 9 | .Fr |
| 10 | by Mitch Marcus of Bell Labs. One of |
| 11 | FIXIT's goals is to get the program running again as quickly |
| 12 | as possible. The user is assisted in making changes to his |
| 13 | functions "on the fly", i.e. in the midst of execution, and |
| 14 | then computation is resumed. |
| 15 | .pp |
| 16 | To enter the debugger type \fI(debug)\fP. |
| 17 | The debugger goes into its own |
| 18 | read-eval-print loop. Like the top-level, the debugger understands |
| 19 | certain special commands. One of these is help, which prints a list of |
| 20 | the available commands. The basic idea is that you are somewhere in a |
| 21 | stack of calls to eval. The command "bka" is probably the most appropriate |
| 22 | for looking at the stack. There are commands to move up and down. If |
| 23 | you want to know the value of "x" as of some place in the stack, move to |
| 24 | that place and type "x" (or (cdr x) or anything else that you might want |
| 25 | to evaluate). All evaluation is done as of the current stack position. |
| 26 | You can fix the problem by changing the values of variables, editing |
| 27 | functions or expressions in the stack etc. Then you can continue from |
| 28 | the current stack position (or anywhere else) with the "redo" command. |
| 29 | Or you can simply return the right answer with the "return" command. |
| 30 | .pp |
| 31 | When it is not immediately obvious why an error has occurred |
| 32 | or how the program got itself into its current state, FIXIT |
| 33 | comes to the rescue by providing a powerful debugging loop |
| 34 | in which the user can: |
| 35 | |
| 36 | - examine the stack |
| 37 | |
| 38 | - evaluate expressions in context |
| 39 | |
| 40 | - enter stepping mode |
| 41 | |
| 42 | - restart the computation at any point |
| 43 | |
| 44 | The result is that program errors can be located and fixed |
| 45 | extremely rapidly, and with a minimum of frustration. |
| 46 | .pp |
| 47 | The debugger can only work effectively when extra information is kept |
| 48 | about forms in evaluation by the lisp system. |
| 49 | Evaluating \fI(*rset\ t)\fP tells the lisp system to maintain this |
| 50 | information. |
| 51 | If you are debugging compiled code you should also be sure that the |
| 52 | compiled code to compiled code linkage tables are unlinked, i.e |
| 53 | do \fI(sstatus\ translink\ nil)\fP. |
| 54 | |
| 55 | .Lf debug "[ s_msg ]" |
| 56 | .No |
| 57 | Within a program, you may enter a debug loop directly by |
| 58 | putting in a call to |
| 59 | .i debug |
| 60 | where you would normally put |
| 61 | a call to |
| 62 | .i break. |
| 63 | Also, within a break loop you may enter |
| 64 | FIXIT by typing |
| 65 | .i debug. |
| 66 | If an argument is given to DEBUG, |
| 67 | it is treated as a message to be printed before the debug loop |
| 68 | is entered. Thus you can put \fI(debug |just before loop|)\fP into |
| 69 | a program to indicate what part of the program is being debugged. |
| 70 | |
| 71 | .Eb |
| 72 | \fIFIXIT Command Summary\fP |
| 73 | |
| 74 | TOP go to top of stack (latest expression) |
| 75 | BOT go to bottom of stack (first expression) |
| 76 | P show current expression (with ellipsis) |
| 77 | PP show current expression in full |
| 78 | WHERE give current stack position |
| 79 | HELP types the abbreviated command summary found |
| 80 | in /usr/lisp/doc/fixit.help. H and ? work too. |
| 81 | U go up one stack frame |
| 82 | U n go up n stack frames |
| 83 | U f go up to the next occurrence of function f |
| 84 | U n f go up n occurrences of function f |
| 85 | UP go up to the next user-written function |
| 86 | UP n go up n user-written functions |
| 87 | ...the DN and DNFN commands are similar, but go down |
| 88 | ...instead of up. |
| 89 | OK resume processing; continue after an error or debug loop |
| 90 | REDO restart the computation with the current stack frame. |
| 91 | The OK command is equivalent to TOP followed by REDO. |
| 92 | REDO f restart the computation with the last call to function f. |
| 93 | (The stack is searched downward from the current position.) |
| 94 | STEP restart the computation at the current stack frame, |
| 95 | but first turn on stepping mode. (Assumes Rich stepper is loaded.) |
| 96 | RETURN e return from the current position in the computation |
| 97 | with the value of expression e. |
| 98 | BK.. print a backtrace. There are many backtrace commands, |
| 99 | formed by adding suffixes to the BK command. "BK" gives |
| 100 | a backtrace showing only user-written functions, and uses |
| 101 | ellipsis. The BK command may be suffixed by one or more |
| 102 | of the following modifiers: |
| 103 | ..F.. show function names instead of expressions |
| 104 | ..A.. show all functions/expressions, not just user-written ones |
| 105 | ..V.. show variable bindings as well as functions/expressions |
| 106 | ..E.. show everything in the expression, i.e. don't use ellipsis |
| 107 | ..C.. go no further than the current position on the stack |
| 108 | Some of the more useful combinations are BKFV, BKFA, |
| 109 | and BKFAV. |
| 110 | BK.. n show only n levels of the stack (starting at the top). |
| 111 | (BK n counts only user functions; BKA n counts all functions.) |
| 112 | BK.. f show stack down to first call of function f |
| 113 | BK.. n f show stack down to nth call of function f |
| 114 | .Ee |
| 115 | .sh 2 Interaction\ with\ \fItrace\fP |
| 116 | FIXIT knows about the standard Franz |
| 117 | trace package, and tries to make |
| 118 | tracing invisible while in the debug loop. However, because |
| 119 | of the way |
| 120 | .i trace |
| 121 | works, it may sometimes be the case that the |
| 122 | functions on the stack are really un\fIintern\fPed atoms that have |
| 123 | the same name as a traced function. (This only happens when |
| 124 | a function is traced WHEREIN another one.) FIXIT will call |
| 125 | attention to |
| 126 | .i trace's |
| 127 | hackery by printing an appropriate tag |
| 128 | next to these stack entries. |
| 129 | |
| 130 | .sh 2 Interaction\ with\ \fIstep\fP |
| 131 | The |
| 132 | .i step |
| 133 | function may be invoked |
| 134 | from within FIXIT via the STEP command. FIXIT initially turns off |
| 135 | stepping when the debug loop is entered. If you step through a function |
| 136 | and get an error, FIXIT will still be invoked normally. At |
| 137 | any time during stepping, you may explicitly enter FIXIT |
| 138 | via the "D" (debug) command. |
| 139 | |
| 140 | .sh 2 Multiple\ error\ levels |
| 141 | FIXIT will evaluate arbitrary LISP |
| 142 | expressions in its debug loop. The evaluation is not done within an |
| 143 | .i errset, |
| 144 | so, if an error occurs, another invocation of the debugger |
| 145 | can be made. When there are multiple errors on the stack, |
| 146 | FIXIT displays a barrier symbol between each level that |
| 147 | looks something like <------------UDF-->. The UDF in |
| 148 | this case stands for UnDefined Function. Thus, the upper |
| 149 | level debug loop was invoked by an undefined function error |
| 150 | that occurred while in the lower loop. |