diff options
author | Markus Metzger <markus.t.metzger@intel.com> | 2025-01-10 07:44:22 +0000 |
---|---|---|
committer | Markus Metzger <markus.t.metzger@intel.com> | 2025-05-26 07:01:15 +0000 |
commit | 13403511a110cd7dcf667484dfd2166af339dbfe (patch) | |
tree | ee18b5cfb6edb33a4dddcfa71a79fd74224a298b | |
parent | 57531a5fa408243cb4443f64aa8380edc5cfccba (diff) | |
download | binutils-users/mmetzger/pr19340.zip binutils-users/mmetzger/pr19340.tar.gz binutils-users/mmetzger/pr19340.tar.bz2 |
linux: handle split resume requests with target-async offusers/mmetzger/pr19340
With
target-async off
scheduler-locking off
schedule-multiple on
and
record btrace
the record-btrace target splits resume and stop requests when there are
multiple inferiors and some are replaying while others are recording.
Since wait would be blocking in this configuration, we cannot afford to
split wait requests, as well, or risk a hang.
This leads to scenarios where the target beneath record-btrace received
resume requests for inferiors other than the current inferior, since
that would be handled by the record target above.
stop requests, but has not gotten the chance to wait for the
corresponding event before receiving another resume request.
Handle those cases for the linux native target.
-rw-r--r-- | gdb/linux-nat.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c index 7889b28..fd3237a 100644 --- a/gdb/linux-nat.c +++ b/gdb/linux-nat.c @@ -1770,9 +1770,45 @@ linux_nat_target::resume (ptid_t scope_ptid, int step, enum gdb_signal signo) last_resume_kind to resume_continue. */ iterate_over_lwps (scope_ptid, resume_set_callback); + /* Let's see if we're supposed to resume INFERIOR_PTID at all. */ + if (!inferior_ptid.matches (scope_ptid)) + { + linux_nat_debug_printf ("inferior_ptid %s not in scope %s", + inferior_ptid.to_string ().c_str (), + scope_ptid.to_string ().c_str ()); + iterate_over_lwps (scope_ptid, [=] (struct lwp_info *info) + { + return linux_nat_resume_callback (info, nullptr); + }); + + if (target_can_async_p ()) + { + target_async (true); + /* Tell the event loop we have something to process. */ + async_file_mark (); + } + + return; + } + lp = find_lwp_pid (inferior_ptid); gdb_assert (lp != NULL); + if (!lp->stopped) + { + linux_nat_debug_printf ("inferior_ptid %s not stopped", + inferior_ptid.to_string ().c_str ()); + + if (target_can_async_p ()) + { + target_async (true); + /* Tell the event loop we have something to process. */ + async_file_mark (); + } + + return; + } + /* Remember if we're stepping. */ lp->last_resume_kind = step ? resume_step : resume_continue; |