[4/7] Insert breakpoint even when the raw breakpoint is found
Commit Message
When GDBserver inserts a breakpoint, it looks for raw breakpoint, if
the raw breakpoint is found, increase its refcount, and return. This
doesn't work when it steps over a breakpoint using software single
step and the underneath instruction of breakpoint is branch to self.
When stepping over a breakpoint on ADDR using software single step,
GDBserver uninsert the breakpoint, so the corresponding raw breakpoint
RAW's 'inserted' flag is zero. Then, GDBserver insert single step
breakpoint at the same address ADDR because the instruction is branch
to self, the same raw brekapoint RAW is found, and increase the
refcount. However, the raw breakpoint is not inserted, and the
program won't stop.
gdb/gdbserver:
2016-03-23 Yao Qi <yao.qi@linaro.org>
* mem-break.c (set_raw_breakpoint_at): Insert raw breakpoint
when its refcount is increased.
---
gdb/gdbserver/mem-break.c | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
Comments
On 03/23/2016 04:09 PM, Yao Qi wrote:
> ---
> gdb/gdbserver/mem-break.c | 17 ++++++++++++++++-
> 1 file changed, 16 insertions(+), 1 deletion(-)
>
> diff --git a/gdb/gdbserver/mem-break.c b/gdb/gdbserver/mem-break.c
> index b06f8e9..af01288 100644
> --- a/gdb/gdbserver/mem-break.c
> +++ b/gdb/gdbserver/mem-break.c
> @@ -411,7 +411,22 @@ set_raw_breakpoint_at (enum raw_bkpt_type type, CORE_ADDR where, int kind,
> if (bp != NULL)
> {
> bp->refcount++;
> - return bp;
> +
> + if (!bp->inserted)
> + {
> + *err = the_target->insert_point (bp->raw_type, bp->pc, bp->kind,
> + bp);
> + if (*err != 0)
> + {
> + if (debug_threads)
> + debug_printf ("Failed to insert breakpoint at 0x%s (%d).\n",
> + paddress (where), *err);
> + bp->refcount--;
Can we only increase the refcount if inserting succeeds? gdbserver can
use gdb exceptions nowadays, and even though lots of current gdbserver
code isn't exception safe, it'd be nice to start considering that.
> + return NULL;
> + }
> + bp->inserted = 1;
> + }
> + return bp;
> }
>
> bp = XCNEW (struct raw_breakpoint);
>
Thanks,
Pedro Alves
Pedro Alves <palves@redhat.com> writes:
> Can we only increase the refcount if inserting succeeds? gdbserver can
> use gdb exceptions nowadays, and even though lots of current gdbserver
> code isn't exception safe, it'd be nice to start considering that.
One thing I can think of is to properly decrease refcount if exception
is thrown. Anything else? I don't think we need to worry about the
atomicity of increment and decrement of refcount, because I don't figure
out a case the refcount is updated together in mainline code and in
exception.
@@ -411,7 +411,22 @@ set_raw_breakpoint_at (enum raw_bkpt_type type, CORE_ADDR where, int kind,
if (bp != NULL)
{
bp->refcount++;
- return bp;
+
+ if (!bp->inserted)
+ {
+ *err = the_target->insert_point (bp->raw_type, bp->pc, bp->kind,
+ bp);
+ if (*err != 0)
+ {
+ if (debug_threads)
+ debug_printf ("Failed to insert breakpoint at 0x%s (%d).\n",
+ paddress (where), *err);
+ bp->refcount--;
+ return NULL;
+ }
+ bp->inserted = 1;
+ }
+ return bp;
}
bp = XCNEW (struct raw_breakpoint);