From patchwork Mon Jul 17 19:20:33 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Baldwin X-Patchwork-Id: 72805 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 1E6773856DD4 for ; Mon, 17 Jul 2023 19:22:31 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mail.baldwin.cx (bigwig.baldwin.cx [66.216.25.90]) by sourceware.org (Postfix) with ESMTPS id DCD4C3858439 for ; Mon, 17 Jul 2023 19:21:01 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org DCD4C3858439 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=FreeBSD.org Authentication-Results: sourceware.org; spf=fail smtp.mailfrom=FreeBSD.org Received: from ralph.com (c-98-35-126-114.hsd1.ca.comcast.net [98.35.126.114]) by mail.baldwin.cx (Postfix) with ESMTPSA id 2BF3C1A84E1C for ; Mon, 17 Jul 2023 15:20:56 -0400 (EDT) From: John Baldwin To: gdb-patches@sourceware.org Subject: [PATCH v2 2/8] fbsd-nat: Defer any ineligible events reported by wait. Date: Mon, 17 Jul 2023 12:20:33 -0700 Message-Id: <20230717192039.13976-3-jhb@FreeBSD.org> X-Mailer: git-send-email 2.40.0 In-Reply-To: <20230717192039.13976-1-jhb@FreeBSD.org> References: <20230717192039.13976-1-jhb@FreeBSD.org> MIME-Version: 1.0 X-Greylist: Sender succeeded SMTP AUTH, not delayed by milter-greylist-4.6.4 (mail.baldwin.cx [0.0.0.0]); Mon, 17 Jul 2023 15:20:56 -0400 (EDT) X-Virus-Scanned: clamav-milter 0.103.1 at mail.baldwin.cx X-Virus-Status: Clean X-Spam-Status: No, score=-12.1 required=5.0 tests=BAYES_00, FORGED_SPF_HELO, GIT_PATCH_0, KAM_DMARC_STATUS, KHOP_HELO_FCRDNS, SPF_HELO_PASS, SPF_SOFTFAIL, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" If wait_1 finds an event for a thread or process that does not match the set of threads and processes previously resumed, defer the event. If the event is for a specific thread, suspend the thread and continue the associated process before waiting for another event. One specific example of such an event is if a thread is created while another thread in the same process hits a breakpoint. If the second thread's event is reported first, the target resume method does not yet "know" about the new thread and will not suspend it via PT_SUSPEND. When wait is called, it will probably return the event from the first thread before the result of the step from second thread. This is the case reported in PR 21497. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=21497 --- gdb/fbsd-nat.c | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/gdb/fbsd-nat.c b/gdb/fbsd-nat.c index f9d8632c0ef..15da555ec3e 100644 --- a/gdb/fbsd-nat.c +++ b/gdb/fbsd-nat.c @@ -1486,7 +1486,40 @@ fbsd_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus, if (is_async_p ()) async_file_flush (); - ptid_t wptid = wait_1 (ptid, ourstatus, target_options); + ptid_t wptid; + while (1) + { + wptid = wait_1 (ptid, ourstatus, target_options); + + /* If no event was found, just return. */ + if (ourstatus->kind () == TARGET_WAITKIND_IGNORE + || ourstatus->kind () == TARGET_WAITKIND_NO_RESUMED) + break; + + /* If an event is reported for a thread or process while + stepping some other thread, suspend the thread reporting the + event and defer the event until it can be reported to the + core. */ + if (!wptid.matches (m_resume_ptid)) + { + add_pending_event (wptid, *ourstatus); + fbsd_nat_debug_printf ("deferring event [%s], [%s]", + target_pid_to_str (wptid).c_str (), + ourstatus->to_string ().c_str ()); + if (wptid.pid () == m_resume_ptid.pid ()) + { + fbsd_nat_debug_printf ("suspending thread [%s]", + target_pid_to_str (wptid).c_str ()); + if (ptrace (PT_SUSPEND, wptid.lwp (), NULL, 0) == -1) + perror_with_name (("ptrace (PT_SUSPEND)")); + if (ptrace (PT_CONTINUE, wptid.pid (), (caddr_t) 1, 0) == -1) + perror_with_name (("ptrace (PT_CONTINUE)")); + } + continue; + } + + break; + } /* If we are in async mode and found an event, there may still be another event pending. Trigger the event pipe so that that the