From 13403511a110cd7dcf667484dfd2166af339dbfe Mon Sep 17 00:00:00 2001 From: Markus Metzger Date: Fri, 10 Jan 2025 07:44:22 +0000 Subject: [PATCH] linux: handle split resume requests with target-async off 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. --- gdb/linux-nat.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c index 7889b2882e1..fd3237ad696 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; -- 2.47.2