diff options
author | Simon Marchi <simon.marchi@efficios.com> | 2021-12-01 09:40:03 -0500 |
---|---|---|
committer | Simon Marchi <simon.marchi@efficios.com> | 2021-12-08 21:00:39 -0500 |
commit | 577d2167bbed078e99fe8b704f936be8ac7cf83d (patch) | |
tree | 7718ef8811dfd386cc891ab2180dfecd7271386c | |
parent | 28561a655942f8e2a70a3b64e867223a60aae7b1 (diff) | |
download | binutils-577d2167bbed078e99fe8b704f936be8ac7cf83d.zip binutils-577d2167bbed078e99fe8b704f936be8ac7cf83d.tar.gz binutils-577d2167bbed078e99fe8b704f936be8ac7cf83d.tar.bz2 |
gdb: move clearing of tp->pending_follow to follow_fork_inferior
A following patch will change targets so that when they detach an
inferior, they also detach any pending fork children this inferior may
have. While doing this, I hit a case where we couldn't differentiate
two cases, where in one we should detach the fork detach but not in the
other.
Suppose we continue past a fork with "follow-fork-mode == child" &&
"detach-on-fork on". follow_fork_inferior calls target_detach to detach
the parent. In that case the target should not detach the fork
child, as we'll continue debugging the child. As of now, the
tp->pending_follow field of the thread who called fork still contains
the details about the fork.
Then, suppose we run to a fork catchpoint and the user types "detach".
In that case, the target should detach the fork child in addition to the
parent. In that case as well, the tp->pending_follow field contains
the details about the fork.
To allow targets to differentiate the two cases, clear
tp->pending_follow a bit earlier, when following a fork. Targets will
then see that tp->pending_follow contains TARGET_WAITKIND_SPURIOUS, and
won't detach the fork child.
As of this patch, no behavior changes are expected.
Change-Id: I537741859ed712cb531baaefc78bb934e2a28153
-rw-r--r-- | gdb/infrun.c | 28 |
1 files changed, 18 insertions, 10 deletions
diff --git a/gdb/infrun.c b/gdb/infrun.c index e4739ed..a1264f7 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -601,6 +601,23 @@ holding the child stopped. Try \"set detach-on-fork\" or \ if (child_inf != nullptr) gdb_assert (!child_inf->thread_list.empty ()); + /* Clear the parent thread's pending follow field. Do this before calling + target_detach, so that the target can differentiate the two following + cases: + + - We continue past a fork with "follow-fork-mode == child" && + "detach-on-fork on", and therefore detach the parent. In that + case the target should not detach the fork child. + - We run to a fork catchpoint and the user types "detach". In that + case, the target should detach the fork child in addition to the + parent. + + The former case will have pending_follow cleared, the later will have + pending_follow set. */ + thread_info *parent_thread = find_thread_ptid (parent_inf, parent_ptid); + gdb_assert (parent_thread != nullptr); + parent_thread->pending_follow.set_spurious (); + /* Detach the parent if needed. */ if (follow_child) { @@ -668,7 +685,6 @@ follow_fork () { bool follow_child = (follow_fork_mode_string == follow_fork_mode_child); bool should_resume = true; - struct thread_info *tp; /* Copy user stepping state to the new inferior thread. FIXME: the followed fork child thread should have a copy of most of the @@ -714,7 +730,7 @@ follow_fork () } } - tp = inferior_thread (); + thread_info *tp = inferior_thread (); /* If there were any forks/vforks that were caught and are now to be followed, then do so now. */ @@ -768,14 +784,6 @@ follow_fork () } else { - /* This pending follow fork event is now handled, one way - or another. The previous selected thread may be gone - from the lists by now, but if it is still around, need - to clear the pending follow request. */ - tp = find_thread_ptid (parent_targ, parent); - if (tp) - tp->pending_follow.set_spurious (); - /* This makes sure we don't try to apply the "Switched over from WAIT_PID" logic above. */ nullify_last_target_wait_ptid (); |