4.2BSD/usr/lib/lisp/manual/ch15.r
CHAPTER 15
The FIXIT Debugger
15.1. Introduction FIXIT is a debugging environment
for FRANZ LISP users doing program development. This
documentation and FIXIT were written by David S.
Touretzky of Carnegie-Mellon University for MACLisp,
and adapted to FRANZ LISP by Mitch Marcus of Bell
Labs. One of FIXIT's goals is to get the program run-
ning 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 compu-
tation is resumed.
To enter the debugger type (_d_e_b_u_g). The debugger
goes into its own read-eval-print loop. Like the
top-level, the debugger understands certain special
commands. One of these is help, which prints a list
of the available commands. The basic idea is that you
are somewhere in a stack of calls to eval. The com-
mand "bka" is probably the most appropriate for look-
ing at the stack. There are commands to move up and
down. If you want to know the value of "x" as of some
place in the stack, move to that place and type "x"
(or (cdr x) or anything else that you might want to
evaluate). All evaluation is done as of the current
stack position. You can fix the problem by changing
the values of variables, editing functions or expres-
sions in the stack etc. Then you can continue from
the current stack position (or anywhere else) with the
"redo" command. Or you can simply return the right
answer with the "return" command.
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
9
9The FIXIT Debugger 15-1
The FIXIT Debugger 15-2
The result is that program errors can be located and
fixed extremely rapidly, and with a minimum of frus-
tration.
The debugger can only work effectively when extra
information is kept about forms in evaluation by the
lisp system. Evaluating (*_r_s_e_t _t) tells the lisp sys-
tem to maintain this information. If you are debugging
compiled code you should also be sure that the com-
piled code to compiled code linkage tables are
unlinked, i.e do (_s_s_t_a_t_u_s _t_r_a_n_s_l_i_n_k _n_i_l).
(debug [ s_msg ])
NOTE: Within a program, you may enter a debug loop
directly by putting in a call to _d_e_b_u_g where you
would normally put a call to _b_r_e_a_k. Also, within
a break loop you may enter FIXIT by typing _d_e_b_u_g.
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 (_d_e_b_u_g |_j_u_s_t _b_e_f_o_r_e
_l_o_o_p|) into a program to indicate what part of
the program is being debugged.
9
9 Printed: July 21, 1983
The FIXIT Debugger 15-3
____________________________________________________
_F_I_X_I_T _C_o_m_m_a_n_d _S_u_m_m_a_r_y
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 /usr/lisp/doc/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
____________________________________________________
9
9 Printed: July 21, 1983
The FIXIT Debugger 15-4
15.2. Interaction with _t_r_a_c_e FIXIT knows about the
standard Franz trace package, and tries to make trac-
ing invisible while in the debug loop. However,
because of the way _t_r_a_c_e works, it may sometimes be
the case that the functions on the stack are really
un_i_n_t_e_r_ned atoms that have the same name as a traced
function. (This only happens when a function is
traced WHEREIN another one.) FIXIT will call atten-
tion to _t_r_a_c_e'_s hackery by printing an appropriate tag
next to these stack entries.
15.3. Interaction with _s_t_e_p The _s_t_e_p function 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.
15.4. Multiple error levels FIXIT will evaluate arbi-
trary LISP expressions in its debug loop. The evalua-
tion is not done within an _e_r_r_s_e_t, so, if an error
occurs, 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.
9
9 Printed: July 21, 1983