DIDL is a MACLISP debugger for use on display terminals. The display features of DIDL show user program code in context: for instance, when the user program hits a breakpoint, DIDL automatically shows not only the point at which the breakpoint occurred, but also the surrounding code. Single-stepping moves a cursor through the user code, showing exactly what is to be executed, in context. Because of its size, and the general lack of disk space, the source of DIDL is only on ML:LIBDOC;DIDL >. DIDL works on uncompiled code only. Make your macros non-displacing, or DIDL will get very confused. Loading and invoking Load DIDL from LIBLSP;DIDL FASL. To invoke DIDL, type (didl), or just C-E, if you haven't already assigned some other function to C-E. To single-step some form, type (dstep
) [more on stepping below]. Commands All DIDL commands are one or two letters long, with an optional positive or negative numeric argument. If no argument is given, 1 is assumed. If just a '-' is given, -1 is assumed. Sometimes some commands will prompt for another argument. To abort a command after such a prompt, just rubout past the left end. Some commands also assume some default after prompting. To get the default, just type space. Displaying code DIDL will display your EXPR's or LEXPR's by grinding them and then displaying the ground function. (If you make extensive use of reader macros, you may not recognize your code.) To display a function, type X (for eXamine). You will be prompted for a function name. After the function has been ground and displayed, you can use EMACS-like commands to move around in the function. At any time, the DIDL cursor is pointing to some parenthesized LISP form, and will show you the left or right parenthesis for that form. The following commands are available (an n before a command indicates it takes an optional numeric argument: < Move to the beginning of the function. (Like M-< in EMACS.) > Move to the end of the function. nV Move forward n pages. -nV Move backward n pages. L Redisplay the screen, in case it has been garbled. ( Show the left parenthesis of the current form (normal case). ) Show the right parenthesis. nI Move forward n left parentheses. This is a textual move and ignores the actual nesting of parentheses. nO Move backward n left parentheses. nN Move forward n parentheses at this nesting level. If n n is too large, just move to the last left parenthesis at this level. nP Move backward n left parentheses at this nesting level. Note that unlike EMACS, DIDL will not change its idea of where the current form is, even if, say a V command moves it out of sight. Thus the ( command will always return you to the current form, and may force a different page to be displayed. Single-stepping To single step a lisp form, type (dstep ) DIDL will start stepping the form, and show you what is about to be executed every time you single step. When some atom or (QUOTE ) is about to be evaluated, DIDL will display the form and will type --Continue-- Just hit space or any other character to continue. When some more complicated form is about to be evaluated, DIDL will display the form, in context if possible, and wait for you to type any DIDL command. The commands that continue stepping are: C Continue, without stepping deeper. , Continue without stepping deeper, but show the value of the form that was evaluated, and wait for the user to type space to continue. ; Continue, breaking on deeper evaluations, and show the value form that was evaluated. Displaying the stack During the evaluation of any form, a backtrace of the stack can be displayed. A typical line of the frame display looks like: 1: Broke at AFUNCTION: (COND ((= X 5) (SETQ Y (GROMMET 'APPLE 6 2)) (RETURN The number on the left side is the frame level number. The top frame is numbered 1. The "Broke at" message indicates that the frame to evaluate this form has not actually been created yet; this happens when DIDL stops on a form because of single-stepping or because it has hit a breakpoint. This message is not printed if the frame actually exists. Then the name of the function (if there is one) and as much code as will fit on one line is printed. If the frame display occupies more than one page, you can use the <, >, V, and L commands to look at other pages. One stack frame is always selected, and is indicated by the cursor at the left-hand edge. To select another stack frame, use the following commands: nP Go up n stack frames. nN Go down n stack frames nJ Jump directly to stack frame n. Once you have selected a stack frame, you can display the code for that frame, in context: . Display the user code for this stack frame, if possible. Evaluation in the current frame E Evaluate. E prompts for a form, and then evaluates the form in the environment of the current frame. You can use this command to examine variable bindings. R Return. R prompts for a form, evaluates the form in the environment of the current frame, and then forces a return from this frame with the given value. Breakpoints You can set breakpoints in any uncompiled function at any time. These breakpoints are non-destructive, and do not actually alter the code. BS Set a breakpoint at the current form. You can give the breakpoint a name, or use a supplied default name. BC Clear the breakpoint at the current form. BG Go to the breakpoint you name, displaying where it is. To clear a breakpoint, you will have to BG to it, and then BC it if you want to clear it, unless you are already sitting on it. Associated with each breakpiont can be an if-condition, an action, and a patch. For new breakpoints, all three of these are disabled, and the breakpoint does nothing except unconditionally break when it is reached. An if-condition is a form that is evaluated to determine if the breakpoint should should cause a break. A break will occur only if the if-condition evaluates to non-NIL. An action is a form that is always evaluated whenever a breakpoint is hit, even if the if-condition evaluates to NIL. Naturally, an action is evaluated solely for its side effects. A patch is also a form that is always evaluated whenever a breakpoint is hit. The value of the patch is returned as the value of the form that would have been evaluated at the breakpoint. The code at the breakpoint is never evaluated. BI Set a new if-condition on the current breakpoint, or reenable the old if-condition. -BI Disable the if-condition. BA Set or reeneable an action. -BA Disable the action. BP Set or reenable a patch. -BP Disable the patch. Finally, there are two informational breakpoint commands: BL List all the breakpoints that are currently set. BT Tell about the current breakpoint, listing its if-condtion, action, and patch. When-conditions When conditions cause a break whenever a certain condition is satisfied. They can be used, for instance, to determine when a variable becomes bound to a particular value. There are global and local when-conditions. A local when-condition is checked for only from the current point into the stack and deeper. When the current frame vanishes, the local when-condition disappears. The scope of a local when-condition is the same as that of a Lisp variable. The global when-condition is like a SPECIAL variable. There is only one global when-condition, and it is checked for at all times. When-conditions are evaluated on every call to EVAL, so they will slow your program down. WG Set or reenable the global when-condition. -WG Disable the global when-condition. WL Set or reenable the local when-condition. -WL Disable the local when-condition. WT Tell about the when-conditions. ONce a when-condition break has occurred, it is usually a good idea to disable the when-condition immediately, because it will be true during every subsequent call to EVAL, until the state it depends on is changed. Miscellaneous Q Quit from DIDL. Be careful, as you may return to a previous invocation of DIDL. Use C-G if you want to forget the whole mess. ? Print a list of all commands and descriptions. G Regrind some function. Useful if something has been reloaded or messed up. C-L (control-L) Clear the echo area. C-A Turn of the split screen used by DIDL. Useful if you accidently get out of DIDL, and the screen is still split. C-E Enter DIDL. Same as typing (didl). are ignored. Known problems Having to go to a breakpoint to work on it is a nuisance. The moving-around commands could be improved. B? and W? should print lists of commands. Don't try to use DIDL in conjunction with other debugging programs that use EVALHOOK (e.g. steppers), or lots of things will go wrong. Dan Halbert (DCH@ML, BUG-DIDL@ML) This version July 1980.