[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

stepper, breakpoints

Bill and I were talking at lunch yesterday about the stepper.  He pointed
out that I have never sent mail to the group saying what I though the
interface to the stepper should be.  This message is an attempt to rectify
that.  I'm also going to mumble about what breakpoint functionality there
should be.  Note: I'm only talking about the TTY interface right now.

First of all, the stepper should not be seperate from the regular debugger.
All the commands for utilizing the stepper should just be regular debugger
commands.  The one exception is the STEP macro.  It basically looks like:

   (defmacro step (form)
     `(funcall (insert-function-start-step-breakpoint #'(lambda () ,@form))))

[We will want to wrap a compile around the lambda until we have breakpoints
in interpreted code.]

Stepper commands:

Whenever you drop into the debugger due to a breakpoint, the following
commands should be available:

STEP - figure out the next code location after the breakpoint that dropped
us into the debugger, put a breakpoint there, and continue execution.

NEXT - same as STEP, but if the next thing is a function call, then skip
over it.  When NEXT is used to skip over a function call, we shouldn't stop
in a recursive invocation of the same function.  For example, if you are
stepping though the a recursive factorial function and you NEXT when it's
about to call (fact 5), it will next stop when fact is returning 120.
Therefore, it can't just blindly put a breakpoint at the return site,
because that will be hit when (fact 1), (fact 2), (fact 3), and (fact 4)
are returning also.

FINISH - add a function-end breakpoint to the function that was running
when we hit the breakpoint that dropped us into the debugger, and continue
execution.  If an optional frame is supplied, break when that frame returns

Whenever the debugger is entered because of a stepper installed breakpoint,
that breakpoint is cleared.  So if you step partway though a function, then
use GO to unconditionally continue execution, you will not end up in the
debugger again if that function is re-executed.

Breakpoint commands:

In this section, whenever I say ``breakpoint'' I really mean ``debugger
breakpoint.''  Breakpoints installed by the tracer and stepper, etc. do not
show up as far as these commands are concerned.

I'm not sure what interface I want for installing breakpoints.  But there
*must* be a TTY interface to this, because there are a lot of times when
using CLX is not an option.  Like, when trying to debug CLX, for example.

You should be able to list all the breakpoints currently installed, along
with whatever other properties are associated with them.

There should be commands to activate and deactivate individual breakpoints,
and batches of breakpoints.  Deactivated breakpoints are still listed, but
they are just marked inactive.

You should be able to specify an ignore count for a breakpoint.  The next N
invocations of that breakpoint will be ignored.

You should be able to specify a trigger condition for a breakpoint.  This
expression should be evaluated in the lexical context of where the
breakpoint is installed.

You should be able to specify a list of debugger commands to execute
whenever the breakpoint is hit.  Having "GO" as the last command in this
list would keep you out of the debugger.

You should also be able to annotate a breakpoint as ``silent.''  When a
silent breakpoint is hit, nothing is printed out beyond the the debugger
prompt.  This is useful when you have a breakpoint that prints a bunch of
stuff via the commands option above and then continues.  You may not want
to have your output cluttered up with lots of noise about what restarts are

When you redefine a function that you have put a bunch of breakpoints in,
it should either move the breakpoints to the new function, or flush them
(with a warning) if it can't figure out the corresponding place.  If we
can't come up with a good heuristic for guessing the corresponding place,
then we should just flush the old breakpoints.

And, of course, you need a way to delete old breakpoints.

Note: if you have a debugger breakpoint and a stepper breakpoint at the
same code location, you don't enter the debugger twice.  If the debugger
breakpoint would not normally trigger (failed condition or non-zero ignore
count, etc.) you still drop in the debugger, but the message should look
just like the debugger breakpoint wasn't there (i.e. use the normal stepper
message).  If the debugger breakpoint triggers, then it should look like
the stepper breakpoint wasn't there.