Re: [RFA/PATCH] breakpoint.c: fix until command

Michael Elizabeth Chastain
2003-01-03T06:49:44Z

Daniel J says:

> With a modern compiler, "after $PC" is pretty much meaningless. Not
> going to fly. It could be re-ordered; there can be out-of-line code in
> separate sections.

I'm thinking of a famous promise in the gcc manual:

Without `-O', the compiler's goal is to reduce the cost of
compilation and to make debugging produce the expected results.
Statements are independent: if you stop the program with a
breakpoint between statements, you can then assign a new value to
any variable or change the program counter to any other statement
in the function and get exactly the results you would expect from
the source code.

Statements which are independent can could be re-ordered, like moving
error-handling blocks far away to a different section of the address
space to improve cache locality. So we might need additional promises.
I think it would be reasonable for us to ask for them if we decide
we need them.

With optimized code, I agree, gdb is just going to degrade, the way
it does now with stepping through for loops.

Unfortunately for us, the no-argument form of 'until' pretty much depends
on the "after" property. Perhaps we could re-implement 'until' to set
a breakpoint on *every* source line after the current source line and
then get rid of the object code address comparison and the steppy
implementation. That would take some work and doubtless have its own
issues.

> I don't see any reason for that to go to a single-steppy behavior
> however.

My primitive impulse is to have 'until' and 'until LOCATION' use the same
mechanism so that they will behave the same way in all the hard cases.

I admit, this is not a compelling reason, it just feels right to me.

> And what it means when LOCATION is not in function is not clear.
> The problem is, do we know well enough when LOCATION is or is not in
> FUNCTION to make any statements?

If we can get more promises from gcc, then we can know this is true
in un-optimized code.

We can also know whether LOCATION is in the function if we operate
on LOCATION while it is in source form before we translate to object
code location. If we are in foo:67, and the user asks to 'until 70',
then I bet we can figure out that '70' is in the current function no
matter where its object code addresses are.

> The implicit breakpoint at the return is still somewhat useful, IMHO.
> It's not quite the same; when you hit one of the breakpoints (or stop
> for some other reason), both vanish. I don't think that's what tbreaks
> do.

And lo ... 'finish'.

This command has a non-intuitive name. It is actually the same as
'continue' plus a momentary breakpoint on the return. The momentary
breakpoint vanishes as soon as proceed() returns.

It looks perfectly okay to use 'finish' almost all the time, even if you
expect the momentary breakpoint not to be hit. In fact, I'm personally
going to try debugging this way, because I've had too many Ellen Feiss
moments where the debugger didn't hit the breakpoint I thought it would
hit and then it went beep beep beep beep and ate all my stack frames
and the inferior was back in something useless like main().

(Just "define cont \n finish \n end" and try debugging for a while,
it's kind of nice to lose only one stack frame at a time!)

The current implementation of 'until LOCATION' looks close to 'tbreak
LOCATION; finish". 'until LOCATION' uses a momentary breakpoint on
'LOCATION' and 'tbreak LOCATION' (obviously) uses a tbreak. But they
both set momentary breakpoints on the return.

> I'm still undecided about what to do if LOCATION is not in the
> function. Maybe you're right and we should make this an error. What
> if LOCATION is in the frame that called this one?

I still say, make it an error. I like the idea that 'until' is all
about the current frame.

And it seems weird. The user should know it's not in the current
frame when they type in in LOCATION. And they know that 'until' rolls
right over function calls. So the user knows that LOCATION is in a
calling frame. This collides head on with the idea that 'until' has
a momentary breakpoint on the return location in the caller. Try it.
It will always take the return-breakpoint. It will never reach LOCATION.

So 'until LOCATION' behaves very similar to 'finish' and the user knows
this, so they should just type 'finish'. If the user wants to hit the
return-breakpoint, they want 'finish'. If they do not want the
return-breakpoint, they want 'tbreak/continue' (almost). Either way,
'until LOCATION' is redundant with something else.

Also try 'until LOCATION' where LOCATION gets hit in an inner frame.
Right now it also behaves like a 'finish' because of the next-y behavior
of function calls .

So 'until LOCATION' is already practically useless if LOCATION is not
in the current frame, either way.

Michael C