From patchwork Tue Feb 28 18:18:45 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Baldwin X-Patchwork-Id: 65805 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 8FCCE384840B for ; Tue, 28 Feb 2023 18:19:50 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mail.baldwin.cx (bigwig.baldwin.cx [IPv6:2607:f138:0:13::2]) by sourceware.org (Postfix) with ESMTPS id AB5A33858C78 for ; Tue, 28 Feb 2023 18:19:03 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org AB5A33858C78 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=FreeBSD.org Authentication-Results: sourceware.org; spf=fail smtp.mailfrom=FreeBSD.org Received: from gimli.baldwin.net (c-98-35-126-114.hsd1.ca.comcast.net [98.35.126.114]) by mail.baldwin.cx (Postfix) with ESMTPSA id DF7921A84E3A for ; Tue, 28 Feb 2023 13:18:59 -0500 (EST) From: John Baldwin To: gdb-patches@sourceware.org Subject: [PATCH 9/9] fbsd-nat: Stop a process if it is running before killing it. Date: Tue, 28 Feb 2023 10:18:45 -0800 Message-Id: <20230228181845.99936-10-jhb@FreeBSD.org> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20230228181845.99936-1-jhb@FreeBSD.org> References: <20230228181845.99936-1-jhb@FreeBSD.org> MIME-Version: 1.0 X-Greylist: Sender succeeded SMTP AUTH, not delayed by milter-greylist-4.6.4 (mail.baldwin.cx [0.0.0.0]); Tue, 28 Feb 2023 13:19:00 -0500 (EST) X-Virus-Scanned: clamav-milter 0.103.1 at mail.baldwin.cx X-Virus-Status: Clean X-Spam-Status: No, score=-11.9 required=5.0 tests=BAYES_00, FORGED_SPF_HELO, GIT_PATCH_0, KAM_DMARC_STATUS, KHOP_HELO_FCRDNS, SPF_HELO_PASS, SPF_SOFTFAIL, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" In addition, detach from any child processes implicitly attached to by the kernel due to fork following that have not yet been processed by GDB's core. --- gdb/fbsd-nat.c | 93 +++++++++++++++++++++++++++++++++++++++++--------- gdb/fbsd-nat.h | 2 ++ 2 files changed, 78 insertions(+), 17 deletions(-) diff --git a/gdb/fbsd-nat.c b/gdb/fbsd-nat.c index 32dd482ec3c..42c69875b0f 100644 --- a/gdb/fbsd-nat.c +++ b/gdb/fbsd-nat.c @@ -1158,6 +1158,31 @@ fbsd_is_child_pending (pid_t pid) return null_ptid; } +/* Wait for a child of a fork to report its stop. Returns the PTID of + the new child process. */ + +static ptid_t +fbsd_wait_for_fork_child (pid_t pid) +{ + ptid_t ptid = fbsd_is_child_pending (pid); + if (ptid != null_ptid) + return ptid; + + int status; + pid_t wpid = waitpid (pid, &status, 0); + if (wpid == -1) + perror_with_name (("waitpid")); + + gdb_assert (wpid == pid); + + struct ptrace_lwpinfo pl; + if (ptrace (PT_LWPINFO, wpid, (caddr_t) &pl, sizeof pl) == -1) + perror_with_name (("ptrace (PT_LWPINFO)")); + + gdb_assert (pl.pl_flags & PL_FLAG_CHILD); + return ptid_t (wpid, pl.pl_lwpid); +} + #ifndef PTRACE_VFORK /* Record a pending vfork done event. */ @@ -1467,23 +1492,7 @@ fbsd_nat_target::wait_1 (ptid_t ptid, struct target_waitstatus *ourstatus, #endif /* Make sure the other end of the fork is stopped too. */ - child_ptid = fbsd_is_child_pending (child); - if (child_ptid == null_ptid) - { - int status; - - pid = waitpid (child, &status, 0); - if (pid == -1) - perror_with_name (("waitpid")); - - gdb_assert (pid == child); - - if (ptrace (PT_LWPINFO, child, (caddr_t) &pl, sizeof pl) == -1) - perror_with_name (("ptrace (PT_LWPINFO)")); - - gdb_assert (pl.pl_flags & PL_FLAG_CHILD); - child_ptid = ptid_t (child, pl.pl_lwpid); - } + child_ptid = fbsd_wait_for_fork_child (child); /* Enable additional events on the child process. */ fbsd_enable_proc_events (child_ptid.pid ()); @@ -2115,6 +2124,56 @@ fbsd_nat_target::detach (inferior *inf, int from_tty) detach_success (inf); } +/* Implement the "kill" target method. */ + +void +fbsd_nat_target::kill () +{ + pid_t pid = inferior_ptid.pid (); + if (pid == 0) + return; + + inferior *inf = current_inferior (); + stop_process (inf); + + if (detach_fork_children (this, inf)) { + /* No need to kill now. */ + target_mourn_inferior (inferior_ptid); + + return; + } + +#ifdef TDP_RFPPWAIT + /* If there are any threads that have forked a new child but not yet + reported it because other threads reported events first, detach + from the children before killing the parent. */ + auto lambda = [] (const struct ptrace_lwpinfo &pl) + { + if (pl.pl_flags & PL_FLAG_FORKED) + { + pid_t child = pl.pl_child_pid; + + /* If the child hasn't reported its stop yet, wait for it to + stop. */ + fbsd_wait_for_fork_child (child); + + /* Detach from the child. */ + (void) ptrace (PT_DETACH, child, (caddr_t) 1, 0); + } + return false; + }; + iterate_other_ptrace_events (pid, gdb::make_function_view (lambda)); +#endif + + if (ptrace (PT_KILL, pid, NULL, 0) == -1) + perror_with_name (("ptrace (PT_KILL)")); + + int status; + waitpid (pid, &status, 0); + + target_mourn_inferior (inferior_ptid); +} + void fbsd_nat_target::mourn_inferior () { diff --git a/gdb/fbsd-nat.h b/gdb/fbsd-nat.h index 3dc22ce1cca..8096c53bc03 100644 --- a/gdb/fbsd-nat.h +++ b/gdb/fbsd-nat.h @@ -80,6 +80,8 @@ class fbsd_nat_target : public inf_ptrace_target void detach (inferior *, int) override; + void kill () override; + void mourn_inferior () override; void resume (ptid_t, int, enum gdb_signal) override;