This minitutorial discusses several topics:

Dropping into the Debugger

Every Lisp Environment comes with a debugger builtin. Given the fact that all environments have the capability to function as "dumb" interpreter ( i.e. do not incrementally compile functions on-the-fly ), this really isn't surprising. Most Lisp "Hackers" like environments that allow them to develop code incrementally with maximum opportunity to "explore". By now I'm sure all of you have manage to drop into the MCL debugger. You can do something as simple as:
     ? car
      > Error: Unbound variable: CAR
      > Whle excuting: SYMBOL-VALUE
      > Type Command-/ to continue , Command-. to abort
      > If continued: Retry getting the value of CAR
           See Restarts... menu item for further choices.
      1 >  
Note that the Listener's cursor has changed from being '?' to '1 >' . This means that you have entered the debugger and are at "break level" one. If you where to type car again you would end up at "break level" two.
       2 >  Command-. 
Meaning, if you were to press Command-period at this point you would drop back to level one. [ The Command key is often refered in by Mac-folks as the "Propeller Key". It might have an "Open Apple" on it too. ] . A quicker way to get back to the Top Level, where the cursor is just "?", is to go to the Eval Menu and choose the Restarts option. Scroll Down until you see the "Return to Toplevel" item and double click.

It is not uncommon to wander the lab and see people at "break level" 23 or some such. This isn't really a good idea since there is a bunch of stuff on the "Stack" waiting for you to resolve the breaks. Unfortunately, ( or not depending on your point of view) you can type in anything at the break prompt that you could type in at the '?' prompt.

Dropping into the Debugger on purpose...

You can drop into the debugger on purpose if you wish. Now why would you want to do that? Don't you remember debugging with breakpoints with your favorite procedural debugger ( e.g. gdb or dbx on a Unix box )? Sometimes you would like to see how your function is behaving at a certain point in time.
        ? (defun  debug-me ( int  num-times  result  )
            (declare ( notinline debug-me ) ) 
												(cond ((= num-times 0 ) result )
	                 ((= num-times 2 ) (break "Help this doesn't work"  ) 
                   (debug-me int num-times ( + int  result)))
	                 ( t (debug-me int (- num-times 1 ) (+ int result ) ) ) ) )
If you now invoke (debug-me 3 5 0 ) the function will run until num-times is equal to 2 and then drop into the debugger. The message that you pass to break is optional [ Look up break with the documentation tool now ]. At this point you can select "Continue" from the Eval Menu to continue evaluation. Which will drop you back into the debugger since the invocation on that condition is remiss. You'll stay at "break level" one since you are purposely invoking break.

Stack Backtrace

Sometimes you land in the debugger and you have NO idea how or why you got there. At this time is call up a Stack Backtrace. You can do this by either typing Command-B or by selecting the "Backtrace" off the of the Tools Menu. The bottom pane of this window contains the current function's argument symbols and values. The top pane is the listing of the functions on the "Stack". Select the debug-me right below the frame for break [ It should be number 1 ]

Let's go back to the Listner window for the moment.

You can look at the local variable bindings without the Stack Backtrace window by typing the following

            1 >   (local num-times )  
                 2
            1 >   (local  2 )     ; the second arg to this function.
You could temporarly fix this by calling
           1 >   (set-local num-times 1 )

or equivalently
          
           1 > (setf (local num-times )  1 )

and then typing

           1 > (continue )   
At which point the functions exits "normally". If you reinvoke that function again and call up the stack backtrace window you can examine the previous invocations. ( If you were to leave the the (notinline ...) declaration out there would only be one invocation of debug-me on the stack.

The Command Menu on the Stack Backtrace will have an "Inspect" option. This will open an inspector window on the function. The inspector window will have a "Disassemble" option on it's command window if you interested in what the assembly language of debug-me looks like.

What else can I do?

You can go on to the minitutorial on stepping and tracing. Placing (break) in your code can be a pain since your have to re-evaluate the function to great the compiler to remove the "breakpoint". However, this recompilation process is quite fast. Or you can try to use the trace facility more effectively. See the trace minitutorial for more info.
Back to MCL and Tool Time

Last modified: by Lyman S. Taylor(lyman@cc.gatech.edu)
(c) copyright Lyman S. Taylor 1995, All rights reserved