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/mem-break.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/mem-break.c')
-rw-r--r-- | gdb/gdbserver/mem-break.c | 71 |
1 files changed, 53 insertions, 18 deletions
diff --git a/gdb/gdbserver/mem-break.c b/gdb/gdbserver/mem-break.c index c14219e..65ca3f9 100644 --- a/gdb/gdbserver/mem-break.c +++ b/gdb/gdbserver/mem-break.c @@ -211,6 +211,9 @@ struct other_breakpoint struct reinsert_breakpoint { struct breakpoint base; + + /* Thread the reinsert breakpoint belongs to. */ + ptid_t ptid; }; /* Return the breakpoint size from its kind. */ @@ -1476,17 +1479,21 @@ gdb_breakpoint_here (CORE_ADDR where) } void -set_reinsert_breakpoint (CORE_ADDR stop_at) +set_reinsert_breakpoint (CORE_ADDR stop_at, ptid_t ptid) { - struct breakpoint *bp; + struct reinsert_breakpoint *bp; + + gdb_assert (ptid_get_pid (current_ptid) == ptid_get_pid (ptid)); - bp = set_breakpoint_type_at (reinsert_breakpoint, stop_at, NULL); + bp = (struct reinsert_breakpoint *) set_breakpoint_type_at (reinsert_breakpoint, + stop_at, NULL); + bp->ptid = ptid; } void -delete_reinsert_breakpoints (void) +delete_reinsert_breakpoints (struct thread_info *thread) { - struct process_info *proc = current_process (); + struct process_info *proc = get_thread_process (thread); struct breakpoint *bp, **bp_link; bp = proc->breakpoints; @@ -1494,11 +1501,17 @@ delete_reinsert_breakpoints (void) while (bp) { - if (bp->type == reinsert_breakpoint) + if (bp->type == reinsert_breakpoint + && ptid_equal (((struct reinsert_breakpoint *) bp)->ptid, + ptid_of (thread))) { + struct thread_info *saved_thread = current_thread; + + current_thread = thread; *bp_link = bp->next; release_breakpoint (proc, bp); bp = *bp_link; + current_thread = saved_thread; } else { @@ -1578,21 +1591,29 @@ uninsert_all_breakpoints (void) } void -uninsert_reinsert_breakpoints (void) +uninsert_reinsert_breakpoints (struct thread_info *thread) { - struct process_info *proc = current_process (); + struct process_info *proc = get_thread_process (thread); struct breakpoint *bp; for (bp = proc->breakpoints; bp != NULL; bp = bp->next) { - if (bp->type == reinsert_breakpoint) + if (bp->type == reinsert_breakpoint + && ptid_equal (((struct reinsert_breakpoint *) bp)->ptid, + ptid_of (thread))) { gdb_assert (bp->raw->inserted > 0); /* Only uninsert the raw breakpoint if it only belongs to a reinsert breakpoint. */ if (bp->raw->refcount == 1) - uninsert_raw_breakpoint (bp->raw); + { + struct thread_info *saved_thread = current_thread; + + current_thread = thread; + uninsert_raw_breakpoint (bp->raw); + current_thread = saved_thread; + } } } } @@ -1642,8 +1663,9 @@ reinsert_breakpoints_at (CORE_ADDR pc) } int -has_reinsert_breakpoints (struct process_info *proc) +has_reinsert_breakpoints (struct thread_info *thread) { + struct process_info *proc = get_thread_process (thread); struct breakpoint *bp, **bp_link; bp = proc->breakpoints; @@ -1651,7 +1673,9 @@ has_reinsert_breakpoints (struct process_info *proc) while (bp) { - if (bp->type == reinsert_breakpoint) + if (bp->type == reinsert_breakpoint + && ptid_equal (((struct reinsert_breakpoint *) bp)->ptid, + ptid_of (thread))) return 1; else { @@ -1677,19 +1701,27 @@ reinsert_all_breakpoints (void) } void -reinsert_reinsert_breakpoints (void) +reinsert_reinsert_breakpoints (struct thread_info *thread) { - struct process_info *proc = current_process (); + struct process_info *proc = get_thread_process (thread); struct breakpoint *bp; for (bp = proc->breakpoints; bp != NULL; bp = bp->next) { - if (bp->type == reinsert_breakpoint) + if (bp->type == reinsert_breakpoint + && ptid_equal (((struct reinsert_breakpoint *) bp)->ptid, + ptid_of (thread))) { gdb_assert (bp->raw->inserted > 0); if (bp->raw->refcount == 1) - reinsert_raw_breakpoint (bp->raw); + { + struct thread_info *saved_thread = current_thread; + + current_thread = thread; + reinsert_raw_breakpoint (bp->raw); + current_thread = saved_thread; + } } } } @@ -2113,7 +2145,7 @@ clone_agent_expr (const struct agent_expr *src_ax) /* Deep-copy the contents of one breakpoint to another. */ static struct breakpoint * -clone_one_breakpoint (const struct breakpoint *src) +clone_one_breakpoint (const struct breakpoint *src, ptid_t ptid) { struct breakpoint *dest; struct raw_breakpoint *dest_raw; @@ -2174,6 +2206,9 @@ clone_one_breakpoint (const struct breakpoint *src) = XCNEW (struct reinsert_breakpoint); dest = (struct breakpoint *) reinsert_dest; + /* Since reinsert breakpoint is thread specific, don't copy + thread id from SRC, use ID instead. */ + reinsert_dest->ptid = ptid; } else gdb_assert_not_reached ("unhandled breakpoint type"); @@ -2201,7 +2236,7 @@ clone_all_breakpoints (struct thread_info *child_thread, for (bp = parent_proc->breakpoints; bp != NULL; bp = bp->next) { - new_bkpt = clone_one_breakpoint (bp); + new_bkpt = clone_one_breakpoint (bp, ptid_of (child_thread)); APPEND_TO_LIST (new_list, new_bkpt, bkpt_tail); APPEND_TO_LIST (new_raw_list, new_bkpt->raw, raw_bkpt_tail); } |