diff options
Diffstat (limited to 'gdb/gdbserver')
-rw-r--r-- | gdb/gdbserver/ChangeLog | 6 | ||||
-rw-r--r-- | gdb/gdbserver/linux-low.c | 21 | ||||
-rw-r--r-- | gdb/gdbserver/mem-break.c | 17 | ||||
-rw-r--r-- | gdb/gdbserver/mem-break.h | 4 |
4 files changed, 41 insertions, 7 deletions
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog index 87ce9e7..f48d7f2 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -1,5 +1,11 @@ 2015-11-30 Antoine Tremblay <antoine.tremblay@ericsson.com> + * linux-low.c (linux_wait_1): Fix pc advance condition. + * mem-break.c (reinsert_breakpoint_inserted_here): New function. + * mem-break.h (reinsert_breakpoint_inserted_here): New declaration. + +2015-11-30 Antoine Tremblay <antoine.tremblay@ericsson.com> + * linux-arm-low.c (arm_is_thumb_mode): New function. (arm_breakpoint_at): Use arm_is_thumb_mode. (arm_breakpoint_kind_from_current_state): New function. diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c index 207a5ba..b29f54e 100644 --- a/gdb/gdbserver/linux-low.c +++ b/gdb/gdbserver/linux-low.c @@ -3071,14 +3071,21 @@ linux_wait_1 (ptid_t ptid, return ptid_of (current_thread); } - /* If step-over executes a breakpoint instruction, it means a - gdb/gdbserver breakpoint had been planted on top of a permanent - breakpoint. The PC has been adjusted by - check_stopped_by_breakpoint to point at the breakpoint address. - Advance the PC manually past the breakpoint, otherwise the - program would keep trapping the permanent breakpoint forever. */ + /* If step-over executes a breakpoint instruction, in the case of a + hardware single step it means a gdb/gdbserver breakpoint had been + planted on top of a permanent breakpoint, in the case of a software + single step it may just mean that gdbserver hit the reinsert breakpoint. + The PC has been adjusted by check_stopped_by_breakpoint to point at + the breakpoint address. + So in the case of the hardware single step advance the PC manually + past the breakpoint and in the case of software single step advance only + if it's not the reinsert_breakpoint we are hitting. + This avoids that a program would keep trapping a permanent breakpoint + forever. */ if (!ptid_equal (step_over_bkpt, null_ptid) - && event_child->stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT) + && event_child->stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT + && (event_child->stepping + || !reinsert_breakpoint_inserted_here (event_child->stop_pc))) { int increment_pc = 0; int breakpoint_kind = 0; diff --git a/gdb/gdbserver/mem-break.c b/gdb/gdbserver/mem-break.c index 11c21db..ea1140a 100644 --- a/gdb/gdbserver/mem-break.c +++ b/gdb/gdbserver/mem-break.c @@ -1662,6 +1662,23 @@ hardware_breakpoint_inserted_here (CORE_ADDR addr) return 0; } +/* See mem-break.h. */ + +int +reinsert_breakpoint_inserted_here (CORE_ADDR addr) +{ + struct process_info *proc = current_process (); + struct breakpoint *bp; + + for (bp = proc->breakpoints; bp != NULL; bp = bp->next) + if (bp->type == reinsert_breakpoint + && bp->raw->pc == addr + && bp->raw->inserted) + return 1; + + return 0; +} + static int validate_inserted_breakpoint (struct raw_breakpoint *bp) { diff --git a/gdb/gdbserver/mem-break.h b/gdb/gdbserver/mem-break.h index d199cc4..40b66a7 100644 --- a/gdb/gdbserver/mem-break.h +++ b/gdb/gdbserver/mem-break.h @@ -100,6 +100,10 @@ int software_breakpoint_inserted_here (CORE_ADDR addr); int hardware_breakpoint_inserted_here (CORE_ADDR addr); +/* Returns TRUE if there's any reinsert breakpoint at ADDR. */ + +int reinsert_breakpoint_inserted_here (CORE_ADDR addr); + /* Clear all breakpoint conditions and commands associated with a breakpoint. */ |