FIXIT - A New MacLisp Debugger David S. Touretzky Carnegie-Mellon University (modified by Mitch Marcus for Franz Lisp) FIXIT is a debugging environment for MacLisp users doing program development. One of FIXIT's goals is to get the program running again as quickly as possible. The user is assisted in making changes to his functions "on the fly", i.e. in the midst of execution, and then computation is resumed. When it is not immediately obvious why an error has occurred or how the program got itself into its current state, FIXIT comes to the rescue by providing a powerful debugging loop in which the user can: examine the stack evaluate expressions in context enter stepping mode restart the computation at any point The result is that program errors can be located and fixed extremely rapidly, and with a minimum of frustration. How to call FIXIT: FIXIT is usually loaded by the .lisprc file as part of a user's standard initialization sequence. FIXIT may be loaded at any time by typing (fasl "/m2/c122/ucb/lib/lisp/fixit"). Within a program, you may enter a debug loop directly by putting in a call to (DEBUG) where you would normally put a call to BREAK. Also, within a break loop you may enter FIXIT by typing (DEBUG). If an argument is given to DEBUG, it is treated as a message to be printed before the debug loop is entered. Thus you can put (DEBUG |just before loop|) into a program to indicate what part of the program is being debugged. FIXIT Command Summary --------------------- TOP go to top of stack (latest expression) BOT go to bottom of stack (first expression) P show current expression (with ellipsis) PP show current expression in full WHERE give current stack position HELP types the abbreviated command summary found in /m2/c122/ucb/lib/lisp/fixit.help. H and ? work too. U go up one stack frame U n go up n stack frames U f go up to the next occurrence of function f U n f go up n occurrences of function f UP go up to the next user-written function UP n go up n user-written functions ...the DN and DNFN commands are similar, but go down ...instead of up. OK resume processing; continue after an error or debug loop REDO restart the computation with the current stack frame. The OK command is equivalent to TOP followed by REDO. REDO f restart the computation with the last call to function f. (The stack is searched downward from the current position.) STEP restart the computation at the current stack frame, but first turn on stepping mode. (Assumes Rich stepper is loaded.) RETURN e return from the current position in the computation with the value of expression e. BK.. print a backtrace. There are many backtrace commands, formed by adding suffixes to the BK command. "BK" gives a backtrace showing only user-written functions, and uses ellipsis. The BK command may be suffixed by one or more of the following modifiers: ..F.. show function names instead of expressions ..A.. show all functions/expressions, not just user-written ones ..V.. show variable bindings as well as functions/expressions ..E.. show everything in the expression, i.e. don't use ellipsis ..C.. go no further than the current position on the stack Some of the more useful combinations are BKFV, BKFA, and BKFAV. BK.. n show only n levels of the stack (starting at the top). (BK n counts only user functions; BKA n counts all functions.) BK.. f show stack down to first call of function f BK.. n f show stack down to nth call of function f ^LInteraction with TRACE: FIXIT knows about the standard Franz trace package, and tries to make tracing invisible while in the debug loop. However, because of the way TRACE works, it may sometimes be the case that the functions on the stack are really unINTERNed atoms that have the same name as a traced function. (This only happens when a function is traced WHEREIN another one.) FIXIT will call attention to TRACE's hackery by printing an appropriate tag next to these stack entries. Interaction with STEP: The Rich stepper may be invoked from within FIXIT via the STEP command. FIXIT initially turns off stepping when the debug loop is entered. If you step through a function and get an error, FIXIT will still be invoked normally. At any time during stepping, you may explicitly enter FIXIT via the "D" (debug) command. Multiple error levels: FIXIT will evaluate arbitrary LISP expressions in its debug loop. The evaluation is not done within an ERRSET, so, if an error occurrs, another invocation of the debugger can be made. When there are multiple errors on the stack, FIXIT displays a barrier symbol between each level that looks something like <------------UDF-->. The UDF in this case stands for UnDefined Function. Thus, the upper level debug loop was invoked by an undefined function error that occurred while in the lower loop. (This version of FIXIT for Franz lacks It also lacks the hooks into error and software interrupt handling of the CMU version, due to the continuing development of the Franz interrupt and error handling facility. Both features will probably reappear in the near future - Mitch Marcus)