From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 29886 invoked by alias); 18 Jul 2016 14:58:56 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 29816 invoked by uid 89); 18 Jul 2016 14:58:56 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.5 required=5.0 tests=AWL,BAYES_00,SPF_HELO_PASS,SPF_SOFTFAIL autolearn=no version=3.3.2 spammy=fork X-HELO: bigwig.baldwin.cx Received: from bigwig.baldwin.cx (HELO bigwig.baldwin.cx) (96.47.65.170) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (CAMELLIA256-SHA encrypted) ESMTPS; Mon, 18 Jul 2016 14:58:43 +0000 Received: from ralph.com (c-73-231-226-104.hsd1.ca.comcast.net [73.231.226.104]) by bigwig.baldwin.cx (Postfix) with ESMTPSA id 8E8FAB9A8 for ; Mon, 18 Jul 2016 10:58:41 -0400 (EDT) From: John Baldwin To: gdb-patches@sourceware.org Subject: [PATCH 3/3] Use a real vfork done event on FreeBSD when available. Date: Mon, 18 Jul 2016 14:58:00 -0000 Message-Id: <20160718145759.58543-4-jhb@FreeBSD.org> In-Reply-To: <20160718145759.58543-1-jhb@FreeBSD.org> References: <20160718145759.58543-1-jhb@FreeBSD.org> X-IsSubscribed: yes X-SW-Source: 2016-07/txt/msg00190.txt.bz2 FreeBSD 12 recently added a new ptrace event to indicate when the vfork parent resumes after the child process stops sharing the address space. Use this event to report a proper TARGET_WAITKIND_VFORK_DONE rather than faking a vfork done event after a delay. gdb/ChangeLog: * fbsd-nat.c (fbsd_enable_proc_events): Enable "PTRACE_VFORK" events. (fbsd_pending_vfork_done): Only define if "PTRACE_VFORK" is not defined. (fbsd_add_vfork_done): Likewise. (fbsd_is_vfork_done_pending): Likewise. (fbsd_next_vfork_done): Likewise. (fbsd_resume): Only ignore pending vfork done events if "PTRACE_VFORK" is not defined. (fbsd_wait): Only look for pending vfork done events if "PTRACE_VFORK" is not defined. [PTRACE_VFORK]: Handle "PL_FLAG_VFORKED" and "PL_FLAG_VFORK_DONE" events. (fbsd_follow_fork): Only fake a vfork done event if "PTRACE_VFORK" is not defined. --- gdb/ChangeLog | 18 ++++++++++++++++++ gdb/fbsd-nat.c | 30 +++++++++++++++++++++++++++--- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 33cd6a7..f11871c 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,23 @@ 2016-07-15 John Baldwin + * fbsd-nat.c (fbsd_enable_proc_events): Enable "PTRACE_VFORK" + events. + (fbsd_pending_vfork_done): Only define if "PTRACE_VFORK" is not + defined. + (fbsd_add_vfork_done): Likewise. + (fbsd_is_vfork_done_pending): Likewise. + (fbsd_next_vfork_done): Likewise. + (fbsd_resume): Only ignore pending vfork done events if + "PTRACE_VFORK" is not defined. + (fbsd_wait): Only look for pending vfork done events if + "PTRACE_VFORK" is not defined. + [PTRACE_VFORK]: Handle "PL_FLAG_VFORKED" and "PL_FLAG_VFORK_DONE" + events. + (fbsd_follow_fork): Only fake a vfork done event if "PTRACE_VFORK" + is not defined. + +2016-07-15 John Baldwin + * fbsd-nat.c (fbsd_wait): Use "fbsd_enable_proc_events" on new child processes. diff --git a/gdb/fbsd-nat.c b/gdb/fbsd-nat.c index 5e4304e..ade62f1 100644 --- a/gdb/fbsd-nat.c +++ b/gdb/fbsd-nat.c @@ -435,6 +435,9 @@ fbsd_enable_proc_events (pid_t pid) sizeof (events)) == -1) perror_with_name (("ptrace")); events |= PTRACE_FORK | PTRACE_LWP; +#ifdef PTRACE_VFORK + events |= PTRACE_VFORK; +#endif if (ptrace (PT_SET_EVENT_MASK, pid, (PTRACE_TYPE_ARG3)&events, sizeof (events)) == -1) perror_with_name (("ptrace")); @@ -598,6 +601,7 @@ fbsd_is_child_pending (pid_t pid) return null_ptid; } +#ifndef PTRACE_VFORK static struct fbsd_fork_info *fbsd_pending_vfork_done; /* Record a pending vfork done event. */ @@ -647,6 +651,7 @@ fbsd_next_vfork_done (void) return null_ptid; } #endif +#endif static int resume_one_thread_cb (struct thread_info *tp, void *data) @@ -686,7 +691,7 @@ static void fbsd_resume (struct target_ops *ops, ptid_t ptid, int step, enum gdb_signal signo) { -#ifdef TDP_RFPPWAIT +#if defined(TDP_RFPPWAIT) && !defined(PTRACE_VFORK) pid_t pid; /* Don't PT_CONTINUE a process which has a pending vfork done event. */ @@ -731,12 +736,14 @@ fbsd_wait (struct target_ops *ops, while (1) { +#ifndef PTRACE_VFORK wptid = fbsd_next_vfork_done (); if (!ptid_equal (wptid, null_ptid)) { ourstatus->kind = TARGET_WAITKIND_VFORK_DONE; return wptid; } +#endif wptid = super_wait (ops, ptid, ourstatus, target_options); if (ourstatus->kind == TARGET_WAITKIND_STOPPED) { @@ -812,12 +819,18 @@ fbsd_wait (struct target_ops *ops, #ifdef TDP_RFPPWAIT if (pl.pl_flags & PL_FLAG_FORKED) { +#ifndef PTRACE_VFORK struct kinfo_proc kp; +#endif ptid_t child_ptid; pid_t child; child = pl.pl_child_pid; ourstatus->kind = TARGET_WAITKIND_FORKED; +#ifdef PTRACE_VFORK + if (pl.pl_flags & PL_FLAG_VFORKED) + ourstatus->kind = TARGET_WAITKIND_VFORKED; +#endif /* Make sure the other end of the fork is stopped too. */ child_ptid = fbsd_is_child_pending (child); @@ -839,11 +852,13 @@ fbsd_wait (struct target_ops *ops, /* Enable additional events on the child process. */ fbsd_enable_proc_events (ptid_get_pid (child_ptid)); +#ifndef PTRACE_VFORK /* For vfork, the child process will have the P_PPWAIT flag set. */ fbsd_fetch_kinfo_proc (child, &kp); if (kp.ki_flag & P_PPWAIT) ourstatus->kind = TARGET_WAITKIND_VFORKED; +#endif ourstatus->value.related_pid = child_ptid; return wptid; @@ -857,6 +872,14 @@ fbsd_wait (struct target_ops *ops, fbsd_remember_child (wptid); continue; } + +#ifdef PTRACE_VFORK + if (pl.pl_flags & PL_FLAG_VFORK_DONE) + { + ourstatus->kind = TARGET_WAITKIND_VFORK_DONE; + return wptid; + } +#endif #endif #ifdef PL_FLAG_EXEC @@ -918,7 +941,6 @@ fbsd_follow_fork (struct target_ops *ops, int follow_child, if (!follow_child && detach_fork) { struct thread_info *tp = inferior_thread (); - int has_vforked = tp->pending_follow.kind == TARGET_WAITKIND_VFORKED; pid_t child_pid = ptid_get_pid (tp->pending_follow.value.related_pid); /* Breakpoints have already been detached from the child by @@ -927,7 +949,8 @@ fbsd_follow_fork (struct target_ops *ops, int follow_child, if (ptrace (PT_DETACH, child_pid, (PTRACE_TYPE_ARG3)1, 0) == -1) perror_with_name (("ptrace")); - if (has_vforked) +#ifndef PTRACE_VFORK + if (tp->pending_follow.kind == TARGET_WAITKIND_VFORKED) { /* We can't insert breakpoints until the child process has finished with the shared memory region. The parent @@ -953,6 +976,7 @@ fbsd_follow_fork (struct target_ops *ops, int follow_child, wait. */ fbsd_add_vfork_done (inferior_ptid); } +#endif } return 0; -- 2.8.4