? 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.
? (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.
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.
(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.