Insert breakpoint even when the raw breakpoint is found
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-04-25 Pedro Alves <palves@redhat.com> Yao Qi <yao.qi@linaro.org> * mem-break.c (set_raw_breakpoint_at): Create a raw breakpoint object. Insert it if it is not inserted yet. Increase the refcount and link it into the proc's raw breakpoint list.
This commit is contained in:
parent
21edc42f4e
commit
20249ae455
@ -1,3 +1,10 @@
|
||||
2016-04-25 Pedro Alves <palves@redhat.com>
|
||||
Yao Qi <yao.qi@linaro.org>
|
||||
|
||||
* mem-break.c (set_raw_breakpoint_at): Create a raw breakpoint
|
||||
object. Insert it if it is not inserted yet. Increase the
|
||||
refcount and link it into the proc's raw breakpoint list.
|
||||
|
||||
2016-04-25 Yao Qi <yao.qi@linaro.org>
|
||||
|
||||
* breakpoint.c (should_be_inserted): Return 0 if the location's
|
||||
|
@ -390,6 +390,7 @@ set_raw_breakpoint_at (enum raw_bkpt_type type, CORE_ADDR where, int kind,
|
||||
{
|
||||
struct process_info *proc = current_process ();
|
||||
struct raw_breakpoint *bp;
|
||||
struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
|
||||
|
||||
if (type == raw_bkpt_type_sw || type == raw_bkpt_type_hw)
|
||||
{
|
||||
@ -408,32 +409,39 @@ set_raw_breakpoint_at (enum raw_bkpt_type type, CORE_ADDR where, int kind,
|
||||
else
|
||||
bp = find_raw_breakpoint_at (where, type, kind);
|
||||
|
||||
if (bp != NULL)
|
||||
if (bp == NULL)
|
||||
{
|
||||
bp->refcount++;
|
||||
return bp;
|
||||
bp = XCNEW (struct raw_breakpoint);
|
||||
bp->pc = where;
|
||||
bp->kind = kind;
|
||||
bp->raw_type = type;
|
||||
make_cleanup (xfree, bp);
|
||||
}
|
||||
|
||||
bp = XCNEW (struct raw_breakpoint);
|
||||
bp->pc = where;
|
||||
bp->kind = kind;
|
||||
bp->refcount = 1;
|
||||
bp->raw_type = type;
|
||||
|
||||
*err = the_target->insert_point (bp->raw_type, bp->pc, bp->kind, bp);
|
||||
if (*err != 0)
|
||||
if (!bp->inserted)
|
||||
{
|
||||
if (debug_threads)
|
||||
debug_printf ("Failed to insert breakpoint at 0x%s (%d).\n",
|
||||
paddress (where), *err);
|
||||
free (bp);
|
||||
return NULL;
|
||||
*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);
|
||||
|
||||
do_cleanups (old_chain);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bp->inserted = 1;
|
||||
}
|
||||
|
||||
bp->inserted = 1;
|
||||
/* Link the breakpoint in. */
|
||||
bp->next = proc->raw_breakpoints;
|
||||
proc->raw_breakpoints = bp;
|
||||
discard_cleanups (old_chain);
|
||||
|
||||
/* Link the breakpoint in, if this is the first reference. */
|
||||
if (++bp->refcount == 1)
|
||||
{
|
||||
bp->next = proc->raw_breakpoints;
|
||||
proc->raw_breakpoints = bp;
|
||||
}
|
||||
return bp;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user