From patchwork Tue Jul 4 15:22:51 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Burgess X-Patchwork-Id: 72086 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 D4BF438768A0 for ; Tue, 4 Jul 2023 15:26:15 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D4BF438768A0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1688484375; bh=gZI4WRPyagAZM+fZLtBD108C6j163ALnav8B4IVh6o0=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=AG/rwS1KcKMJxsc2dbtyk3wHFKGZ7ogwpncn3JzlF4x13WQFqBFiu5hItzNNO1hdd HXGHBg2K7FLFPHP9GAg5iypG4Ai7bqQk+5v0hiSzHN0DiR5zl81cMDdc31tNXDEBxk HTbruBIC9jmF8UVAowin0VizbZLy8dINmHwPRWeg= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id 13D133857342 for ; Tue, 4 Jul 2023 15:23:08 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 13D133857342 Received: from mail-wm1-f71.google.com (mail-wm1-f71.google.com [209.85.128.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-338-4sgLa7E_O4umc3G_BwHhzQ-1; Tue, 04 Jul 2023 11:23:05 -0400 X-MC-Unique: 4sgLa7E_O4umc3G_BwHhzQ-1 Received: by mail-wm1-f71.google.com with SMTP id 5b1f17b1804b1-3fa9a282fffso33382395e9.1 for ; Tue, 04 Jul 2023 08:23:05 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1688484184; x=1691076184; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=gZI4WRPyagAZM+fZLtBD108C6j163ALnav8B4IVh6o0=; b=KyXtAlnDgonWNWE7dNhN1Qi3TPpIG0uyRnYX69JkN7qCUprCQvLbo26XIbeUN7bcXX KkOLkzgqe3CQhAXWmBvM4nPB67u/6/FvOUgID6lnow0Dpim4XE8fB9rYNKK444w4e8gu mUpOXlTyInIAiRr2bHfW5H/32ZNrWhps56kCX0R4zBiNyMBmJEcxaWw30dCG/B2L9JLd aVUrjXuSyh7qaTvjr+EO6nZndlXJqT2VrCtKUqvcB1Lw7wqO4ihQmmGAZv2uX6cWdpMV +8X5pWP2Xx/iAoMpN2Wk08ZlKXC8H8I8uq+emYr6ynHmcr5W5SsfcIDJ1w8DVdNo3Al0 vAGA== X-Gm-Message-State: ABy/qLY/Zc6q6TZrzHI5jOS/yCgpPyV0Fg/juKd+WkeVrkOsKWwruFel Mm3PysxCfPEApSotqQSCmV5HuUvSgHZBkIeoH+NkYK+/e2lx+aHMuw1AA0J2TZRt40bihtu+quA 6hyIfZe2eg+QYTcc9hhL2x8/K51GHL7jQBCb4zsE8/rAkUcKbVXoH0nyiKj+aLtiuiZt6TocNAe nuJUJsAg== X-Received: by 2002:a1c:f712:0:b0:3fb:dbd0:a7ea with SMTP id v18-20020a1cf712000000b003fbdbd0a7eamr4525405wmh.37.1688484184372; Tue, 04 Jul 2023 08:23:04 -0700 (PDT) X-Google-Smtp-Source: APBJJlHDuiKbM3wNz1vt03sBX/P6wBG00U9dioLj01AunGg40lF4Fo/s6dXolJW+T5I3t8x4o9KV/Q== X-Received: by 2002:a1c:f712:0:b0:3fb:dbd0:a7ea with SMTP id v18-20020a1cf712000000b003fbdbd0a7eamr4525388wmh.37.1688484184088; Tue, 04 Jul 2023 08:23:04 -0700 (PDT) Received: from localhost (2.72.115.87.dyn.plus.net. [87.115.72.2]) by smtp.gmail.com with ESMTPSA id m25-20020a7bca59000000b003fbca942499sm11429879wml.14.2023.07.04.08.23.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 04 Jul 2023 08:23:03 -0700 (PDT) To: gdb-patches@sourceware.org Cc: Andrew Burgess , tankut.baris.aktemur@intel.com Subject: [PATCHv2 1/8] gdb: catch more errors in gdb.base/foll-vfork.exp Date: Tue, 4 Jul 2023 16:22:51 +0100 Message-Id: <470e7aaaf7e27a36c33083afe412720492a915b1.1688484032.git.aburgess@redhat.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: References: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, 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: , X-Patchwork-Original-From: Andrew Burgess via Gdb-patches From: Andrew Burgess Reply-To: Andrew Burgess Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" For *reasons* I was looking at gdb.base/foll-vfork.exp. This test script has a proc 'setup_gdb' that could (potentially) fail. The setup_gdb proc is called from many places and I, initially, didn't think that we were checking if setup_gdb had failed or not. My confusion was because I didn't understand what this tcl construct did: return -code return this will actually act as a return in the context of a proc's caller, effectively returning two levels of the call stack. Neat (I guess). So it turns out my worries were misplaced, everywhere setup_gdb is called, if setup_gdb fails then we will (magically) return. However, I did spot one place where we managed to confuse ourselves with our cleverness. In check_vfork_catchpoints, this proc is called to check that GDB is able to catch vforks or not. This proc is called early in the test script, and the intention is that, should this proc fail, we'll mark the whole test script as unsupported and then move onto the next test script. However, check_vfork_catchpoints also uses setup_gdb, and so, if that call to setup_gdb fails we'll end up returning immediately from check_vfork_catchpoints, and then continue with the test of _this_ test script, which is not correct. To fix this I see two choices, one is remove the use of 'return -code return' from setup_gdb, however, this would require every use of setup_gdb to then be placed inside: if { ![setup_gdb] } { return } Or, I can wrap the one call to setup_gdb in check_vfork_catchpoints and check its return code. I chose the second option as this is the smaller code change. There should be no change in what is tested after this commit. --- gdb/testsuite/gdb.base/foll-vfork.exp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/gdb/testsuite/gdb.base/foll-vfork.exp b/gdb/testsuite/gdb.base/foll-vfork.exp index 313afa06324..bdceff0f5de 100644 --- a/gdb/testsuite/gdb.base/foll-vfork.exp +++ b/gdb/testsuite/gdb.base/foll-vfork.exp @@ -70,9 +70,15 @@ proc setup_gdb {} { proc check_vfork_catchpoints {} { global gdb_prompt - global has_vfork_catchpoints - setup_gdb + # Because setup_gdb uses 'return -code return' which would return to + # our caller we need to wrap this call, spot when setup_gdb failed + # (with return code 2), and then issue our own 'return -code return'. + set code [catch {setup_gdb} string] + if { $code == 2 } { + unsupported "vfork catchpoints" + return -code return + } # Verify that the system supports "catch vfork". gdb_test "catch vfork" "Catchpoint \[0-9\]* \\(vfork\\)" "insert first vfork catchpoint" From patchwork Tue Jul 4 15:22:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Burgess X-Patchwork-Id: 72084 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 C8E963882066 for ; Tue, 4 Jul 2023 15:25:04 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C8E963882066 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1688484304; bh=mKzH9MLKVP5xgcDn1f82J9gu64ht1G+TBO+TnqY596I=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=yK9SC6SiHeWOU2qKD11WiyD+Bq5ay+bXOMjKau6atorYaCbwUQV8xHmqNviO6h98y QxA3ctBHKVEp90gWCnUqdlb9PsMg2qb8JChpYIqMpv3MXnExZtc3oXMd/FqBSiX70l 8hYyDTgkzD1JfDCLoflZvyGegxTMkZIWphr9ygTQ= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id E625938555B2 for ; Tue, 4 Jul 2023 15:23:12 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org E625938555B2 Received: from mail-wm1-f70.google.com (mail-wm1-f70.google.com [209.85.128.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-363-eE_iD2DlPGWUB8zmyfs5nw-1; Tue, 04 Jul 2023 11:23:07 -0400 X-MC-Unique: eE_iD2DlPGWUB8zmyfs5nw-1 Received: by mail-wm1-f70.google.com with SMTP id 5b1f17b1804b1-3fb416d7731so31948875e9.2 for ; Tue, 04 Jul 2023 08:23:07 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1688484186; x=1691076186; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=mKzH9MLKVP5xgcDn1f82J9gu64ht1G+TBO+TnqY596I=; b=RBsV+GBidt3lbPhu48ev6XL/x28nM6YpPPO84saGgYY2nIIsnqR+YhkrcDB9V31V8i eBdNcjr72MZ2/erjN4cj+ZdzO37R4JBjNGvgDzu0TiYoBm3VzaX4K621f0EiGPxNx2Of yZ8t0VcFGICT2O8v9Q/i1iXV8ej7fLa2lVsbWjOblb4KO1L43i4S0AdSm914g30togtF /YgJ2Hu6ZxB6I5bV16EAbKuUxbQnCOmfbzP6mOvPjpNWr2JzRW0P23G5URq6FR2jxFRa G3R3fmeSgxi+PefJbNALWrCmxeSCcSDeSCum4i0Fdi9KpRcPkQNJEzU0Qvsa+z8eoK29 l2fA== X-Gm-Message-State: AC+VfDzr8GWX+l4gIO1Ba/i+5Q9U/Q7tJPQPLkgmroWkaAOPsXgYaFnE Wo+aBKC0MQ8pQsGj8z84FR6fjHZxKBlXrwLpS9EQCEboe8QGeh3Rxgv7aZctJtHO4qWVSJfpP6j sBUrqW1rZD6XzuyD1GLnTylHrT3UVOI9oeQ7h5LxtQrPpFeGt2jiMnnqwyp2Rti6Zx6ZwaOAd3t qaNQ2Vvg== X-Received: by 2002:a7b:cb95:0:b0:3fb:b53c:1a32 with SMTP id m21-20020a7bcb95000000b003fbb53c1a32mr10163411wmi.34.1688484186029; Tue, 04 Jul 2023 08:23:06 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ7KWnrYBXpHqFm8iCx0zyaeMXX2EHc9kudTcaMBGDRw58VEdqjB7MxMu9mG0ysLAFNwQHEmAQ== X-Received: by 2002:a7b:cb95:0:b0:3fb:b53c:1a32 with SMTP id m21-20020a7bcb95000000b003fbb53c1a32mr10163384wmi.34.1688484185528; Tue, 04 Jul 2023 08:23:05 -0700 (PDT) Received: from localhost (2.72.115.87.dyn.plus.net. [87.115.72.2]) by smtp.gmail.com with ESMTPSA id y5-20020a05600c364500b003fbc9d178a8sm11962492wmq.4.2023.07.04.08.23.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 04 Jul 2023 08:23:05 -0700 (PDT) To: gdb-patches@sourceware.org Cc: Andrew Burgess , tankut.baris.aktemur@intel.com Subject: [PATCHv2 2/8] gdb: don't restart vfork parent while waiting for child to finish Date: Tue, 4 Jul 2023 16:22:52 +0100 Message-Id: X-Mailer: git-send-email 2.25.4 In-Reply-To: References: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, 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: , X-Patchwork-Original-From: Andrew Burgess via Gdb-patches From: Andrew Burgess Reply-To: Andrew Burgess Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" While working on a later patch, which changes gdb.base/foll-vfork.exp, I noticed that sometimes I would hit this assert: x86_linux_update_debug_registers: Assertion `lwp_is_stopped (lwp)' failed. I eventually tracked it down to a combination of schedule-multiple mode being on, target-non-stop being off, follow-fork-mode being set to child, and some bad timing. The failing case is pretty simple, a single threaded application performs a vfork, the child process then execs some other application while the parent process (once the vfork child has completed its exec) just exits. As best I understand things, here's what happens when things go wrong: 1. The parent process performs a vfork, GDB sees the VFORKED event and creates an inferior and thread for the vfork child, 2. GDB resumes the vfork child process. As schedule-multiple is on and target-non-stop is off, this is translated into a request to start all processes (see user_visible_resume_ptid), 3. In the linux-nat layer we spot that one of the threads we are about to start is a vfork parent, and so don't start that thread (see resume_lwp), the vfork child thread is resumed, 4. GDB waits for the next event, eventually entering linux_nat_target::wait, which in turn calls linux_nat_wait_1, 5. In linux_nat_wait_1 we eventually call resume_stopped_resumed_lwps, this should restart threads that have stopped but don't actually have anything interesting to report. 6. Unfortunately, resume_stopped_resumed_lwps doesn't check for vfork parents like resume_lwp does, so at this point the vfork parent is resumed. This feels like the start of the bug, and this is where I'm proposing to fix things, but, resuming the vfork parent isn't the worst thing in the world because.... 7. As the vfork child is still alive the kernel holds the vfork parent stopped, 8. Eventually the child performs its exec and GDB is sent and EXECD event. However, because the parent is resumed, as soon as the child performs its exec the vfork parent also sends a VFORK_DONE event to GDB, 9. Depending on timing both of these events might seem to arrive in GDB at the same time. Normally GDB expects to see the EXECD or EXITED/SIGNALED event from the vfork child before getting the VFORK_DONE in the parent. We know this because it is as a result of the EXECD/EXITED/SIGNALED that GDB detaches from the parent (see handle_vfork_child_exec_or_exit for details). Further the comment in target/waitstatus.h on TARGET_WAITKIND_VFORK_DONE indicates that when we remain attached to the child (not the parent) we should not expect to see a VFORK_DONE, 10. If both events arrive at the same time then GDB will randomly choose one event to handle first, in some cases this will be the VFORK_DONE. As described above, upon seeing a VFORK_DONE GDB expects that (a) the vfork child has finished, however, in this case this is not completely true, the child has finished, but GDB has not processed the event associated with the completion yet, and (b) upon seeing a VFORK_DONE GDB assumes we are remaining attached to the parent, and so resumes the parent process, 11. GDB now handles the EXECD event. In our case we are detaching from the parent, so GDB calls target_detach (see handle_vfork_child_exec_or_exit), 12. While this has been going on the vfork parent is executing, and might even exit, 13. In linux_nat_target::detach the first thing we do is stop all threads in the process we're detaching from, the result of the stop request will be cached on the lwp_info object, 14. In our case the vfork parent has exited though, so when GDB waits for the thread, instead of a stop due to signal, we instead get a thread exited status, 15. Later in the detach process we try to resume the threads just prior to making the ptrace call to actually detach (see detach_one_lwp), as part of the process to resume a thread we try to touch some registers within the thread, and before doing this GDB asserts that the thread is stopped, 16. An exited thread is not classified as stopped, and so the assert triggers! So there's two bugs I see here. The first, and most critical one here is in step #6. I think that resume_stopped_resumed_lwps should not resume a vfork parent, just like resume_lwp doesn't resume a vfork parent. With this change in place the vfork parent will remain stopped in step instead GDB will only see the EXECD/EXITED/SIGNALLED event. The problems in #9 and #10 are therefore skipped and we arrive at #11, handling the EXECD event. As the parent is still stopped #12 doesn't apply, and in #13 when we try to stop the process we will see that it is already stopped, there's no risk of the vfork parent exiting before we get to this point. And finally, in #15 we are safe to poke the process registers because it will not have exited by this point. However, I did mention two bugs. The second bug I've not yet managed to actually trigger, but I'm convinced it must exist: if we forget vforks for a moment, in step #13 above, when linux_nat_target::detach is called, we first try to stop all threads in the process GDB is detaching from. If we imagine a multi-threaded inferior with many threads, and GDB running in non-stop mode, then, if the user tries to detach there is a chance that thread could exit just as linux_nat_target::detach is entered, in which case we should be able to trigger the same assert. But, like I said, I've not (yet) managed to trigger this second bug, and even if I could, the fix would not belong in this commit, so I'm pointing this out just for completeness. There's no test included in this commit. In a couple of commits time I will expand gdb.base/foll-vfork.exp which is when this bug would be exposed. Unfortunately there are at least two other bugs (separate from the ones discussed above) that need fixing first, these will be fixed in the next commits before the gdb.base/foll-vfork.exp test is expanded. If you do want to reproduce this failure then you will for certainly need to run the gdb.base/foll-vfork.exp test in a loop as the failures are all very timing sensitive. I've found that running multiple copies in parallel makes the failure more likely to appear, I usually run ~6 copies in parallel and expect to see a failure after within 10mins. --- gdb/linux-nat.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c index 383ef58fa23..7e121b7ab41 100644 --- a/gdb/linux-nat.c +++ b/gdb/linux-nat.c @@ -3346,7 +3346,14 @@ linux_nat_wait_1 (ptid_t ptid, struct target_waitstatus *ourstatus, static int resume_stopped_resumed_lwps (struct lwp_info *lp, const ptid_t wait_ptid) { - if (!lp->stopped) + struct inferior *inf = find_inferior_ptid (linux_target, lp->ptid); + + if (inf->vfork_child != nullptr) + { + linux_nat_debug_printf ("NOT resuming LWP %s (vfork parent)", + lp->ptid.to_string ().c_str ()); + } + else if (!lp->stopped) { linux_nat_debug_printf ("NOT resuming LWP %s, not stopped", lp->ptid.to_string ().c_str ()); From patchwork Tue Jul 4 15:22:53 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Burgess X-Patchwork-Id: 72083 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 629EB385ED78 for ; Tue, 4 Jul 2023 15:24:36 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 629EB385ED78 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1688484276; bh=qD3h85yOc28kXXbSbpZFA/DABx2nvUwci4wpUNDMVRI=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=cjb4KyhkZH9UNem6dPeRv9s5EWz+M3gomcOU3CdVYA6I1OiT/f1ltRoax7sdw07y/ 6hRAwwBssQJzvV+hBcZV04Zs7wOzCD7tOo+44RkRc9+EMiWjeCG8zTM05qmGX2/+OM LRtnXVk3A5+nsk6G1urfwLqrpYp9L8H4qXLga+5A= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id E2313385B537 for ; Tue, 4 Jul 2023 15:23:09 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org E2313385B537 Received: from mail-wr1-f72.google.com (mail-wr1-f72.google.com [209.85.221.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-478-4d2mXumDMGmN5RzbL03uGw-1; Tue, 04 Jul 2023 11:23:08 -0400 X-MC-Unique: 4d2mXumDMGmN5RzbL03uGw-1 Received: by mail-wr1-f72.google.com with SMTP id ffacd0b85a97d-313f2430134so2853439f8f.3 for ; Tue, 04 Jul 2023 08:23:08 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1688484187; x=1691076187; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=qD3h85yOc28kXXbSbpZFA/DABx2nvUwci4wpUNDMVRI=; b=St7AdiL7sXOLJfaIS2kCH/8VpYuJgbIk2Y8wEaCrhCNU+TVGbOYl7XRpx0mOpXkYsx j+mtfGi10zNOufGw3sOPXl4LQIgOjmToV+1evaiOAi9BM/nJUV5sV3jqoL5wW4Nr4shw QDAnY0787RZRYwILsTb5LYkyWLICMKzD4sxZxd24obdligYK8Dt9KSNS53buSdh8qbHR aFEW0j/oxMOcWD027XwCyhtRjijw+yJkfBUSIqSzx2iupCrukjnGU0idb4WE9vmIu4OM 0cMv9n7rwE5jjyhpacnizToY+a46vxpETbwphpAII0FchAfzLEP2IyyriYTkDwve9FQi k9HQ== X-Gm-Message-State: ABy/qLYhYwAvJMlGIkQQuP+i07hNgtg5zeYZMGTvew2GE5vGnq0XEoRF gCyVmnyZAbBn8GrdUGV+y5lsFAHKvXaaaTA6FX/T0YeQeHWNDfFmUSPcQVFAspBfe1nHl1ehqtl jRCqu/dt+HSfe7AEbvQW/E5AoHNSPjWpTUDWPiKzv0hZakRSh8vZFgOrw49WoMfk7zpWdCdGwsX c+m0aXEA== X-Received: by 2002:adf:fd43:0:b0:314:77a:c2b2 with SMTP id h3-20020adffd43000000b00314077ac2b2mr11256252wrs.32.1688484187156; Tue, 04 Jul 2023 08:23:07 -0700 (PDT) X-Google-Smtp-Source: APBJJlE5bO8jowo5EdIurguwND6T/NhCK8K5sBObNxAYZyTukDw6xLvodJrp7L0nnRbOyPanjfdYcA== X-Received: by 2002:adf:fd43:0:b0:314:77a:c2b2 with SMTP id h3-20020adffd43000000b00314077ac2b2mr11256235wrs.32.1688484186839; Tue, 04 Jul 2023 08:23:06 -0700 (PDT) Received: from localhost (2.72.115.87.dyn.plus.net. [87.115.72.2]) by smtp.gmail.com with ESMTPSA id q10-20020adfdfca000000b003141e629cb6sm12719421wrn.101.2023.07.04.08.23.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 04 Jul 2023 08:23:06 -0700 (PDT) To: gdb-patches@sourceware.org Cc: Andrew Burgess , tankut.baris.aktemur@intel.com Subject: [PATCHv2 3/8] gdb: fix an issue with vfork in non-stop mode Date: Tue, 4 Jul 2023 16:22:53 +0100 Message-Id: <1320f2998985fa621cb3dfab0e3143fa2ba99568.1688484032.git.aburgess@redhat.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: References: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, 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: , X-Patchwork-Original-From: Andrew Burgess via Gdb-patches From: Andrew Burgess Reply-To: Andrew Burgess Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" This commit fixes a bug introduced by this commit: commit d8bbae6ea080249c05ca90b1f8640fde48a18301 Date: Fri Jan 14 15:40:59 2022 -0500 gdb: fix handling of vfork by multi-threaded program (follow-fork-mode=parent, detach-on-fork=on) The problem can be seen in this GDB session: $ gdb -q (gdb) set non-stop on (gdb) file ./gdb/testsuite/outputs/gdb.base/foll-vfork/foll-vfork Reading symbols from ./gdb/testsuite/outputs/gdb.base/foll-vfork/foll-vfork... (gdb) tcatch vfork Catchpoint 1 (vfork) (gdb) run Starting program: /tmp/gdb/testsuite/outputs/gdb.base/foll-vfork/foll-vfork Temporary catchpoint 1 (vforked process 1375914), 0x00007ffff7d5043c in vfork () from /lib64/libc.so.6 (gdb) bt #0 0x00007ffff7d5043c in vfork () from /lib64/libc.so.6 #1 0x00000000004011af in main (argc=1, argv=0x7fffffffad88) at .../gdb/testsuite/gdb.base/foll-vfork.c:32 (gdb) finish Run till exit from #0 0x00007ffff7d5043c in vfork () from /lib64/libc.so.6 [Detaching after vfork from child process 1375914] No unwaited-for children left. (gdb) Notice the "No unwaited-for children left." error. This is incorrect, given where we are stopped there's no reason why we shouldn't be able to use "finish" to return to the main frame. When the inferior is stopped as a result of the 'tcatch vfork', the inferior is in the process of performing the vfork, that is, GDB has seen the VFORKED event, but has not yet attached to the new child process, nor has the child process been resumed. However, GDB has seen the VFORKED, and, as we are going to follow the parent process, the inferior for the vfork parent will have its thread_waiting_for_vfork_done member variable set, this will point to the one and only thread that makes up the vfork parent process. When the "finish" command is used GDB eventually ends up in the proceed function (in infrun.c), in here we pass through all the function until we eventually encounter this 'else if' condition: else if (!cur_thr->resumed () && !thread_is_in_step_over_chain (cur_thr) /* In non-stop, forbid resuming a thread if some other thread of that inferior is waiting for a vfork-done event (this means breakpoints are out for this inferior). */ && !(non_stop && cur_thr->inf->thread_waiting_for_vfork_done != nullptr)) { The first two of these conditions will both be true, the thread is not already resumed, and is not in the step-over chain, however, the third condition, this one: && !(non_stop && cur_thr->inf->thread_waiting_for_vfork_done != nullptr)) is false, and this prevents the thread we are trying to finish from being resumed. This condition is false because (a) non_stop is true, and (b) cur_thr->inf->thread_waiting_for_vfork_done is not nullptr (see above for why). Now, if we check the comment embedded within the condition it says: /* In non-stop, forbid resuming a thread if some other thread of that inferior is waiting for a vfork-done event (this means breakpoints are out for this inferior). */ And this makes sense, if we have a vfork parent with two thread, and one thread has performed a vfork, then we shouldn't try to resume the second thread. However, if we are trying to resume the thread that actually performed a vfork, then this is fine. If we never resume the vfork parent then we'll never get a VFORK_DONE event, and so the vfork will never complete. Thus, the condition should actually be: && !(non_stop && cur_thr->inf->thread_waiting_for_vfork_done != nullptr && cur_thr->inf->thread_waiting_for_vfork_done != cur_thr)) This extra check will allow the vfork parent thread to resume, but prevent any other thread in the vfork parent process from resuming. This is the same condition that already exists in the all-stop on a non-stop-target block earlier in the proceed function. My actual fix is slightly different to the above, first, I've chosen to use a nested 'if' check instead of extending the original 'else if' check, this makes it easier to write a longer comment explaining what's going on, and second, instead of checking 'non_stop' I've switched to checking 'target_is_non_stop_p'. In this context this is effectively the same thing, a previous 'else if' block in proceed already handles '!non_stop && target_is_non_stop_p ()', so by the time we get here, if 'target_is_non_stop_p ()' then we must be running in non_stop mode. Both of these tweaks will make the next patch easier, which is a refactor to merge two parts of the proceed function, so this nested 'if' block is not going to exist for long. For testing, there is no test included with this commit. The test was exposed when using a modified version of the gdb.base/foll-vfork.exp test script, however, there are other bugs that are exposed when using the modified test script. These bugs will be addressed in subsequent commits, and then I'll add the updated gdb.base/foll-vfork.exp. If you wish to reproduce this failure then grab the updates to gdb.base/foll-vfork.exp from the later commit and run this test, the failure is always reproducible. --- gdb/infrun.c | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/gdb/infrun.c b/gdb/infrun.c index 58da1cef29e..5b0257076f0 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -3503,19 +3503,29 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal) } } else if (!cur_thr->resumed () - && !thread_is_in_step_over_chain (cur_thr) - /* In non-stop, forbid resuming a thread if some other thread of - that inferior is waiting for a vfork-done event (this means - breakpoints are out for this inferior). */ - && !(non_stop - && cur_thr->inf->thread_waiting_for_vfork_done != nullptr)) + && !thread_is_in_step_over_chain (cur_thr)) { - /* The thread wasn't started, and isn't queued, run it now. */ - execution_control_state ecs (cur_thr); - switch_to_thread (cur_thr); - keep_going_pass_signal (&ecs); - if (!ecs.wait_some_more) - error (_("Command aborted.")); + /* In non-stop mode, if a there exists a thread waiting for a vfork + then only allow that thread to resume (breakpoints are removed + from an inferior when handling a vfork). + + We check target_is_non_stop_p here rather than just checking the + non-stop flag, though these are equivalent (all-stop on a + non-stop target was handled in a previous block, so at this + point, if target_is_non_stop_p then GDB must be running on + non-stop mode). By using target_is_non_stop_p it will be easier + to merge this block with the previous in a later commit. */ + if (!(target_is_non_stop_p () + && cur_thr->inf->thread_waiting_for_vfork_done != nullptr + && cur_thr->inf->thread_waiting_for_vfork_done != cur_thr)) + { + /* The thread wasn't started, and isn't queued, run it now. */ + execution_control_state ecs (cur_thr); + switch_to_thread (cur_thr); + keep_going_pass_signal (&ecs); + if (!ecs.wait_some_more) + error (_("Command aborted.")); + } } disable_commit_resumed.reset_and_commit (); From patchwork Tue Jul 4 15:22:54 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Burgess X-Patchwork-Id: 72087 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 D47DC3882040 for ; Tue, 4 Jul 2023 15:26:44 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D47DC3882040 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1688484404; bh=kP8BHpJJMpvfjrHJOCmo4H62EqjsFTN3LgZ9yJn0NXI=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=r2c/fwDZNYk55rQ6MaGXf66Sn5KePo0ji3kb9e+6o6nERnmA6WufTvcKYS3iqExw7 HBE/4CnUulDQJkoHdV/RGet1bKz0yenpY4abYE72spaWL912SSKimCxa+krCqszUMu X9UilQQQWrFRQXft5SMPIcwru+1LxUsfcf/rjLKE= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id 826393855598 for ; Tue, 4 Jul 2023 15:23:11 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 826393855598 Received: from mail-wm1-f70.google.com (mail-wm1-f70.google.com [209.85.128.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-512-9YkZFvgOPseF607tJ_L49w-1; Tue, 04 Jul 2023 11:23:10 -0400 X-MC-Unique: 9YkZFvgOPseF607tJ_L49w-1 Received: by mail-wm1-f70.google.com with SMTP id 5b1f17b1804b1-3fbab56aac7so36164155e9.1 for ; Tue, 04 Jul 2023 08:23:09 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1688484189; x=1691076189; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=kP8BHpJJMpvfjrHJOCmo4H62EqjsFTN3LgZ9yJn0NXI=; b=U4ZZbkKvdgDP8GZRgxQxNCyFCcuRBDZedy64ZrQ+ysMT/pRiLzYGFci1mxCNGLOk5f P0ZRKM68CkG6moMFDLrS8LXLFWFbB21YilNPZQs3Si09PZpmzUsHhngiXFWPNB5GUFRh QPcNvZlG7g8sPtCgQ8RQWfcE91FqrwriEdVkOMtVhHDETZ/DhhP/ht0HrfLwTTNHBCjh 4lTRQv0tNqadabiLVBItowgXQ7g7i0dHEKzj09yAMtdO21/lV2xc1gEx1dbRca2GlUEn dPGgO5fBSLkXWyQs6wrNBL+WO0ZO4GhBSIv9XS4nFVLcE5OTOpFgMAobn4eWZ+mWtkYC mRVQ== X-Gm-Message-State: AC+VfDx0GG3g7kJ6KwlWFbMJH2lq7zi1ze3VTrJ/aFH/Q/kz3Nb6JFVk t11HKFgvJ470o8EGM8m3UjUDAlzmt7GaI4EEu5RO8YOm+2DeBRkTT0Ir/BNB2RfQ8q6NnOmQYVD iusJ6gcoDsh3kzj7tWwQy63VGT1VkFCZm7Tvzb6N0MRNillZFdbM/NNnVsrvZOTfIeWpDDh9sg9 bDaafaww== X-Received: by 2002:a05:600c:22c3:b0:3fa:79af:15c8 with SMTP id 3-20020a05600c22c300b003fa79af15c8mr11804093wmg.23.1688484188799; Tue, 04 Jul 2023 08:23:08 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ5H3ReYsj9C+bGQFp2JFK+2vpEe+P2a/ovdrpkwsAOrTbhb9dQ1//Qkn0VZOgZ9sYPMkPYdLQ== X-Received: by 2002:a05:600c:22c3:b0:3fa:79af:15c8 with SMTP id 3-20020a05600c22c300b003fa79af15c8mr11804070wmg.23.1688484188373; Tue, 04 Jul 2023 08:23:08 -0700 (PDT) Received: from localhost (2.72.115.87.dyn.plus.net. [87.115.72.2]) by smtp.gmail.com with ESMTPSA id k16-20020a05600c0b5000b003fba6709c68sm21209216wmr.47.2023.07.04.08.23.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 04 Jul 2023 08:23:08 -0700 (PDT) To: gdb-patches@sourceware.org Cc: Mihails Strasuns , tankut.baris.aktemur@intel.com, Christina Schimpe Subject: [PATCHv2 4/8] gdb, infrun: refactor part of `proceed` into separate function Date: Tue, 4 Jul 2023 16:22:54 +0100 Message-Id: <72b43d4ee86a71924d83198ed771da5a8bd93469.1688484032.git.aburgess@redhat.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: References: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, 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: , X-Patchwork-Original-From: Andrew Burgess via Gdb-patches From: Andrew Burgess Reply-To: Andrew Burgess Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" From: Mihails Strasuns Split the thread resuming code from proceed into new function proceed_resume_thread_checked. Co-Authored-By: Christina Schimpe --- gdb/infrun.c | 155 ++++++++++++++++++++++++++++----------------------- 1 file changed, 86 insertions(+), 69 deletions(-) diff --git a/gdb/infrun.c b/gdb/infrun.c index 5b0257076f0..010fcd7952f 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -3268,6 +3268,89 @@ check_multi_target_resumption (process_stratum_target *resume_target) } } +/* Helper function for `proceed`. Check if thread TP is suitable for + resuming, and, if it is, switch to the thread and call + `keep_going_pass_signal`. If TP is not suitable for resuming then this + function will just return without switching threads. */ + +static void +proceed_resume_thread_checked (thread_info *tp) +{ + if (!tp->inf->has_execution ()) + { + infrun_debug_printf ("[%s] target has no execution", + tp->ptid.to_string ().c_str ()); + return; + } + + if (tp->resumed ()) + { + infrun_debug_printf ("[%s] resumed", + tp->ptid.to_string ().c_str ()); + gdb_assert (tp->executing () || tp->has_pending_waitstatus ()); + return; + } + + if (thread_is_in_step_over_chain (tp)) + { + infrun_debug_printf ("[%s] needs step-over", + tp->ptid.to_string ().c_str ()); + return; + } + + /* When handling a vfork GDB removes all breakpoints from the program + space in which the vfork is being handled, as such we must take care + not to resume any thread other than the vfork parent -- resuming the + vfork parent allows GDB to receive and handle the 'vfork done' + event. */ + if (tp->inf->thread_waiting_for_vfork_done != nullptr) + { + if (target_is_non_stop_p ()) + { + /* For non-stop targets, regardless of whether GDB is using + all-stop or non-stop mode, threads are controlled + individually. + + When a thread is handling a vfork, breakpoints are removed + from the inferior (well, program space in fact), so it is + critical that we don't try to resume any thread other than the + vfork parent. */ + if (tp != tp->inf->thread_waiting_for_vfork_done) + { + infrun_debug_printf ("[%s] thread %s of this inferior is " + "waiting for vfork-done", + tp->ptid.to_string ().c_str (), + tp->inf->thread_waiting_for_vfork_done + ->ptid.to_string ().c_str ()); + return; + } + } + else + { + /* For all-stop targets, when we attempt to resume the inferior, + we will only resume the vfork parent thread, this is handled + in internal_resume_ptid. + + Additionally, we will always be called with the vfork parent + thread as the current thread (TP) thanks to follow_fork, as + such the following assertion should hold. + + Beyond this there is nothing more that needs to be done + here. */ + gdb_assert (tp == tp->inf->thread_waiting_for_vfork_done); + } + } + + infrun_debug_printf ("resuming %s", + tp->ptid.to_string ().c_str ()); + + execution_control_state ecs (tp); + switch_to_thread (tp); + keep_going_pass_signal (&ecs); + if (!ecs.wait_some_more) + error (_("Command aborted.")); +} + /* Basic routine for continuing the program in various fashions. ADDR is the address to resume at, or -1 for resume where stopped. @@ -3456,77 +3539,11 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal) resume_ptid)) { switch_to_thread_no_regs (tp); - - if (!tp->inf->has_execution ()) - { - infrun_debug_printf ("[%s] target has no execution", - tp->ptid.to_string ().c_str ()); - continue; - } - - if (tp->resumed ()) - { - infrun_debug_printf ("[%s] resumed", - tp->ptid.to_string ().c_str ()); - gdb_assert (tp->executing () || tp->has_pending_waitstatus ()); - continue; - } - - if (thread_is_in_step_over_chain (tp)) - { - infrun_debug_printf ("[%s] needs step-over", - tp->ptid.to_string ().c_str ()); - continue; - } - - /* If a thread of that inferior is waiting for a vfork-done - (for a detached vfork child to exec or exit), breakpoints are - removed. We must not resume any thread of that inferior, other - than the one waiting for the vfork-done. */ - if (tp->inf->thread_waiting_for_vfork_done != nullptr - && tp != tp->inf->thread_waiting_for_vfork_done) - { - infrun_debug_printf ("[%s] another thread of this inferior is " - "waiting for vfork-done", - tp->ptid.to_string ().c_str ()); - continue; - } - - infrun_debug_printf ("resuming %s", - tp->ptid.to_string ().c_str ()); - - execution_control_state ecs (tp); - switch_to_thread (tp); - keep_going_pass_signal (&ecs); - if (!ecs.wait_some_more) - error (_("Command aborted.")); - } - } - else if (!cur_thr->resumed () - && !thread_is_in_step_over_chain (cur_thr)) - { - /* In non-stop mode, if a there exists a thread waiting for a vfork - then only allow that thread to resume (breakpoints are removed - from an inferior when handling a vfork). - - We check target_is_non_stop_p here rather than just checking the - non-stop flag, though these are equivalent (all-stop on a - non-stop target was handled in a previous block, so at this - point, if target_is_non_stop_p then GDB must be running on - non-stop mode). By using target_is_non_stop_p it will be easier - to merge this block with the previous in a later commit. */ - if (!(target_is_non_stop_p () - && cur_thr->inf->thread_waiting_for_vfork_done != nullptr - && cur_thr->inf->thread_waiting_for_vfork_done != cur_thr)) - { - /* The thread wasn't started, and isn't queued, run it now. */ - execution_control_state ecs (cur_thr); - switch_to_thread (cur_thr); - keep_going_pass_signal (&ecs); - if (!ecs.wait_some_more) - error (_("Command aborted.")); + proceed_resume_thread_checked (tp); } } + else + proceed_resume_thread_checked (cur_thr); disable_commit_resumed.reset_and_commit (); } From patchwork Tue Jul 4 15:22:55 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Burgess X-Patchwork-Id: 72082 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 4B0AD3870C36 for ; Tue, 4 Jul 2023 15:24:33 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4B0AD3870C36 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1688484273; bh=Yvjc9lwb+nxFF+zASO251ZxERL0t82RR+1Fj34o3l9k=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=pbKlsNYwaSlIiZGIJ2/gxzBjI/3SPyAOkN0VKRSFLFPwplC/FZh4B0h8q5QfwpHuQ bXjb65t10q7tw1dXUqhTSG3YNk3hZyMHyVRidxPM0VfoKExk+0kvdCIOqkVjpPFDKi MJtQ8csSIPazno0+Ve4sHZVwRZ8AB5NcI4nj6XV8= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id A758A3856DDE for ; Tue, 4 Jul 2023 15:23:14 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org A758A3856DDE Received: from mail-wm1-f71.google.com (mail-wm1-f71.google.com [209.85.128.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-98-S_ZKalrMNXG8ibqEdlEKuQ-1; Tue, 04 Jul 2023 11:23:12 -0400 X-MC-Unique: S_ZKalrMNXG8ibqEdlEKuQ-1 Received: by mail-wm1-f71.google.com with SMTP id 5b1f17b1804b1-3fbdde92299so8769285e9.3 for ; Tue, 04 Jul 2023 08:23:11 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1688484190; x=1691076190; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Yvjc9lwb+nxFF+zASO251ZxERL0t82RR+1Fj34o3l9k=; b=LmANJqIP/A2dacscWEZQCZgEDu/GZkO7Zh3tH64XHsPdY3f3vK5FAUvqEhn8wkRoZ5 QgN+NzHhcncL10fC5TIkrcOBHwsv4eDttO1/hBI210yu7WLoZdR1lV5Plp8Vb2BhmuQ/ 1kSAvcnic3iXmZ0r7uj6TYxZJnqzn4pnUvJrzLcBxAO4Pm89Xs3j3mwuei9PNC+XMhkC OiaWv8Y5X7Hj+o65BEJw9MBmnq2qWkjNlMXgtXpg8wedkVCfuTSNLB3aP5bA8sPJzEl3 eR+8RFRc4G/B1eCCpfTv0ESG5ehrramhF88FSxU3S2st26+z7yklKr31QDJzYR2/LOPc xwAA== X-Gm-Message-State: AC+VfDwp3KExiBmKF0QpnFb1mKKO097gNNCidAQLWG/HYGANlBd9fQki emyQPxS/PRlHUxKZn8oH9pp3nBtGclg4dFq5Eff03gm05mo1uYSzh175+I5R4lomhvrk26bQBM7 ovqoVbFoPD+jcxUZd5KDTl2Ws7ryNJd1kCVn243ram3E7WaylDidPieBECITAFOuD0ECjzIIetu sAZA7PsA== X-Received: by 2002:a05:600c:c1:b0:3fa:8cd8:9743 with SMTP id u1-20020a05600c00c100b003fa8cd89743mr11933261wmm.19.1688484190180; Tue, 04 Jul 2023 08:23:10 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ5ftUxUNLEf1kFnwwkzlYH3MSdJsGhTGUkkzxuSImOpr7J9lfZPLwVe6HmYPkabvu2XhA8POA== X-Received: by 2002:a05:600c:c1:b0:3fa:8cd8:9743 with SMTP id u1-20020a05600c00c100b003fa8cd89743mr11933238wmm.19.1688484189657; Tue, 04 Jul 2023 08:23:09 -0700 (PDT) Received: from localhost (2.72.115.87.dyn.plus.net. [87.115.72.2]) by smtp.gmail.com with ESMTPSA id y23-20020a7bcd97000000b003fbb2c0fce5sm17877445wmj.25.2023.07.04.08.23.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 04 Jul 2023 08:23:09 -0700 (PDT) To: gdb-patches@sourceware.org Cc: Andrew Burgess , tankut.baris.aktemur@intel.com Subject: [PATCHv2 5/8] gdb: don't resume vfork parent while child is still running Date: Tue, 4 Jul 2023 16:22:55 +0100 Message-Id: <9b3303bed5b6afcbe2e11e65d9696e3b59a61826.1688484032.git.aburgess@redhat.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: References: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, 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: , X-Patchwork-Original-From: Andrew Burgess via Gdb-patches From: Andrew Burgess Reply-To: Andrew Burgess Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" Like the last few commit, this fixes yet another vfork related issue. Like the commit titled: gdb: don't restart vfork parent while waiting for child to finish which addressed a case in linux-nat where we would try to resume a vfork parent, this commit addresses a very similar case, but this time occurring in infrun.c. Just like with that previous commit, this bug results in the assert: x86-linux-dregs.c:146: internal-error: x86_linux_update_debug_registers: Assertion `lwp_is_stopped (lwp)' failed. In this case the issue occurs when target-non-stop is on, but non-stop is off, and again, schedule-multiple is on. As with the previous commit, GDB is in follow-fork-mode child. If you have not done so, it is worth reading the earlier commit as many of the problems leading to the failure are the same, they just appear in a different part of GDB. Here are the steps leading to the assertion failure: 1. The user performs a 'next' over a vfork, GDB stop in the vfork child, 2. As we are planning to follow the child GDB sets the vfork_parent and vfork_child member variables in the two inferiors, the thread_waiting_for_vfork_done member is left as nullptr, that member is only used when GDB is planning to follow the parent inferior, 3. The user does 'continue', our expectation is that the vfork child should resume, and once that process has exited or execd, GDB should detach from the vfork parent. As a result of the 'continue' GDB eventually enters the proceed function, 4. In proceed we selected a ptid_t to resume, because schedule-multiple is on we select minus_one_ptid (see user_visible_resume_ptid), 5. As GDB is running in all-stop on top of non-stop mode, in the proceed function we iterate over all threads that match the resume ptid, which turns out to be all threads, and call proceed_resume_thread_checked. One of the threads we iterate over is the vfork parent thread, 6. As the thread passed to proceed_resume_thread_checked doesn't match any of the early return conditions, GDB will set the thread resumed, 7. As we are resuming one thread at a time, this thread is seen by the lower layers (e.g. linux-nat) as the "event thread", which means we don't apply any of the checks, e.g. is this thread a vfork parent, instead we assume that GDB core knows what it's doing, and linux-nat will resume the thread, we have now incorrectly set running the vfork parent thread when this thread should be waiting for the vfork child to complete, 8. Back in the proceed function GDB continues to iterate over all threads, and now (correctly) resumes the vfork child thread, 8. As the vfork child is still alive the kernel holds the vfork parent stopped, 9. Eventually the child performs its exec and GDB is sent and EXECD event. However, because the parent is resumed, as soon as the child performs its exec the vfork parent also sends a VFORK_DONE event to GDB, 10. Depending on timing both of these events might seem to arrive in GDB at the same time. Normally GDB expects to see the EXECD or EXITED/SIGNALED event from the vfork child before getting the VFORK_DONE in the parent. We know this because it is as a result of the EXECD/EXITED/SIGNALED that GDB detaches from the parent (see handle_vfork_child_exec_or_exit for details). Further the comment in target/waitstatus.h on TARGET_WAITKIND_VFORK_DONE indicates that when we remain attached to the child (not the parent) we should not expect to see a VFORK_DONE, 11. If both events arrive at the same time then GDB will randomly choose one event to handle first, in some cases this will be the VFORK_DONE. As described above, upon seeing a VFORK_DONE GDB expects that (a) the vfork child has finished, however, in this case this is not completely true, the child has finished, but GDB has not processed the event associated with the completion yet, and (b) upon seeing a VFORK_DONE GDB assumes we are remaining attached to the parent, and so resumes the parent process, 12. GDB now handles the EXECD event. In our case we are detaching from the parent, so GDB calls target_detach (see handle_vfork_child_exec_or_exit), 13. While this has been going on the vfork parent is executing, and might even exit, 14. In linux_nat_target::detach the first thing we do is stop all threads in the process we're detaching from, the result of the stop request will be cached on the lwp_info object, 15. In our case the vfork parent has exited though, so when GDB waits for the thread, instead of a stop due to signal, we instead get a thread exited status, 16. Later in the detach process we try to resume the threads just prior to making the ptrace call to actually detach (see detach_one_lwp), as part of the process to resume a thread we try to touch some registers within the thread, and before doing this GDB asserts that the thread is stopped, 17. An exited thread is not classified as stopped, and so the assert triggers! Just like with the earlier commit, the fix is to spot the vfork parent status of the thread, and not resume such threads. Where the earlier commit fixed this in linux-nat, in this case I think the fix should live in infrun.c, in proceed_resume_thread_checked. This function already has a similar check to not resume the vfork parent in the case where we are planning to follow the vfork parent, I propose adding a similar case that checks for the vfork parent when we plan to follow the vfork child. This new check will mean that at step #6 above GDB doesn't try to resume the vfork parent thread, which prevents the VFORK_DONE from ever arriving. Once GDB sees the EXECD/EXITED/SIGNALLED event from the vfork child GDB will detach from the parent. There's no test included in this commit. In a subsequent commit I will expand gdb.base/foll-vfork.exp which is when this bug would be exposed. If you do want to reproduce this failure then you will for certainly need to run the gdb.base/foll-vfork.exp test in a loop as the failures are all very timing sensitive. I've found that running multiple copies in parallel makes the failure more likely to appear, I usually run ~6 copies in parallel and expect to see a failure after within 10mins. --- gdb/infrun.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/gdb/infrun.c b/gdb/infrun.c index 010fcd7952f..2d2f7d67a0f 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -3299,10 +3299,12 @@ proceed_resume_thread_checked (thread_info *tp) } /* When handling a vfork GDB removes all breakpoints from the program - space in which the vfork is being handled, as such we must take care - not to resume any thread other than the vfork parent -- resuming the - vfork parent allows GDB to receive and handle the 'vfork done' - event. */ + space in which the vfork is being handled. If we are following the + parent then GDB will set the thread_waiting_for_vfork_done member of + the parent inferior. In this case we should take care to only resume + the vfork parent thread, the kernel will hold this thread suspended + until the vfork child has exited or execd, at which point the parent + will be resumed and a VFORK_DONE event sent to GDB. */ if (tp->inf->thread_waiting_for_vfork_done != nullptr) { if (target_is_non_stop_p ()) @@ -3341,6 +3343,20 @@ proceed_resume_thread_checked (thread_info *tp) } } + /* When handling a vfork GDB removes all breakpoints from the program + space in which the vfork is being handled. If we are following the + child then GDB will set vfork_child member of the vfork parent + inferior. Once the child has either exited or execd then GDB will + detach from the parent process. Until that point GDB should not + resume any thread in the parent process. */ + if (tp->inf->vfork_child != nullptr) + { + infrun_debug_printf ("[%s] thread is part of a vfork parent, child is %d", + tp->ptid.to_string ().c_str (), + tp->inf->vfork_child->pid); + return; + } + infrun_debug_printf ("resuming %s", tp->ptid.to_string ().c_str ()); From patchwork Tue Jul 4 15:22:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Burgess X-Patchwork-Id: 72081 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 94BC5387093F for ; Tue, 4 Jul 2023 15:24:23 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 94BC5387093F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1688484263; bh=2WjmivqQFrTiWFzf6SmnjSDzKaIGOZLbSA54cckrpu8=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=XNCCg/+4qjlXHuFdevdLO2De60YsT56+ybZgD8szfln28mJDxWww3O7NwEqgOckMQ dmg3i8hDuphgA7IG2GpOJbpDCX54PdfoMQiQVTRIs3dknttlGSsBil1TUUyYxD8Vrk cEDDFOaLo1/AxWURD6g975xzB7tWpM+lQFR18t04= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id 70051385558C for ; Tue, 4 Jul 2023 15:23:14 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 70051385558C Received: from mail-wr1-f70.google.com (mail-wr1-f70.google.com [209.85.221.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-552-bpw0VZGYPq61eoNw36KySg-1; Tue, 04 Jul 2023 11:23:13 -0400 X-MC-Unique: bpw0VZGYPq61eoNw36KySg-1 Received: by mail-wr1-f70.google.com with SMTP id ffacd0b85a97d-3142665f122so2457206f8f.0 for ; Tue, 04 Jul 2023 08:23:13 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1688484192; x=1691076192; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=2WjmivqQFrTiWFzf6SmnjSDzKaIGOZLbSA54cckrpu8=; b=cOGe0k4T9lW6b9XxcecWS538+wpXZLk+BEtQungdqDBosXKnXPFaPT3ot2v/nxcp5q ykDxqCnH4NiIyVvcHE2/R7k0reZh1HxK27JU9XRGkSpni6jZd5Csd46h8lU3bh208w17 +rd97HBMI2/pZvkMLvOb2v/sfn/TBvDK+EYIsHy2bpZiqW0vqWcEknhtdyFb1NZcjoHo ZWY9Y3n/pMufBXRqE43unbxvFRQYO50j6ZKRVM0OFy+drp08uiysVodKkC239O3+b89G DCzgvrN2wkNoiFeQkssuzmZffhGZbmDfUUKy+a8Arrdfrz0a92G4LhGr+htotObP1p1m sV+g== X-Gm-Message-State: ABy/qLbfpNEuv8K+nm5+ZSVo47PeYdbf0fF69kny4XNbp7124fPqUskY z0x1FLF1EsQ4wZGTHH8Wo/DoKiA+HXkRJh9SWWkKZ1qzWIXedi6kBhqw3DBbaP0knutCrkgv+Md JOnQZ1Y68Tzp5NUdorRjzpjT1zZvQ7nb9mWubnxB3B0HV4niH6F4O8D2YKBUqVSvocg4xwQrtfm jI9Ttavg== X-Received: by 2002:a5d:5511:0:b0:313:f59c:95ec with SMTP id b17-20020a5d5511000000b00313f59c95ecmr10770691wrv.28.1688484191586; Tue, 04 Jul 2023 08:23:11 -0700 (PDT) X-Google-Smtp-Source: APBJJlGb+Mpgt1rvk10m1WXPJm6mCTP1X5d5t88g54Lf4PL6YhNDkh8dB9apeXfWeuSkRqXKvL4HEg== X-Received: by 2002:a5d:5511:0:b0:313:f59c:95ec with SMTP id b17-20020a5d5511000000b00313f59c95ecmr10770662wrv.28.1688484191006; Tue, 04 Jul 2023 08:23:11 -0700 (PDT) Received: from localhost (2.72.115.87.dyn.plus.net. [87.115.72.2]) by smtp.gmail.com with ESMTPSA id fa12-20020a05600c518c00b003fbb1ce274fsm16121545wmb.0.2023.07.04.08.23.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 04 Jul 2023 08:23:10 -0700 (PDT) To: gdb-patches@sourceware.org Cc: Andrew Burgess , tankut.baris.aktemur@intel.com Subject: [PATCHv2 6/8] gdb/testsuite: expand gdb.base/foll-vfork.exp Date: Tue, 4 Jul 2023 16:22:56 +0100 Message-Id: <20cb4bbc67707268a75d32b8eaa539758ac4b31b.1688484032.git.aburgess@redhat.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: References: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.9 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, 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: , X-Patchwork-Original-From: Andrew Burgess via Gdb-patches From: Andrew Burgess Reply-To: Andrew Burgess Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" This commit provides tests for all of the bugs fixed in the previous four commits, this is achieved by expanding gdb.base/foll-vfork.exp to run with different configurations: * target-non-stop on/off * non-stop on/off * schedule-multiple on/off We don't test with schedule-multiple on if we are using a remote target, this is due to bug gdb/30574. I've added a link to that bug in this commit, but all this commit does is expose that bug, there's no fixes here. Some of the bugs fixed in the previous commits are very timing dependent, as such, they don't always show up. I've had more success when running this test on a very loaded machine -- I usually run ~8 copies of the test in parallel, then the bugs would normally show up pretty quickly. Other than running the test in more configurations, I've not made any changes to what is actually being tested, other than in one place where, when testing with non-stop mode, GDB stops in a different inferior, as such I had to add a new 'inferior 2' call, this can be found in vfork_relations_in_info_inferiors. I have cleaned things up a little, for example, making use of proc_with_prefix to remove some with_test_prefix calls. Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=30574 --- gdb/testsuite/gdb.base/foll-vfork.exp | 628 ++++++++++++-------------- 1 file changed, 300 insertions(+), 328 deletions(-) diff --git a/gdb/testsuite/gdb.base/foll-vfork.exp b/gdb/testsuite/gdb.base/foll-vfork.exp index bdceff0f5de..be0715b05c0 100644 --- a/gdb/testsuite/gdb.base/foll-vfork.exp +++ b/gdb/testsuite/gdb.base/foll-vfork.exp @@ -25,56 +25,52 @@ if {![istarget "*-linux*"]} { continue } -standard_testfile +standard_testfile .c -exit.c vforked-prog.c -set compile_options debug +set binfile $testfile +set binfile2 ${testfile}-exit +set binfile3 vforked-prog -if {[build_executable $testfile.exp $testfile $srcfile $compile_options] == -1} { +if {[build_executable "compile $binfile" $binfile $srcfile] == -1} { untested "failed to compile main testcase" return -1 } -set testfile2 "vforked-prog" -set srcfile2 ${testfile2}.c +if {[build_executable "compile $binfile2" $binfile2 $srcfile2] == -1} { + untested "failed to compile main testcase" + return -1 +} -if {[build_executable $testfile.exp $testfile2 $srcfile2 $compile_options] == -1} { - untested "failed to compile secondary testcase" +if {[build_executable "compile $binfile3" $binfile3 $srcfile3] == -1} { + untested "failed to compile main testcase" return -1 } +# If required, download the program that we exec after vfork to the +# remote target. if { [is_remote target] } { - gdb_remote_download target [standard_output_file $testfile2] + gdb_remote_download target [standard_output_file $binfile3] } -# A few of these tests require a little more time than the standard -# timeout allows. -set oldtimeout $timeout -set timeout [expr "$timeout + 10"] - # Start with a fresh GDB, with verbosity enabled, and run to main. On # error, behave as "return", so we don't try to continue testing with # a borked session. -proc setup_gdb {} { - global testfile srcfile - - clean_restart $testfile +proc setup_gdb { binfile srcfile } { + clean_restart $binfile if ![runto_main] { return -code return } - set tbreak_line [gdb_get_line_number " VFORK " $srcfile] - gdb_test "tbreak ${tbreak_line}" - gdb_continue_to_breakpoint ".*" + gdb_breakpoint [gdb_get_line_number " VFORK " $srcfile] temporary + gdb_continue_to_breakpoint "at VFORK" } proc check_vfork_catchpoints {} { - global gdb_prompt - # Because setup_gdb uses 'return -code return' which would return to # our caller we need to wrap this call, spot when setup_gdb failed # (with return code 2), and then issue our own 'return -code return'. - set code [catch {setup_gdb} string] + set code [catch {setup_gdb $::testfile $::srcfile} string] if { $code == 2 } { unsupported "vfork catchpoints" return -code return @@ -84,10 +80,10 @@ proc check_vfork_catchpoints {} { gdb_test "catch vfork" "Catchpoint \[0-9\]* \\(vfork\\)" "insert first vfork catchpoint" set has_vfork_catchpoints 0 gdb_test_multiple "continue" "continue to first vfork catchpoint" { - -re ".*Your system does not support this type\r\nof catchpoint.*$gdb_prompt $" { + -re -wrap ".*Your system does not support this type\r\nof catchpoint.*" { unsupported "continue to first vfork catchpoint" } - -re ".*Catchpoint.*$gdb_prompt $" { + -re -wrap ".*Catchpoint.*" { set has_vfork_catchpoints 1 pass "continue to first vfork catchpoint" } @@ -99,319 +95,278 @@ proc check_vfork_catchpoints {} { } } -proc vfork_parent_follow_through_step {} { - with_test_prefix "vfork parent follow, through step" { - global gdb_prompt +proc_with_prefix vfork_parent_follow_through_step { binfile srcfile } { + setup_gdb $binfile $srcfile - setup_gdb + gdb_test_no_output "set follow-fork parent" - gdb_test_no_output "set follow-fork parent" + gdb_test_multiple "next" "" { + -re -wrap "\\\[Detaching after vfork from.*if \\(pid == 0\\).*" { + pass $gdb_test_name + } + } - set test "step" - gdb_test_multiple "next" $test { - -re "\\\[Detaching after vfork from.*if \\(pid == 0\\).*$gdb_prompt " { - pass $test - } - } - # The child has been detached; allow time for any output it might - # generate to arrive, so that output doesn't get confused with - # any gdb_expected debugger output from a subsequent testpoint. - # - exec sleep 1 -}} - -proc vfork_parent_follow_to_bp {} { - with_test_prefix "vfork parent follow, to bp" { - global gdb_prompt - global srcfile - - setup_gdb - - gdb_test_no_output "set follow-fork parent" - - set bp_location [gdb_get_line_number "I'm the proud parent of child"] - gdb_test "break ${srcfile}:${bp_location}" ".*" "break, vfork to bp" - - set test "continue to bp" - gdb_test_multiple "continue" $test { - -re ".*\\\[Detaching after vfork from child process.*Breakpoint.*${bp_location}.*$gdb_prompt " { - pass $test - } - } - # The child has been detached; allow time for any output it might - # generate to arrive, so that output doesn't get confused with - # any expected debugger output from a subsequent testpoint. - # - exec sleep 1 -}} - -proc vfork_child_follow_to_exit {} { - with_test_prefix "vfork child follow, to exit" { - global gdb_prompt - - setup_gdb - - gdb_test_no_output "set follow-fork child" - - set test "continue to child exit" - gdb_test_multiple "continue" $test { - -re "Couldn't get registers.*$gdb_prompt " { - # PR gdb/14766 - fail "$test" - } - -re "\\\[Attaching after.* vfork to.*\\\[Detaching vfork parent .* after child exit.*$gdb_prompt " { - pass $test - } - } - # The parent has been detached; allow time for any output it might - # generate to arrive, so that output doesn't get confused with - # any gdb_expected debugger output from a subsequent testpoint. - # - exec sleep 1 -}} + # The child has been detached; allow time for any output it might + # generate to arrive, so that output doesn't get confused with + # any gdb_expected debugger output from a subsequent testpoint. + # + exec sleep 1 +} -proc vfork_and_exec_child_follow_to_main_bp {} { - with_test_prefix "vfork and exec child follow, to main bp" { - global gdb_prompt - global srcfile2 +proc_with_prefix vfork_parent_follow_to_bp { binfile srcfile } { + setup_gdb $binfile $srcfile - setup_gdb + gdb_test_no_output "set follow-fork parent" - gdb_test_no_output "set follow-fork child" + set bp_location \ + [gdb_get_line_number "I'm the proud parent of child" $srcfile] + gdb_test "break ${srcfile}:${bp_location}" ".*" "break, vfork to bp" - set linenum [gdb_get_line_number "Hello from vforked-prog" ${srcfile2}] + gdb_test_multiple "continue" "continue to bp" { + -re -wrap ".*\\\[Detaching after vfork from child process.*Breakpoint.*${bp_location}.*" { + pass $gdb_test_name + } + } - set test "continue to bp" - gdb_test_multiple "continue" $test { - -re "\\\[Attaching after.* vfork to.*\\\[Detaching vfork parent.*xecuting new program.*Breakpoint.*vforked-prog.c:${linenum}.*$gdb_prompt " { - pass $test - } - } - # The parent has been detached; allow time for any output it might - # generate to arrive, so that output doesn't get confused with - # any gdb_expected debugger output from a subsequent testpoint. - # - exec sleep 1 -}} - -proc vfork_and_exec_child_follow_through_step {} { - with_test_prefix "vfork and exec child follow, through step" { - global gdb_prompt - global srcfile2 - - setup_gdb - - gdb_test_no_output "set follow-fork child" - - set test "step over vfork" - - # The ideal support is to be able to debug the child even - # before it execs. Thus, "next" lands on the next line after - # the vfork. - gdb_test_multiple "next" $test { - -re "\\\[Attaching after .* vfork to child.*if \\(pid == 0\\).*$gdb_prompt " { - pass "$test" - } - } - # The parent has been detached; allow time for any output it might - # generate to arrive, so that output doesn't get confused with - # any expected debugger output from a subsequent testpoint. - # - exec sleep 1 -}} + # The child has been detached; allow time for any output it might + # generate to arrive, so that output doesn't get confused with + # any expected debugger output from a subsequent testpoint. + # + exec sleep 1 +} + +proc_with_prefix vfork_child_follow_to_exit { binfile srcfile } { + setup_gdb $binfile $srcfile + + gdb_test_no_output "set follow-fork child" + + gdb_test_multiple "continue" "continue to child exit" { + -re -wrap "Couldn't get registers.*" { + # PR gdb/14766 + fail $gdb_test_name + } + -re -wrap "\\\[Attaching after.* vfork to.*\\\[Detaching vfork parent .* after child exit.*" { + pass $gdb_test_name + } + } + + # The parent has been detached; allow time for any output it might + # generate to arrive, so that output doesn't get confused with + # any gdb_expected debugger output from a subsequent testpoint. + # + exec sleep 1 +} + +proc_with_prefix vfork_and_exec_child_follow_to_main_bp { binfile srcfile } { + setup_gdb $binfile $srcfile + + gdb_test_no_output "set follow-fork child" + + set linenum [gdb_get_line_number "Hello from vforked-prog" ${::srcfile3}] + + gdb_test_multiple "continue" "continue to bp" { + -re -wrap "\\\[Attaching after.* vfork to.*\\\[Detaching vfork parent.*xecuting new program.*Breakpoint.*vforked-prog.c:${linenum}.*" { + pass $gdb_test_name + } + } + + # The parent has been detached; allow time for any output it might + # generate to arrive, so that output doesn't get confused with + # any gdb_expected debugger output from a subsequent testpoint. + # + exec sleep 1 +} + +proc_with_prefix vfork_and_exec_child_follow_through_step { binfile srcfile } { + setup_gdb $binfile $srcfile + + gdb_test_no_output "set follow-fork child" + + # The ideal support is to be able to debug the child even + # before it execs. Thus, "next" lands on the next line after + # the vfork. + gdb_test_multiple "next" "next over vfork" { + -re -wrap "\\\[Attaching after .* vfork to child.*if \\(pid == 0\\).*" { + pass $gdb_test_name + } + } + + # The parent has been detached; allow time for any output it might + # generate to arrive, so that output doesn't get confused with + # any expected debugger output from a subsequent testpoint. + # + exec sleep 1 +} proc continue_to_vfork {} { - global gdb_prompt - - # A vfork catchpoint may stop in either "vfork" or "_vfork". - set test "continue to vfork" - gdb_test_multiple "continue" $test { - -re "vfork \\(\\) at .*$gdb_prompt $" { - pass $test - } - -re "0x\[0-9a-fA-F\]*.*(vfork|__kernel_v?syscall).*$gdb_prompt " { - pass $test - } - } + # A vfork catchpoint may stop in either "vfork" or "_vfork". + gdb_test_multiple "continue" "continue to vfork" { + -re -wrap "vfork \\(\\) at .*" { + pass $gdb_test_name + } + -re -wrap "0x\[0-9a-fA-F\]*.*(vfork|__kernel_v?syscall).*" { + pass $gdb_test_name + } + } } -proc tcatch_vfork_then_parent_follow {} { - with_test_prefix "vfork parent follow, finish after tcatch vfork" { - global gdb_prompt - global srcfile - - setup_gdb - - gdb_test_no_output "set follow-fork parent" - - gdb_test "tcatch vfork" "Catchpoint .*(vfork).*" - - continue_to_vfork - - set linenum [gdb_get_line_number "pid = vfork ();"] - set test "finish" - gdb_test_multiple "finish" $test { - -re "Run till exit from.*vfork.*0x\[0-9a-fA-F\]* in main .* at .*${srcfile}:${linenum}.*$gdb_prompt " { - pass $test - } - -re "Run till exit from.*__kernel_v?syscall.*0x\[0-9a-fA-F\]* in vfork .*$gdb_prompt " { - send_gdb "finish\n" - exp_continue - } - } - # The child has been detached; allow time for any output it might - # generate to arrive, so that output doesn't get confused with - # any expected debugger output from a subsequent testpoint. - # - exec sleep 1 -}} - -proc tcatch_vfork_then_child_follow_exec {} { - with_test_prefix "vfork child follow, finish after tcatch vfork" { - global gdb_prompt - global srcfile - global srcfile2 - - setup_gdb - - gdb_test_no_output "set follow-fork child" - - gdb_test "tcatch vfork" "Catchpoint .*(vfork).*" - - continue_to_vfork - - set linenum1 [gdb_get_line_number "pid = vfork ();"] - set linenum2 [gdb_get_line_number "Hello from vforked-prog" ${srcfile2}] - - set test "finish" - gdb_test_multiple "finish" $test { - -re "Run till exit from.*vfork.*${srcfile}:${linenum1}.*$gdb_prompt " { - pass $test - } - -re "Run till exit from.*__kernel_v?syscall.*0x\[0-9a-fA-F\]* in vfork .*$gdb_prompt " { - send_gdb "finish\n" - exp_continue - } - -re "Run till exit from.*vfork.*${srcfile2}:${linenum2}.*$gdb_prompt " { - pass "$test (followed exec)" - } - } - # The parent has been detached; allow time for any output it might - # generate to arrive, so that output doesn't get confused with - # any expected debugger output from a subsequent testpoint. - # - exec sleep 1 -}} - -proc tcatch_vfork_then_child_follow_exit {} { - with_test_prefix "vfork child follow, finish after tcatch vfork" { - global gdb_prompt - global srcfile - - setup_gdb - - gdb_test_no_output "set follow-fork child" - - gdb_test "tcatch vfork" "Catchpoint .*(vfork).*" - - continue_to_vfork - - set test "finish" - gdb_test_multiple "finish" $test { - -re "Run till exit from.*vfork.*exited normally.*$gdb_prompt " { - setup_kfail "gdb/14762" *-*-* - fail $test - } - -re "Run till exit from.*vfork.*pid = vfork \\(\\).*$gdb_prompt " { - pass $test - } - -re "Run till exit from.*__kernel_v?syscall.*0x\[0-9a-fA-F\]* in vfork .*$gdb_prompt " { - send_gdb "finish\n" - exp_continue - } - } - # The parent has been detached; allow time for any output it might - # generate to arrive, so that output doesn't get confused with - # any expected debugger output from a subsequent testpoint. - # - exec sleep 1 -}} +proc_with_prefix tcatch_vfork_then_parent_follow { binfile srcfile } { + setup_gdb $binfile $srcfile -proc vfork_relations_in_info_inferiors { variant } { - with_test_prefix "vfork relations in info inferiors" { - global gdb_prompt + gdb_test_no_output "set follow-fork parent" - setup_gdb + gdb_test "tcatch vfork" "Catchpoint .*(vfork).*" - gdb_test_no_output "set follow-fork child" + continue_to_vfork - set test "step over vfork" - gdb_test_multiple "next" $test { - -re "\\\[Attaching after .* vfork to child.*if \\(pid == 0\\).*$gdb_prompt " { - pass "$test" - } - } + set linenum [gdb_get_line_number "pid = vfork ();" $srcfile] + gdb_test_multiple "finish" "" { + -re -wrap "Run till exit from.*vfork.*0x\[0-9a-fA-F\]* in main .* at .*${srcfile}:${linenum}.*" { + pass $gdb_test_name + } + -re -wrap "Run till exit from.*__kernel_v?syscall.*0x\[0-9a-fA-F\]* in vfork .*" { + send_gdb "finish\n" + exp_continue + } + } - gdb_test "info inferiors" \ - ".*is vfork parent of inferior 2.*is vfork child of inferior 1" \ - "info inferiors shows vfork parent/child relation" + # The child has been detached; allow time for any output it might + # generate to arrive, so that output doesn't get confused with + # any expected debugger output from a subsequent testpoint. + # + exec sleep 1 +} - if { $variant == "exec" } { - global srcfile2 +proc_with_prefix tcatch_vfork_then_child_follow_exec { binfile srcfile } { + setup_gdb $binfile $srcfile - set linenum [gdb_get_line_number "Hello from vforked-prog" ${srcfile2}] - set test "continue to bp" - gdb_test_multiple "continue" $test { - -re ".*xecuting new program.*Breakpoint.*vforked-prog.c:${linenum}.*$gdb_prompt " { - pass $test - } - } - } else { - set test "continue to child exit" - gdb_test_multiple "continue" $test { - -re "exited normally.*$gdb_prompt " { - pass $test + gdb_test_no_output "set follow-fork child" + + gdb_test "tcatch vfork" "Catchpoint .*(vfork).*" + + continue_to_vfork + + set linenum1 [gdb_get_line_number "pid = vfork ();" $srcfile] + set linenum2 [gdb_get_line_number "Hello from vforked-prog" ${::srcfile3}] + + gdb_test_multiple "finish" "" { + -re -wrap "Run till exit from.*vfork.*${srcfile}:${linenum1}.*" { + pass $gdb_test_name + } + -re -wrap "Run till exit from.*__kernel_v?syscall.*0x\[0-9a-fA-F\]* in vfork .*" { + send_gdb "finish\n" + exp_continue + } + -re -wrap "Run till exit from.*vfork.*${::srcfile3}:${linenum2}.*" { + pass "$gdb_test_name (followed exec)" + } + } + + # The parent has been detached; allow time for any output it might + # generate to arrive, so that output doesn't get confused with + # any expected debugger output from a subsequent testpoint. + # + exec sleep 1 +} + +proc tcatch_vfork_then_child_follow_exit { binfile srcfile } { + setup_gdb $binfile $srcfile + + gdb_test_no_output "set follow-fork child" + + gdb_test "tcatch vfork" "Catchpoint .*(vfork).*" + + continue_to_vfork + + gdb_test_multiple "finish" "" { + -re -wrap "Run till exit from.*vfork.*exited normally.*" { + setup_kfail "gdb/14762" *-*-* + fail $gdb_test_name + } + -re -wrap "Run till exit from.*vfork.*pid = vfork \\(\\).*" { + pass $gdb_test_name + } + -re -wrap "Run till exit from.*__kernel_v?syscall.*0x\[0-9a-fA-F\]* in vfork .*" { + send_gdb "finish\n" + exp_continue + } + } + + # The parent has been detached; allow time for any output it might + # generate to arrive, so that output doesn't get confused with + # any expected debugger output from a subsequent testpoint. + # + exec sleep 1 +} + +proc_with_prefix vfork_relations_in_info_inferiors { variant binfile srcfile non_stop } { + setup_gdb $binfile $srcfile + + gdb_test_no_output "set follow-fork child" + + gdb_test_multiple "next" "next over vfork" { + -re -wrap "\\\[Attaching after .* vfork to child.*if \\(pid == 0\\).*" { + pass $gdb_test_name + } + } + + if { $non_stop } { + gdb_test "inferior 2" ".*" + } + + gdb_test "info inferiors" \ + ".*is vfork parent of inferior 2.*is vfork child of inferior 1" \ + "info inferiors shows vfork parent/child relation" + + if { $variant == "exec" } { + set linenum [gdb_get_line_number "Hello from vforked-prog" ${::srcfile3}] + gdb_test_multiple "continue" "continue to bp" { + -re -wrap ".*xecuting new program.*Breakpoint.*vforked-prog.c:${linenum}.*" { + pass $gdb_test_name + } + } + } else { + gdb_test_multiple "continue" "continue to child exit" { + -re -wrap "exited normally.*" { + pass $gdb_test_name } - } - } - - set test "vfork relation no longer appears in info inferiors" - gdb_test_multiple "info inferiors" $test { - -re -wrap "is vfork child of inferior 1.*" { - fail $test - } - -re -wrap "is vfork parent of inferior 2.*" { - fail $test - } - -re -wrap "" { - pass $test - } - } -}} - -proc do_vfork_and_follow_parent_tests {} { - global gdb_prompt + } + } + gdb_test_multiple "info inferiors" "vfork relation no longer appears in info inferiors" { + -re -wrap "is vfork child of inferior 1.*" { + fail $gdb_test_name + } + -re -wrap "is vfork parent of inferior 2.*" { + fail $gdb_test_name + } + -re -wrap "" { + pass $gdb_test_name + } + } +} + +proc do_vfork_and_follow_parent_tests { binfile srcfile } { # Try following the parent process by stepping through a call to # vfork. Do this without catchpoints. - vfork_parent_follow_through_step + vfork_parent_follow_through_step $binfile $srcfile # Try following the parent process by setting a breakpoint on the # other side of a vfork, and running to that point. Do this # without catchpoints. - vfork_parent_follow_to_bp + vfork_parent_follow_to_bp $binfile $srcfile # Try catching a vfork, and stepping out to the parent. # - tcatch_vfork_then_parent_follow + tcatch_vfork_then_parent_follow $binfile $srcfile } -proc do_vfork_and_follow_child_tests_exec {} { +proc do_vfork_and_follow_child_tests_exec { binfile srcfile non_stop } { # Try following the child process by just continuing through the # vfork, and letting the parent's breakpoint on "main" be auto- # magically reset in the child. # - vfork_and_exec_child_follow_to_main_bp + vfork_and_exec_child_follow_to_main_bp $binfile $srcfile # Try following the child process by stepping through a call to # vfork. The child also executes an exec. Since the child cannot @@ -420,11 +375,11 @@ proc do_vfork_and_follow_child_tests_exec {} { # recomputed in the exec'd child, the step through a vfork should # land us in the "main" for the exec'd child, too. # - vfork_and_exec_child_follow_through_step + vfork_and_exec_child_follow_through_step $binfile $srcfile # Try catching a vfork, and stepping out to the child. # - tcatch_vfork_then_child_follow_exec + tcatch_vfork_then_child_follow_exec $binfile $srcfile # Test the ability to follow both child and parent of a vfork. Do # this without catchpoints. @@ -442,25 +397,25 @@ proc do_vfork_and_follow_child_tests_exec {} { # and confirm the relation is no longer displayed in "info # inferiors". # - vfork_relations_in_info_inferiors "exec" + vfork_relations_in_info_inferiors "exec" $binfile $srcfile $non_stop } -proc do_vfork_and_follow_child_tests_exit {} { +proc do_vfork_and_follow_child_tests_exit { binfile srcfile non_stop } { # Try following the child process by just continuing through the # vfork, and letting the child exit. # - vfork_child_follow_to_exit + vfork_child_follow_to_exit $binfile $srcfile # Try catching a vfork, and stepping out to the child. # - tcatch_vfork_then_child_follow_exit + tcatch_vfork_then_child_follow_exit $binfile $srcfile # Step over a vfork in the child, do "info inferiors" and check the # parent/child relation is displayed. Run the child to completion, # and confirm the relation is no longer displayed in "info # inferiors". # - vfork_relations_in_info_inferiors "exit" + vfork_relations_in_info_inferiors "exit" $binfile $srcfile $non_stop } with_test_prefix "check vfork support" { @@ -470,41 +425,58 @@ with_test_prefix "check vfork support" { } # Follow parent and follow child vfork tests with a child that execs. -with_test_prefix "exec" { +proc_with_prefix exec_tests { binfile srcfile non_stop } { # These are tests of gdb's ability to follow the parent of a Unix # vfork system call. The child will subsequently call a variant # of the Unix exec system call. - do_vfork_and_follow_parent_tests + do_vfork_and_follow_parent_tests $binfile $srcfile # These are tests of gdb's ability to follow the child of a Unix # vfork system call. The child will subsequently call a variant # of a Unix exec system call. # - do_vfork_and_follow_child_tests_exec -} - -# Switch to test the case of the child exiting. We can't use -# standard_testfile here because we don't want to overwrite the binary -# of the previous tests. -set testfile "foll-vfork-exit" -set srcfile ${testfile}.c -set binfile [standard_output_file ${testfile}] - -if {[build_executable $testfile.exp $testfile $srcfile] == -1} { - untested "failed to build $testfile" - return + do_vfork_and_follow_child_tests_exec $binfile $srcfile $non_stop } # Follow parent and follow child vfork tests with a child that exits. -with_test_prefix "exit" { +proc_with_prefix exit_tests { binfile srcfile non_stop } { # These are tests of gdb's ability to follow the parent of a Unix # vfork system call. The child will subsequently exit. - do_vfork_and_follow_parent_tests + do_vfork_and_follow_parent_tests $binfile $srcfile # These are tests of gdb's ability to follow the child of a Unix # vfork system call. The child will subsequently exit. # - do_vfork_and_follow_child_tests_exit + do_vfork_and_follow_child_tests_exit $binfile $srcfile $non_stop +} + +# Using the remote protocol with schedule-multiple turned triggers bug +# gdb/30574, so avoid this for now. +if {[target_info exists gdb_protocol] + && ([target_info gdb_protocol] == "remote" + || [target_info gdb_protocol] == "extended-remote")} { + set sm_modes { off } +} else { + set sm_modes { off on } } -set timeout $oldtimeout +# A few of these tests require a little more time than the standard timeout +# allows. +with_timeout_factor 2 { + foreach_with_prefix target-non-stop {auto on off} { + foreach_with_prefix non-stop {off on} { + foreach_with_prefix schedule-multiple $sm_modes { + save_vars { ::GDBFLAGS } { + # These flags will be picked up by the call to + # clean_restart inside setup_gdb. + append ::GDBFLAGS " -ex \"maintenance set target-non-stop ${target-non-stop}\"" + append ::GDBFLAGS " -ex \"set non-stop ${non-stop}\"" + append ::GDBFLAGS " -ex \"set schedule-multiple ${schedule-multiple}\"" + + exec_tests $binfile $srcfile ${non-stop} + exit_tests $binfile2 $srcfile2 ${non-stop} + } + } + } + } +} From patchwork Tue Jul 4 15:22:57 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Burgess X-Patchwork-Id: 72080 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 B90803851ABC for ; Tue, 4 Jul 2023 15:23:59 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org B90803851ABC DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1688484239; bh=qlT6NWnA117BtEp4OTwtH4P644YNxJpV+p4TmFJoWMM=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=byaTU/LoN5M3PrYs+Aq8EYCj7e7y5nsGY43+3HqgJCJXNRta2jOYn9iUqqwlN/Tli K89kH1ctz9Opk/V8R1TTF9rGW7u8CjRAXpIq6LZGDn2E3SqUxBxQQDqvqaQN5D72jp KlHyOF8GTmA9AOOqGu0mmPYVln4bibwfzY+gEJ+0= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id 920EB3856DD0 for ; Tue, 4 Jul 2023 15:23:15 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 920EB3856DD0 Received: from mail-wm1-f69.google.com (mail-wm1-f69.google.com [209.85.128.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-523-w0Z2UikzPhmFKjfPj7NK0w-1; Tue, 04 Jul 2023 11:23:14 -0400 X-MC-Unique: w0Z2UikzPhmFKjfPj7NK0w-1 Received: by mail-wm1-f69.google.com with SMTP id 5b1f17b1804b1-3fa979d0c32so33378305e9.2 for ; Tue, 04 Jul 2023 08:23:13 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1688484192; x=1691076192; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=qlT6NWnA117BtEp4OTwtH4P644YNxJpV+p4TmFJoWMM=; b=Vzby9mBwDNLPXtvzfNU5paWys3d0AqlQqg+HP8ZcMQz6s8q1egKXqYbAcZh6S5/HbP Yhk7VzYiyEjitJBPOl7Xobpk+SEhZ7h+yhPnMzEbRggX80Jml66kUvNJP2QsZI+EJ+vM nK6aV9oy0dIlGfg8wsf3nm9NxPNYBv5TZDLu4LEeyuFasue10ftk6cI7XdKArYkzH34s CSSwnCc29+IT95ZCzgGfLNGD1mOZT1FhwjsNPz8qQOdhLcDPDLFD1v3XjSeXd31Z6Eqq FR9pAfR5T1/kHDIQurhVtO+awq9pU4lcz462jxN6lOSTdf78jKFl5+KwNFyI29U+QA9T NmNg== X-Gm-Message-State: AC+VfDyuGM5B7ZUqPIKfGHRPrn9y0/47U204Tk8XYlTDNmxvYpy6D4Zg m77SG7Pvky3yB7YipH6HQjE08ccLd7dX1l71e9kd/q4Y924BMSROW2QUch1GAyzDJZfVMQ8rFeQ lLx3PzhKAyox91lWGUl81mAplmr+xyka8J49X3Lsnhsgxyp/kfYmwi8zFdx8+5RdSwT7Q6JUfIa FFKqZSlA== X-Received: by 2002:a1c:f70a:0:b0:3fb:c060:8b3d with SMTP id v10-20020a1cf70a000000b003fbc0608b3dmr10459371wmh.40.1688484192669; Tue, 04 Jul 2023 08:23:12 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ5LFqJUrbdCfFN8OR+WqzafFQAJvj2CuY3GToA67scUedsJzetcHV7AztNkrpRBl80nbe3wdQ== X-Received: by 2002:a1c:f70a:0:b0:3fb:c060:8b3d with SMTP id v10-20020a1cf70a000000b003fbc0608b3dmr10459354wmh.40.1688484192309; Tue, 04 Jul 2023 08:23:12 -0700 (PDT) Received: from localhost (2.72.115.87.dyn.plus.net. [87.115.72.2]) by smtp.gmail.com with ESMTPSA id p23-20020a1c7417000000b003fbdd9c72aasm3895753wmc.21.2023.07.04.08.23.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 04 Jul 2023 08:23:12 -0700 (PDT) To: gdb-patches@sourceware.org Cc: Andrew Burgess , tankut.baris.aktemur@intel.com Subject: [PATCHv2 7/8] gdb/testsuite: remove use of sleep from gdb.base/foll-vfork.exp Date: Tue, 4 Jul 2023 16:22:57 +0100 Message-Id: <36f84df0fd365f78be0c94b8cdb382c2c272e94e.1688484032.git.aburgess@redhat.com> X-Mailer: git-send-email 2.25.4 In-Reply-To: References: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.9 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, 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: , X-Patchwork-Original-From: Andrew Burgess via Gdb-patches From: Andrew Burgess Reply-To: Andrew Burgess Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" While working on gdb.base/foll-vfork.exp I noticed that there are several random 'sleep' calls throughout the test. The comment suggests these are to allow for output from a vforked child to arrive, but in each case the test is about to close and restart GDB, so I don't see how random output from a child process could impact testing. I removed the sleep calls and couldn't reproduce any failures from this test, I left the test running for a couple of hours, and tried loading my machine, and the test seems fine with these removed. I've left this as a separate commit so that if, in the future, someone can show that these are required, it will be easy to revert this one patch and bring them back. There should be no change in what is tested after this commit. --- gdb/testsuite/gdb.base/foll-vfork.exp | 48 --------------------------- 1 file changed, 48 deletions(-) diff --git a/gdb/testsuite/gdb.base/foll-vfork.exp b/gdb/testsuite/gdb.base/foll-vfork.exp index be0715b05c0..43fc25cc2c0 100644 --- a/gdb/testsuite/gdb.base/foll-vfork.exp +++ b/gdb/testsuite/gdb.base/foll-vfork.exp @@ -105,12 +105,6 @@ proc_with_prefix vfork_parent_follow_through_step { binfile srcfile } { pass $gdb_test_name } } - - # The child has been detached; allow time for any output it might - # generate to arrive, so that output doesn't get confused with - # any gdb_expected debugger output from a subsequent testpoint. - # - exec sleep 1 } proc_with_prefix vfork_parent_follow_to_bp { binfile srcfile } { @@ -127,12 +121,6 @@ proc_with_prefix vfork_parent_follow_to_bp { binfile srcfile } { pass $gdb_test_name } } - - # The child has been detached; allow time for any output it might - # generate to arrive, so that output doesn't get confused with - # any expected debugger output from a subsequent testpoint. - # - exec sleep 1 } proc_with_prefix vfork_child_follow_to_exit { binfile srcfile } { @@ -149,12 +137,6 @@ proc_with_prefix vfork_child_follow_to_exit { binfile srcfile } { pass $gdb_test_name } } - - # The parent has been detached; allow time for any output it might - # generate to arrive, so that output doesn't get confused with - # any gdb_expected debugger output from a subsequent testpoint. - # - exec sleep 1 } proc_with_prefix vfork_and_exec_child_follow_to_main_bp { binfile srcfile } { @@ -169,12 +151,6 @@ proc_with_prefix vfork_and_exec_child_follow_to_main_bp { binfile srcfile } { pass $gdb_test_name } } - - # The parent has been detached; allow time for any output it might - # generate to arrive, so that output doesn't get confused with - # any gdb_expected debugger output from a subsequent testpoint. - # - exec sleep 1 } proc_with_prefix vfork_and_exec_child_follow_through_step { binfile srcfile } { @@ -190,12 +166,6 @@ proc_with_prefix vfork_and_exec_child_follow_through_step { binfile srcfile } { pass $gdb_test_name } } - - # The parent has been detached; allow time for any output it might - # generate to arrive, so that output doesn't get confused with - # any expected debugger output from a subsequent testpoint. - # - exec sleep 1 } proc continue_to_vfork {} { @@ -229,12 +199,6 @@ proc_with_prefix tcatch_vfork_then_parent_follow { binfile srcfile } { exp_continue } } - - # The child has been detached; allow time for any output it might - # generate to arrive, so that output doesn't get confused with - # any expected debugger output from a subsequent testpoint. - # - exec sleep 1 } proc_with_prefix tcatch_vfork_then_child_follow_exec { binfile srcfile } { @@ -261,12 +225,6 @@ proc_with_prefix tcatch_vfork_then_child_follow_exec { binfile srcfile } { pass "$gdb_test_name (followed exec)" } } - - # The parent has been detached; allow time for any output it might - # generate to arrive, so that output doesn't get confused with - # any expected debugger output from a subsequent testpoint. - # - exec sleep 1 } proc tcatch_vfork_then_child_follow_exit { binfile srcfile } { @@ -291,12 +249,6 @@ proc tcatch_vfork_then_child_follow_exit { binfile srcfile } { exp_continue } } - - # The parent has been detached; allow time for any output it might - # generate to arrive, so that output doesn't get confused with - # any expected debugger output from a subsequent testpoint. - # - exec sleep 1 } proc_with_prefix vfork_relations_in_info_inferiors { variant binfile srcfile non_stop } { From patchwork Tue Jul 4 15:22:58 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Burgess X-Patchwork-Id: 72085 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 CC2553856DCE for ; Tue, 4 Jul 2023 15:25:12 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org CC2553856DCE DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1688484312; bh=G/zIfOJp2nfWAScMrZXbicWhqLpFRvmqyc32HWVP4+A=; h=To:Cc:Subject:Date:In-Reply-To:References:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=Ry7NX0bru5vvX3q4KEHlNFhRfb9xVBUpZFyBMriL3TMtseyi/zsYLCbux5ciUKGan +6iyrWSxDZLFXa+3bsEHXhj823ayTB88FhFZSamjSupT7u6ntgypWL6wTGwTyA5LQV jcKtnm52FwdwaphanZPD8dsqs0oVLQcveYI/o5RA= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id A3A20385C6F4 for ; Tue, 4 Jul 2023 15:23:17 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org A3A20385C6F4 Received: from mail-lf1-f70.google.com (mail-lf1-f70.google.com [209.85.167.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-581-2IOvFDX5MPW7I_Nbm7XQjw-1; Tue, 04 Jul 2023 11:23:16 -0400 X-MC-Unique: 2IOvFDX5MPW7I_Nbm7XQjw-1 Received: by mail-lf1-f70.google.com with SMTP id 2adb3069b0e04-4f3932e595dso5333997e87.1 for ; Tue, 04 Jul 2023 08:23:15 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1688484194; x=1691076194; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=G/zIfOJp2nfWAScMrZXbicWhqLpFRvmqyc32HWVP4+A=; b=Fs+6Y7L8sBi0I54n9au8LB17zkm6hQR4WWXF3bVDrKLKceBaFCyCX1UBeCoEbfZk4W giYzK2NRJSKUaMVsSelvnpbTsctG/UlS8ZTU/Etazy+77hwgYf2mBqw5qK/a7RmYk4Bp WsWvq3QKmsQC5Vs5dx+MIkwlWJtleuRH0cE0A4sVMAn84roiWErj8/d5qBSRPSDO/RnO AWblh9VsToEZauD/xJrDdgbubPA9F+0+9vJxpP6hbGwgYwxYeBF65DjiVlLKbMP80FsD mvN07T4Cukbkly8pO4jBNRIbIUDdPiRfAwQI3feRvRcyCrFUqfgwPm3uAA9P/I9ojyh9 +J1w== X-Gm-Message-State: ABy/qLakZa/O3Jf3U5FbY0Z1riw2fAJ8UJgY0BO2PE126Sh+qXN03Kan 9ZpvNH+IqoYq3qKp0n4xj+OhpPXJdyRvyx0W++yWvDraoPKv5IlYkVGkKTPfqENgJZkAE1zXUKJ GWfnSMHIBtt4/u5G620HP4CWCDll0ANJfCckU4GImxcN4bJhqI3HruL3rDQUjYrsPukfV/vnqw0 k71/OXng== X-Received: by 2002:a19:5e06:0:b0:4f8:5671:ed1 with SMTP id s6-20020a195e06000000b004f856710ed1mr8943165lfb.29.1688484194281; Tue, 04 Jul 2023 08:23:14 -0700 (PDT) X-Google-Smtp-Source: APBJJlEiYQBaytjhxmO/65le40xWnDnquQh7+FEi0ooqWVN/KR890UhTgxKMT2ByTNsFeLGfXHKZKA== X-Received: by 2002:a19:5e06:0:b0:4f8:5671:ed1 with SMTP id s6-20020a195e06000000b004f856710ed1mr8943149lfb.29.1688484193951; Tue, 04 Jul 2023 08:23:13 -0700 (PDT) Received: from localhost (2.72.115.87.dyn.plus.net. [87.115.72.2]) by smtp.gmail.com with ESMTPSA id n20-20020a7bcbd4000000b003fb739d27aesm22288341wmi.35.2023.07.04.08.23.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 04 Jul 2023 08:23:13 -0700 (PDT) To: gdb-patches@sourceware.org Cc: Andrew Burgess , tankut.baris.aktemur@intel.com Subject: [PATCHv2 8/8] gdb: additional debug output in infrun.c and linux-nat.c Date: Tue, 4 Jul 2023 16:22:58 +0100 Message-Id: X-Mailer: git-send-email 2.25.4 In-Reply-To: References: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-11.9 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, 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: , X-Patchwork-Original-From: Andrew Burgess via Gdb-patches From: Andrew Burgess Reply-To: Andrew Burgess Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" While working on some of the recent patches relating to vfork handling I found this debug output very helpful, I'd like to propose adding this into GDB. With debug turned off there should be no user visible changes after this commit. --- gdb/infrun.c | 28 ++++++++++++++++++++++++---- gdb/linux-nat.c | 23 +++++++++++++++++++---- 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/gdb/infrun.c b/gdb/infrun.c index 2d2f7d67a0f..7efa0617526 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -435,6 +435,11 @@ show_follow_fork_mode_string (struct ui_file *file, int from_tty, static bool follow_fork_inferior (bool follow_child, bool detach_fork) { + INFRUN_SCOPED_DEBUG_ENTER_EXIT; + + infrun_debug_printf ("follow_child = %d, detach_fork = %d", + follow_child, detach_fork); + target_waitkind fork_kind = inferior_thread ()->pending_follow.kind (); gdb_assert (fork_kind == TARGET_WAITKIND_FORKED || fork_kind == TARGET_WAITKIND_VFORKED); @@ -543,6 +548,13 @@ holding the child stopped. Try \"set detach-on-fork\" or \ parent_inf->thread_waiting_for_vfork_done = detach_fork ? inferior_thread () : nullptr; parent_inf->pspace->breakpoints_not_allowed = detach_fork; + + infrun_debug_printf + ("parent_inf->thread_waiting_for_vfork_done == %s", + (parent_inf->thread_waiting_for_vfork_done == nullptr + ? "nullptr" + : (parent_inf->thread_waiting_for_vfork_done + ->ptid.to_string ().c_str ()))); } } else @@ -727,6 +739,8 @@ set_last_target_status_stopped (thread_info *tp) static bool follow_fork () { + INFRUN_SCOPED_DEBUG_ENTER_EXIT; + bool follow_child = (follow_fork_mode_string == follow_fork_mode_child); bool should_resume = true; @@ -996,6 +1010,8 @@ proceed_after_vfork_done (thread_info *thread) static void handle_vfork_child_exec_or_exit (int exec) { + INFRUN_SCOPED_DEBUG_ENTER_EXIT; + struct inferior *inf = current_inferior (); if (inf->vfork_parent) @@ -1127,6 +1143,8 @@ handle_vfork_child_exec_or_exit (int exec) static void handle_vfork_done (thread_info *event_thread) { + INFRUN_SCOPED_DEBUG_ENTER_EXIT; + /* We only care about this event if inferior::thread_waiting_for_vfork_done is set, that is if we are waiting for a vfork child not under our control (because we detached it) to exec or exit. @@ -1142,8 +1160,6 @@ handle_vfork_done (thread_info *event_thread) return; } - INFRUN_SCOPED_DEBUG_ENTER_EXIT; - /* We stopped all threads (other than the vforking thread) of the inferior in follow_fork and kept them stopped until now. It should therefore not be possible for another thread to have reported a vfork during that window. @@ -3407,6 +3423,8 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal) thread_info *cur_thr = inferior_thread (); + infrun_debug_printf ("cur_thr = %s", cur_thr->ptid.to_string ().c_str ()); + /* Fill in with reasonable starting values. */ init_thread_stepping_state (cur_thr); @@ -3463,8 +3481,10 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal) if (!cur_thr->control.in_infcall) set_running (resume_target, resume_ptid, true); - infrun_debug_printf ("addr=%s, signal=%s", paddress (gdbarch, addr), - gdb_signal_to_symbol_string (siggnal)); + infrun_debug_printf ("addr=%s, signal=%s, resume_ptid=%s", + paddress (gdbarch, addr), + gdb_signal_to_symbol_string (siggnal), + resume_ptid.to_string ().c_str ()); annotate_starting (); diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c index 7e121b7ab41..87152621dd6 100644 --- a/gdb/linux-nat.c +++ b/gdb/linux-nat.c @@ -1293,6 +1293,11 @@ get_detach_signal (struct lwp_info *lp) static void detach_one_lwp (struct lwp_info *lp, int *signo_p) { + LINUX_NAT_SCOPED_DEBUG_ENTER_EXIT; + + linux_nat_debug_printf ("lwp %s (stopped = %d)", + lp->ptid.to_string ().c_str (), lp->stopped); + int lwpid = lp->ptid.lwp (); int signo; @@ -1363,6 +1368,10 @@ detach_one_lwp (struct lwp_info *lp, int *signo_p) else signo = *signo_p; + linux_nat_debug_printf ("preparing to resume lwp %s (stopped = %d)", + lp->ptid.to_string ().c_str (), + lp->stopped); + /* Preparing to resume may try to write registers, and fail if the lwp is zombie. If that happens, ignore the error. We'll handle it below, when detach fails with ESRCH. */ @@ -1395,6 +1404,8 @@ detach_callback (struct lwp_info *lp) void linux_nat_target::detach (inferior *inf, int from_tty) { + LINUX_NAT_SCOPED_DEBUG_ENTER_EXIT; + struct lwp_info *main_lwp; int pid = inf->pid; @@ -3122,13 +3133,13 @@ static ptid_t linux_nat_wait_1 (ptid_t ptid, struct target_waitstatus *ourstatus, target_wait_flags target_options) { + LINUX_NAT_SCOPED_DEBUG_ENTER_EXIT; + sigset_t prev_mask; enum resume_kind last_resume_kind; struct lwp_info *lp; int status; - linux_nat_debug_printf ("enter"); - /* The first time we get here after starting a new inferior, we may not have added it to the LWP list yet - this is the earliest moment at which we know its PID. */ @@ -3228,7 +3239,7 @@ linux_nat_wait_1 (ptid_t ptid, struct target_waitstatus *ourstatus, if (target_options & TARGET_WNOHANG) { - linux_nat_debug_printf ("exit (ignore)"); + linux_nat_debug_printf ("no interesting events found"); ourstatus->set_ignore (); restore_child_signals_mask (&prev_mask); @@ -3314,7 +3325,7 @@ linux_nat_wait_1 (ptid_t ptid, struct target_waitstatus *ourstatus, else *ourstatus = host_status_to_waitstatus (status); - linux_nat_debug_printf ("exit"); + linux_nat_debug_printf ("event found"); restore_child_signals_mask (&prev_mask); @@ -3410,6 +3421,8 @@ ptid_t linux_nat_target::wait (ptid_t ptid, struct target_waitstatus *ourstatus, target_wait_flags target_options) { + LINUX_NAT_SCOPED_DEBUG_ENTER_EXIT; + ptid_t event_ptid; linux_nat_debug_printf ("[%s], [%s]", ptid.to_string ().c_str (), @@ -3589,6 +3602,8 @@ linux_nat_target::kill () void linux_nat_target::mourn_inferior () { + LINUX_NAT_SCOPED_DEBUG_ENTER_EXIT; + int pid = inferior_ptid.pid (); purge_lwp_list (pid);