svn commit: r309597 - in head: cddl/compat/opensolaris/include cddl/lib/libdtrace lib/libproc

Mark Johnston markj at FreeBSD.org
Tue Dec 6 04:22:40 UTC 2016


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 <libproc.h>
 
 #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);
 }
 


More information about the svn-src-head mailing list