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);
 }
 
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to