From owner-svn-src-all@freebsd.org Tue Dec 6 04:22:40 2016 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 2172CC699C5; Tue, 6 Dec 2016 04:22:40 +0000 (UTC) (envelope-from markj@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id D661F8F4; Tue, 6 Dec 2016 04:22:39 +0000 (UTC) (envelope-from markj@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id uB64Mdjk067720; Tue, 6 Dec 2016 04:22:39 GMT (envelope-from markj@FreeBSD.org) Received: (from markj@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id uB64McT8067715; Tue, 6 Dec 2016 04:22:38 GMT (envelope-from markj@FreeBSD.org) Message-Id: <201612060422.uB64McT8067715@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: markj set sender to markj@FreeBSD.org using -f From: Mark Johnston Date: Tue, 6 Dec 2016 04:22:38 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r309597 - in head: cddl/compat/opensolaris/include cddl/lib/libdtrace lib/libproc X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 06 Dec 2016 04:22:40 -0000 Author: markj Date: Tue Dec 6 04:22:38 2016 New Revision: 309597 URL: https://svnweb.freebsd.org/changeset/base/309597 Log: libproc: Add support for some proc_attach() flags. This change adds some handling for the equivalent of Solaris' PGRAB_* flags. In particular, support for PGRAB_RDONLY is needed to avoid a nasty deadlock: dtrace(1) may otherwise stop the master process for its pseudo-terminal and end up blocking while writing to standard output. Modified: head/cddl/compat/opensolaris/include/libproc.h head/cddl/lib/libdtrace/libproc_compat.h head/lib/libproc/libproc.h head/lib/libproc/proc_create.c head/lib/libproc/proc_util.c Modified: head/cddl/compat/opensolaris/include/libproc.h ============================================================================== --- head/cddl/compat/opensolaris/include/libproc.h Tue Dec 6 04:21:35 2016 (r309596) +++ head/cddl/compat/opensolaris/include/libproc.h Tue Dec 6 04:22:38 2016 (r309597) @@ -38,9 +38,6 @@ #define PR_RLC 0x0001 #define PR_KLC 0x0002 -#define PGRAB_RDONLY O_RDONLY -#define PGRAB_FORCE 0 - #include_next #endif Modified: head/cddl/lib/libdtrace/libproc_compat.h ============================================================================== --- head/cddl/lib/libdtrace/libproc_compat.h Tue Dec 6 04:21:35 2016 (r309596) +++ head/cddl/lib/libdtrace/libproc_compat.h Tue Dec 6 04:22:38 2016 (r309597) @@ -34,6 +34,9 @@ * Functions sorted alphabetically. */ #define PR_LMID_EVERY 0 +#define PGRAB_RDONLY PATTACH_RDONLY +#define PGRAB_FORCE PATTACH_FORCE + #define Psetrun(p, a1, a2) proc_continue((p)) #define Pxlookup_by_addr(p, a, n, s, sym, i) \ proc_addr2sym(p, a, n, s, sym) Modified: head/lib/libproc/libproc.h ============================================================================== --- head/lib/libproc/libproc.h Tue Dec 6 04:21:35 2016 (r309596) +++ head/lib/libproc/libproc.h Tue Dec 6 04:22:38 2016 (r309597) @@ -50,6 +50,11 @@ typedef void (*proc_child_func)(void *); #define PS_DEAD 5 #define PS_LOST 6 +/* Flags for proc_attach(). */ +#define PATTACH_FORCE 0x01 +#define PATTACH_RDONLY 0x02 +#define PATTACH_NOSTOP 0x04 + /* Reason values for proc_detach(). */ #define PRELEASE_HANG 1 #define PRELEASE_KILL 2 Modified: head/lib/libproc/proc_create.c ============================================================================== --- head/lib/libproc/proc_create.c Tue Dec 6 04:21:35 2016 (r309596) +++ head/lib/libproc/proc_create.c Tue Dec 6 04:22:38 2016 (r309597) @@ -127,7 +127,7 @@ proc_attach(pid_t pid, int flags, struct struct proc_handle *phdl; int error, status; - if (pid == 0 || pid == getpid()) + if (pid == 0 || (pid == getpid() && (flags & PATTACH_RDONLY) == 0)) return (EINVAL); if (elf_version(EV_CURRENT) == EV_NONE) return (ENOENT); @@ -140,27 +140,32 @@ proc_attach(pid_t pid, int flags, struct if (error != 0) goto out; - if (ptrace(PT_ATTACH, proc_getpid(phdl), 0, 0) != 0) { - error = errno; - DPRINTF("ERROR: cannot ptrace child process %d", pid); - goto out; - } + if ((flags & PATTACH_RDONLY) == 0) { + if (ptrace(PT_ATTACH, proc_getpid(phdl), 0, 0) != 0) { + error = errno; + DPRINTF("ERROR: cannot ptrace child process %d", pid); + goto out; + } - /* Wait for the child process to stop. */ - if (waitpid(pid, &status, WUNTRACED) == -1) { - error = errno; - DPRINTF("ERROR: child process %d didn't stop as expected", pid); - goto out; - } + /* Wait for the child process to stop. */ + if (waitpid(pid, &status, WUNTRACED) == -1) { + error = errno; + DPRINTF("ERROR: child process %d didn't stop as expected", pid); + goto out; + } - /* Check for an unexpected status. */ - if (!WIFSTOPPED(status)) - DPRINTFX("ERROR: child process %d status 0x%x", pid, status); - else - phdl->status = PS_STOP; + /* Check for an unexpected status. */ + if (!WIFSTOPPED(status)) + DPRINTFX("ERROR: child process %d status 0x%x", pid, status); + else + phdl->status = PS_STOP; + + if ((flags & PATTACH_NOSTOP) != 0) + proc_continue(phdl); + } out: - if (error && phdl != NULL) { + if (error != 0 && phdl != NULL) { proc_free(phdl); phdl = NULL; } Modified: head/lib/libproc/proc_util.c ============================================================================== --- head/lib/libproc/proc_util.c Tue Dec 6 04:21:35 2016 (r309596) +++ head/lib/libproc/proc_util.c Tue Dec 6 04:22:38 2016 (r309597) @@ -87,21 +87,25 @@ proc_detach(struct proc_handle *phdl, in if (phdl == NULL) return (EINVAL); + if (reason == PRELEASE_HANG) + return (EINVAL); if (reason == PRELEASE_KILL) { kill(proc_getpid(phdl), SIGKILL); - return (0); + goto free; } + if ((phdl->flags & PATTACH_RDONLY) != 0) + goto free; pid = proc_getpid(phdl); if (ptrace(PT_DETACH, pid, 0, 0) != 0 && errno == ESRCH) - return (0); + goto free; if (errno == EBUSY) { kill(pid, SIGSTOP); waitpid(pid, &status, WUNTRACED); ptrace(PT_DETACH, pid, 0, 0); kill(pid, SIGCONT); - return (0); } - +free: + proc_free(phdl); return (0); }