aboutsummaryrefslogtreecommitdiff
path: root/gdb/gdbserver
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/gdbserver')
-rw-r--r--gdb/gdbserver/ChangeLog6
-rw-r--r--gdb/gdbserver/linux-low.c21
-rw-r--r--gdb/gdbserver/mem-break.c17
-rw-r--r--gdb/gdbserver/mem-break.h4
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. */