diff options
author | Yao Qi <yao.qi@linaro.org> | 2016-07-21 12:12:18 +0100 |
---|---|---|
committer | Yao Qi <yao.qi@linaro.org> | 2016-07-21 12:12:18 +0100 |
commit | bec903c96bc5119e357b4ad2cab99bbee7de628e (patch) | |
tree | 52884d4f74f3a7fe441e815a25ccca4d63142873 /gdb/gdbserver/linux-low.c | |
parent | 63c40ec727109e2bb2956ab95968350df00c1aa1 (diff) | |
download | gdb-bec903c96bc5119e357b4ad2cab99bbee7de628e.zip gdb-bec903c96bc5119e357b4ad2cab99bbee7de628e.tar.gz gdb-bec903c96bc5119e357b4ad2cab99bbee7de628e.tar.bz2 |
Make reinsert_breakpoint thread specific
This patch makes reinsert_breakpoint thread specific, which means we
insert and remove reinsert_breakpoint breakpoints for a specific
thread. This motivation of this change is that I'll use
reinsert_breakpoint for vCont;s on software single step target, so that
GDBserver may insert one reinsert_breakpoint for one thread doing
step-over, and insert one reinsert_breakpoint for another thread doing
vCont;s. After the operation of one thread is finished, GDBserver must
remove reinsert_breakpoint for that thread only.
On the other hand, reinsert_breakpoint is used for step-over nowadays.
GDBserver inserts reinsert_breakpoint, and wait only from the thread
doing step-over. After the step-over is done, GDBserver removes the
reinsert_breakpoint. If there is still any threads need step-over, do
the same again until all threads are finished step-over. In other words,
reinsert_breakpoint is globally thread specific, but in an implicit way.
It is natural to make it explicitly thread specific.
gdb/gdbserver:
2016-07-21 Yao Qi <yao.qi@linaro.org>
* mem-break.c (struct reinsert_breakpoint) <ptid>: New field.
(set_reinsert_breakpoint): New parameter ptid. Callers updated.
(clone_one_breakpoint): Likewise.
(delete_reinsert_breakpoints): Change parameter to thread.
Callers updated.
(has_reinsert_breakpoints): Likewise.
(uninsert_reinsert_breakpoints): Likewise.
(reinsert_reinsert_breakpoints): Likewise.
* mem-break.h (set_reinsert_breakpoint): Update declaration.
(delete_reinsert_breakpoints): Likewise.
(reinsert_reinsert_breakpoints): Likewise.
(uninsert_reinsert_breakpoints): Likewise.
(has_reinsert_breakpoints): Likewise.
Diffstat (limited to 'gdb/gdbserver/linux-low.c')
-rw-r--r-- | gdb/gdbserver/linux-low.c | 37 |
1 files changed, 11 insertions, 26 deletions
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c index 39718c6..c0b2ac0 100644 --- a/gdb/gdbserver/linux-low.c +++ b/gdb/gdbserver/linux-low.c @@ -549,15 +549,11 @@ handle_extended_wait (struct lwp_info **orig_event_lwp, int wstat) && can_software_single_step () && event == PTRACE_EVENT_VFORK) { - struct thread_info *saved_thread = current_thread; - - current_thread = event_thr; /* If we leave reinsert breakpoints there, child will hit it, so uninsert reinsert breakpoints from parent (and child). Once vfork child is done, reinsert them back to parent. */ - uninsert_reinsert_breakpoints (); - current_thread = saved_thread; + uninsert_reinsert_breakpoints (event_thr); } clone_all_breakpoints (child_thr, event_thr); @@ -592,17 +588,13 @@ handle_extended_wait (struct lwp_info **orig_event_lwp, int wstat) if (event_lwp->bp_reinsert != 0 && can_software_single_step ()) { - struct thread_info *saved_thread = current_thread; - /* The child process is forked and stopped, so it is safe to access its memory without stopping all other threads from other processes. */ - current_thread = child_thr; - delete_reinsert_breakpoints (); - current_thread = saved_thread; + delete_reinsert_breakpoints (child_thr); - gdb_assert (has_reinsert_breakpoints (parent_proc)); - gdb_assert (!has_reinsert_breakpoints (child_proc)); + gdb_assert (has_reinsert_breakpoints (event_thr)); + gdb_assert (!has_reinsert_breakpoints (child_thr)); } /* Report the event. */ @@ -656,14 +648,9 @@ handle_extended_wait (struct lwp_info **orig_event_lwp, int wstat) if (event_lwp->bp_reinsert != 0 && can_software_single_step ()) { - struct thread_info *saved_thread = current_thread; - struct process_info *proc = get_thread_process (event_thr); + reinsert_reinsert_breakpoints (event_thr); - current_thread = event_thr; - reinsert_reinsert_breakpoints (); - current_thread = saved_thread; - - gdb_assert (has_reinsert_breakpoints (proc)); + gdb_assert (has_reinsert_breakpoints (event_thr)); } /* Report the event. */ @@ -2632,11 +2619,9 @@ maybe_hw_step (struct thread_info *thread) 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)); + gdb_assert (has_reinsert_breakpoints (thread)); return 0; } } @@ -4224,7 +4209,7 @@ install_software_single_step_breakpoints (struct lwp_info *lwp) next_pcs = (*the_low_target.get_next_pcs) (regcache); for (i = 0; VEC_iterate (CORE_ADDR, next_pcs, i, pc); ++i) - set_reinsert_breakpoint (pc); + set_reinsert_breakpoint (pc, current_ptid); do_cleanups (old_chain); } @@ -4367,7 +4352,7 @@ linux_resume_one_lwp_throw (struct lwp_info *lwp, { /* If the thread isn't doing step-over, there shouldn't be any reinsert breakpoints. */ - gdb_assert (!has_reinsert_breakpoints (proc)); + gdb_assert (!has_reinsert_breakpoints (thread)); } if (fast_tp_collecting == 1) @@ -4860,8 +4845,8 @@ finish_step_over (struct lwp_info *lwp) threads but LWP stopped while doing that. */ if (!can_hardware_single_step ()) { - gdb_assert (has_reinsert_breakpoints (current_process ())); - delete_reinsert_breakpoints (); + gdb_assert (has_reinsert_breakpoints (current_thread)); + delete_reinsert_breakpoints (current_thread); } step_over_bkpt = null_ptid; |