aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarkus Metzger <markus.t.metzger@intel.com>2025-01-10 07:44:22 +0000
committerMarkus Metzger <markus.t.metzger@intel.com>2025-05-26 07:01:15 +0000
commit13403511a110cd7dcf667484dfd2166af339dbfe (patch)
treeee18b5cfb6edb33a4dddcfa71a79fd74224a298b
parent57531a5fa408243cb4443f64aa8380edc5cfccba (diff)
downloadbinutils-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.c36
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;