From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id +I7zL/bTIGK5WgAAWB0awg (envelope-from ) for ; Thu, 03 Mar 2022 09:43:02 -0500 Received: by simark.ca (Postfix, from userid 112) id C265B1F3CA; Thu, 3 Mar 2022 09:43:02 -0500 (EST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,MAILING_LIST_MULTI, RDNS_DYNAMIC,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from sourceware.org (ip-8-43-85-97.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id 3799B1F0D2 for ; Thu, 3 Mar 2022 09:43:02 -0500 (EST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id F0B793857C7D for ; Thu, 3 Mar 2022 14:43:01 +0000 (GMT) Received: from mail-wr1-f43.google.com (mail-wr1-f43.google.com [209.85.221.43]) by sourceware.org (Postfix) with ESMTPS id 43CE43857C62 for ; Thu, 3 Mar 2022 14:40:46 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 43CE43857C62 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=palves.net Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-wr1-f43.google.com with SMTP id d3so8205861wrf.1 for ; Thu, 03 Mar 2022 06:40:46 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=FNDGPmiGFW739xMsChvg9xpIcN6O+KJAl7iRnQbuNMw=; b=04uYTdtkSlzQmMZ6Q50w8ORxJpb0xPAggcPS0GTXzrajhhE8WOAHZ2Pmu24pLdx3iz JMq/SKrP6a3Yg7wNI1Le0RKOStDB9bHR1LRurJQvQcgQ6xbtq7yvg6Z4m6b7YBnx2AVG 1UIjqWJwukVSw+4Qk23FKGn8EebomS3azmBGskweijYwPkCps5lK1sq8jW6M4l10eAkM lRFZmG94HCXM5MbF8JZ8gitC+7qSBKOsT3XSL33R1987Os4fPOV2qQ8fNkmTB9h9w1DT gX3oULiHv022/VArEHB0wYrRSbjXFOOLWupqJqpB6c7Pnq6SWRZiMpLPrcnxHTHch9Ns 5vRw== X-Gm-Message-State: AOAM533m8NIIBNQ6TatxFrV0ZovC78eeX7/2D+4Q3SDJHicxwxxfQt8I fqlNcJzRgb2kCfBluKJTzAPzG8bfwH8= X-Google-Smtp-Source: ABdhPJyt8hDN5ux3R8qy/pHulNen7BJBQIC1cqCUwbL8RSXf5IwohdNKFMqr8NKvve+3PR3HKKBbHQ== X-Received: by 2002:a5d:6344:0:b0:1f0:21ee:9705 with SMTP id b4-20020a5d6344000000b001f021ee9705mr8523241wrw.93.1646318444602; Thu, 03 Mar 2022 06:40:44 -0800 (PST) Received: from localhost ([2001:8a0:f924:2600:209d:85e2:409e:8726]) by smtp.gmail.com with ESMTPSA id i9-20020adffdc9000000b001f046861795sm2128567wrs.19.2022.03.03.06.40.43 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 03 Mar 2022 06:40:43 -0800 (PST) From: Pedro Alves To: gdb-patches@sourceware.org Subject: [PATCH 10/11] Ensure EXIT is last event, gdbserver/linux Date: Thu, 3 Mar 2022 14:40:19 +0000 Message-Id: <20220303144020.3601082-11-pedro@palves.net> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20220303144020.3601082-1-pedro@palves.net> References: <20220303144020.3601082-1-pedro@palves.net> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 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+public-inbox=simark.ca@sourceware.org Sender: "Gdb-patches" Same as the previous patch, but for GDBserver. In a nutshell, don't report exit events for the leader thread until all pending events for other threads are flushed. Change-Id: I3f855f48bea15a527a87565f8b9f4000169cd6c0 --- gdbserver/linux-low.cc | 46 +++++++++++++++++++++++++++++++++--------- gdbserver/linux-low.h | 15 ++++++++++++-- 2 files changed, 49 insertions(+), 12 deletions(-) diff --git a/gdbserver/linux-low.cc b/gdbserver/linux-low.cc index 5c037881670..15c2914e444 100644 --- a/gdbserver/linux-low.cc +++ b/gdbserver/linux-low.cc @@ -1655,16 +1655,10 @@ lwp_resumed (struct lwp_info *lwp) } bool -linux_process_target::status_pending_p_callback (thread_info *thread, - ptid_t ptid) +linux_process_target::status_pending_p (thread_info *thread) { struct lwp_info *lp = get_thread_lwp (thread); - /* Check if we're only interested in events from a specific process - or a specific LWP. */ - if (!thread->id.matches (ptid)) - return 0; - if (!lwp_resumed (lp)) return 0; @@ -1678,6 +1672,38 @@ linux_process_target::status_pending_p_callback (thread_info *thread, return lp->status_pending_p; } +bool +linux_process_target::non_leader_lwp_in_process_with_pending_event + (thread_info *thread) +{ + gdb_assert (is_leader (thread)); + + thread_info *found = find_thread (ptid_t (pid_of (thread)), + [&] (thread_info *other) + { + return !is_leader (other) && status_pending_p (other); + }); + + return found != nullptr; +} + +bool +linux_process_target::has_reportable_pending_event (thread_info *thread, + ptid_t filter_ptid) +{ + /* Check if we're only interested in events from a specific process + or a specific thread. */ + if (!thread->id.matches (filter_ptid)) + return false; + + lwp_info *lp = get_thread_lwp (thread); + + return (status_pending_p (thread) + && !(!WIFSTOPPED (lp->status_pending) + && is_leader (thread) + && non_leader_lwp_in_process_with_pending_event (thread))); +} + struct lwp_info * find_lwp_pid (ptid_t ptid) { @@ -2446,7 +2472,7 @@ linux_process_target::wait_for_event_filtered (ptid_t wait_ptid, { event_thread = find_thread_in_random ([&] (thread_info *thread) { - return status_pending_p_callback (thread, filter_ptid); + return has_reportable_pending_event (thread, filter_ptid); }); if (event_thread != NULL) @@ -2562,7 +2588,7 @@ linux_process_target::wait_for_event_filtered (ptid_t wait_ptid, any. */ event_thread = find_thread_in_random ([&] (thread_info *thread) { - return status_pending_p_callback (thread, filter_ptid); + return has_reportable_pending_event (thread, filter_ptid); }); if (event_thread != NULL) @@ -2902,7 +2928,7 @@ linux_process_target::wait_1 (ptid_t ptid, target_waitstatus *ourstatus, auto status_pending_p_any = [&] (thread_info *thread) { - return status_pending_p_callback (thread, minus_one_ptid); + return status_pending_p (thread); }; auto not_stopped = [&] (thread_info *thread) diff --git a/gdbserver/linux-low.h b/gdbserver/linux-low.h index 27cc9641f12..bd71e673871 100644 --- a/gdbserver/linux-low.h +++ b/gdbserver/linux-low.h @@ -483,8 +483,19 @@ class linux_process_target : public process_stratum_target they should be re-issued if necessary. */ void resume_one_thread (thread_info *thread, bool leave_all_stopped); - /* Return true if this lwp has an interesting status pending. */ - bool status_pending_p_callback (thread_info *thread, ptid_t ptid); + /* Return true if THREAD has an interesting status pending. */ + bool status_pending_p (thread_info *thread); + + /* Return true if another thread of the same process as THREAD has a + pending status ready to be processed. THREAD is assumed to be + the leader of its process. */ + bool non_leader_lwp_in_process_with_pending_event (thread_info *thread); + + /* Indicate if THREAD has a pending event which should be considered + for immediate processing. Only threads that match FILTER_PTID + are considered. Does not consider a leader thread's exit event + before the non-leader threads have reported their exits. */ + bool has_reportable_pending_event (thread_info *thread, ptid_t filter_ptid); /* Resume LWPs that are currently stopped without any pending status to report, but are resumed from the core's perspective. */ -- 2.26.2