aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/gdbserver/ChangeLog10
-rw-r--r--gdb/gdbserver/linux-low.c35
-rw-r--r--gdb/gdbserver/mem-break.c22
-rw-r--r--gdb/gdbserver/mem-break.h4
4 files changed, 67 insertions, 4 deletions
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog
index 079507a..70f64ff 100644
--- a/gdb/gdbserver/ChangeLog
+++ b/gdb/gdbserver/ChangeLog
@@ -1,3 +1,13 @@
+2016-06-17 Yao Qi <yao.qi@linaro.org>
+
+ * linux-low.c (maybe_hw_step): New function.
+ (linux_resume_one_lwp_throw): Call maybe_hw_step.
+ (finish_step_over): Switch current_thread to lwp temporarily,
+ and assert has_reinsert_breakpoints returns true.
+ (proceed_one_lwp): Call maybe_hw_step.
+ * mem-break.c (has_reinsert_breakpoints): New function.
+ * mem-break.h (has_reinsert_breakpoints): Declare.
+
2016-06-02 Jon Turney <jon.turney@dronecode.org.uk>
* win32-low.c (win32_create_inferior): Add pointer casts for C++.
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index 81134b0..77c296c 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -2495,6 +2495,24 @@ linux_low_filter_event (int lwpid, int wstat)
return child;
}
+/* Return true if THREAD is doing hardware single step. */
+
+static int
+maybe_hw_step (struct thread_info *thread)
+{
+ if (can_hardware_single_step ())
+ return 1;
+ else
+ {
+ struct process_info *proc = get_thread_process (thread);
+
+ /* GDBserver must insert reinsert breakpoint for software
+ single step. */
+ gdb_assert (has_reinsert_breakpoints (proc));
+ return 0;
+ }
+}
+
/* Resume LWPs that are currently stopped without any pending status
to report, but are resumed from the core's perspective. */
@@ -4215,9 +4233,9 @@ linux_resume_one_lwp_throw (struct lwp_info *lwp,
fprintf (stderr, "BAD - reinserting and suspended(%d).\n",
lwp->suspended);
}
-
- step = 1;
}
+
+ step = maybe_hw_step (thread);
}
if (fast_tp_collecting == 1)
@@ -4689,9 +4707,13 @@ finish_step_over (struct lwp_info *lwp)
{
if (lwp->bp_reinsert != 0)
{
+ struct thread_info *saved_thread = current_thread;
+
if (debug_threads)
debug_printf ("Finished step over.\n");
+ current_thread = get_lwp_thread (lwp);
+
/* Reinsert any breakpoint at LWP->BP_REINSERT. Note that there
may be no breakpoint to reinsert there by now. */
reinsert_breakpoints_at (lwp->bp_reinsert);
@@ -4705,9 +4727,13 @@ finish_step_over (struct lwp_info *lwp)
because we were stepping over a breakpoint, and we hold all
threads but LWP stopped while doing that. */
if (!can_hardware_single_step ())
- delete_reinsert_breakpoints ();
+ {
+ gdb_assert (has_reinsert_breakpoints (current_process ()));
+ delete_reinsert_breakpoints ();
+ }
step_over_bkpt = null_ptid;
+ current_thread = saved_thread;
return 1;
}
else
@@ -5029,7 +5055,8 @@ proceed_one_lwp (struct inferior_list_entry *entry, void *except)
if (debug_threads)
debug_printf (" stepping LWP %ld, reinsert set\n",
lwpid_of (thread));
- step = 1;
+
+ step = maybe_hw_step (thread);
}
else
step = 0;
diff --git a/gdb/gdbserver/mem-break.c b/gdb/gdbserver/mem-break.c
index 363d7ca..3313459 100644
--- a/gdb/gdbserver/mem-break.c
+++ b/gdb/gdbserver/mem-break.c
@@ -1553,6 +1553,28 @@ reinsert_breakpoints_at (CORE_ADDR pc)
}
}
+int
+has_reinsert_breakpoints (struct process_info *proc)
+{
+ struct breakpoint *bp, **bp_link;
+
+ bp = proc->breakpoints;
+ bp_link = &proc->breakpoints;
+
+ while (bp)
+ {
+ if (bp->type == reinsert_breakpoint)
+ return 1;
+ else
+ {
+ bp_link = &bp->next;
+ bp = *bp_link;
+ }
+ }
+
+ return 0;
+}
+
void
reinsert_all_breakpoints (void)
{
diff --git a/gdb/gdbserver/mem-break.h b/gdb/gdbserver/mem-break.h
index 4d9a76c..b84dc1e 100644
--- a/gdb/gdbserver/mem-break.h
+++ b/gdb/gdbserver/mem-break.h
@@ -163,6 +163,10 @@ void delete_reinsert_breakpoints (void);
void reinsert_breakpoints_at (CORE_ADDR where);
+/* Process PROC has reinsert breakpoints or not. */
+
+int has_reinsert_breakpoints (struct process_info *proc);
+
/* Uninsert breakpoints at WHERE (and change their status to
uninserted). This still leaves the breakpoints in the table. */