Keeping breakpoints inserted

Vladimir Prus
2007-11-29T19:24:41Z

One of the infrastructure bits necessary for the non-stop threads
debugging is always-inserted-breakpoints mode. If GDB has stopped
one thread, and other threads are running, we want those other threads
to still hit breakpoints and watchpoints. However, current GDB removes
all breakpoints from the target before giving user a prompt, and this
has to change.

I've spend quite time examining breakpoint.c and infrun.c and
cleaning/localizing the decisions as to when breakpoints are
inserted/removed, and I believe I now have a fully workable plan
to make breakpoints always inserted. We need to:

1. Generally, whenever a breakpoint is added, changed, or
removed, immediately communicate this change to the target.

2. In order to do that, we need to have a single function called on each
breakpoint change. That function will be responsible to update
bp_location_chain, using locations of existing breakpoint, removing
breakpoint locations that are no longer necessary, and inserting newly
added locations. Since we can have several breakpoints at the same address,
the function should take care not to remove location belonging to a
deleted breakpoint, if there's location at the same address belonging
to a still-present breakpoint.

Specifically, the function will walk over current bp_location_chain.
For each location:

- if no breakpoint has a location with the same address,
we remove the location from target
- if no breakpoint has this bp_location* object, we free it.

All locations present in some breakpoint but not yet present in
bp_location_chain are added to bp_location_chain and inserted to target.

3. The functions that read memory should be modified to restore memory
content overwritten by breakpoints. I believe there's a
single function that is in all memory-reading code paths, so this change is
easy.

4. infrun.c should be modified to avoid removing breakpoints when
we stop -- most probably under control of a new variable.

5. Sometimes, infrun.c still need to remove breakpoints -- in particular
when stepping over them. We'll implement smart code that allows to
step over breakpoint without removing it -- Jim will separately post details
on this. For watchpoints, we still have to remove them when stepping
over watchpoint (for the case of non-continuable non-steppable watchpoints).

6. It's possible that we get an error when inserting breakpoint.
In present GDB, such an error will be printed when we try to resume
target, and the target won't be resumed. With always-inserted mode,
the error will be printed when we add or change the breakpoint. However,
resuming target with not-inserted breakpoint still seems wrong behaviour,
so we'll try to insert breakpoints again when resuming, and if that fails,
stop.

Anybody has comments on this approach?

- Volodya