Kill SINGLE_PTRACE and use SINGLE_SUSPEND which has almost the same semantic
authormpi <mpi@openbsd.org>
Fri, 12 Mar 2021 10:13:28 +0000 (10:13 +0000)
committermpi <mpi@openbsd.org>
Fri, 12 Mar 2021 10:13:28 +0000 (10:13 +0000)
single_thread_set() is modified to explicitly indicated when waiting until
sibling threads are parked is required.  This is obviously not required if
a traced thread is switching away from a CPU after handling a STOP signal.

ok claudio@

sys/kern/kern_exec.c
sys/kern/kern_exit.c
sys/kern/kern_sig.c
sys/sys/proc.h

index 81a5b2c..1a69380 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: kern_exec.c,v 1.221 2021/03/08 18:09:15 claudio Exp $ */
+/*     $OpenBSD: kern_exec.c,v 1.222 2021/03/12 10:13:28 mpi Exp $     */
 /*     $NetBSD: kern_exec.c,v 1.75 1996/02/09 18:59:28 christos Exp $  */
 
 /*-
@@ -432,7 +432,7 @@ sys_execve(struct proc *p, void *v, register_t *retval)
         * we're committed: any further errors will kill the process, so
         * kill the other threads now.
         */
-       single_thread_set(p, SINGLE_EXIT, 0);
+       single_thread_set(p, SINGLE_EXIT, 1);
 
        /*
         * Prepare vmspace for remapping. Note that uvmspace_exec can replace
index 8898286..0c6ceb3 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: kern_exit.c,v 1.198 2021/03/08 18:09:15 claudio Exp $ */
+/*     $OpenBSD: kern_exit.c,v 1.199 2021/03/12 10:13:28 mpi Exp $     */
 /*     $NetBSD: kern_exit.c,v 1.39 1996/04/22 01:38:25 christos Exp $  */
 
 /*
@@ -136,7 +136,7 @@ exit1(struct proc *p, int xexit, int xsig, int flags)
        } else {
                /* nope, multi-threaded */
                if (flags == EXIT_NORMAL)
-                       single_thread_set(p, SINGLE_EXIT, 0);
+                       single_thread_set(p, SINGLE_EXIT, 1);
                else if (flags == EXIT_THREAD)
                        single_thread_check(p, 0);
        }
index 0550839..2e1b7b8 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: kern_sig.c,v 1.277 2021/03/08 18:09:15 claudio Exp $  */
+/*     $OpenBSD: kern_sig.c,v 1.278 2021/03/12 10:13:28 mpi Exp $      */
 /*     $NetBSD: kern_sig.c,v 1.54 1996/04/22 01:38:32 christos Exp $   */
 
 /*
@@ -1219,7 +1219,7 @@ cursig(struct proc *p)
                    signum != SIGKILL) {
                        pr->ps_xsig = signum;
 
-                       single_thread_set(p, SINGLE_PTRACE, 0);
+                       single_thread_set(p, SINGLE_SUSPEND, 0);
 
                        if (dolock)
                                SCHED_LOCK(s);
@@ -1488,7 +1488,7 @@ sigexit(struct proc *p, int signum)
 
                /* if there are other threads, pause them */
                if (P_HASSIBLING(p))
-                       single_thread_set(p, SINGLE_SUSPEND, 0);
+                       single_thread_set(p, SINGLE_SUSPEND, 1);
 
                if (coredump(p) == 0)
                        signum |= WCOREFLAG;
@@ -1998,14 +1998,12 @@ single_thread_check(struct proc *p, int deep)
  * where the other threads should stop:
  *  - SINGLE_SUSPEND: stop wherever they are, will later either be told to exit
  *    (by setting to SINGLE_EXIT) or be released (via single_thread_clear())
- *  - SINGLE_PTRACE: stop wherever they are, will wait for them to stop
- *    later (via single_thread_wait()) and released as with SINGLE_SUSPEND
  *  - SINGLE_UNWIND: just unwind to kernel boundary, will be told to exit
  *    or released as with SINGLE_SUSPEND
  *  - SINGLE_EXIT: unwind to kernel boundary and exit
  */
 int
-single_thread_set(struct proc *p, enum single_thread_mode mode, int deep)
+single_thread_set(struct proc *p, enum single_thread_mode mode, int wait)
 {
        struct process *pr = p->p_p;
        struct proc *q;
@@ -2014,7 +2012,7 @@ single_thread_set(struct proc *p, enum single_thread_mode mode, int deep)
        KASSERT(curproc == p);
 
        SCHED_LOCK(s);
-       error = single_thread_check_locked(p, deep, s);
+       error = single_thread_check_locked(p, (mode == SINGLE_UNWIND), s);
        if (error) {
                SCHED_UNLOCK(s);
                return error;
@@ -2022,7 +2020,6 @@ single_thread_set(struct proc *p, enum single_thread_mode mode, int deep)
 
        switch (mode) {
        case SINGLE_SUSPEND:
-       case SINGLE_PTRACE:
                break;
        case SINGLE_UNWIND:
                atomic_setbits_int(&pr->ps_flags, PS_SINGLEUNWIND);
@@ -2061,8 +2058,7 @@ single_thread_set(struct proc *p, enum single_thread_mode mode, int deep)
                        /* if it's not interruptible, then just have to wait */
                        if (q->p_flag & P_SINTR) {
                                /* merely need to suspend?  just stop it */
-                               if (mode == SINGLE_SUSPEND ||
-                                   mode == SINGLE_PTRACE) {
+                               if (mode == SINGLE_SUSPEND) {
                                        q->p_stat = SSTOP;
                                        break;
                                }
@@ -2087,7 +2083,7 @@ single_thread_set(struct proc *p, enum single_thread_mode mode, int deep)
        }
        SCHED_UNLOCK(s);
 
-       if (mode != SINGLE_PTRACE)
+       if (wait)
                single_thread_wait(pr, 1);
 
        return 0;
index 462af50..a050762 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: proc.h,v 1.309 2021/02/15 09:35:59 mpi Exp $  */
+/*     $OpenBSD: proc.h,v 1.310 2021/03/12 10:13:28 mpi Exp $  */
 /*     $NetBSD: proc.h,v 1.44 1996/04/22 01:23:21 christos Exp $       */
 
 /*-
@@ -600,7 +600,6 @@ refreshcreds(struct proc *p)
 
 enum single_thread_mode {
        SINGLE_SUSPEND,         /* other threads to stop wherever they are */
-       SINGLE_PTRACE,          /* other threads to stop but don't wait */
        SINGLE_UNWIND,          /* other threads to unwind and stop */
        SINGLE_EXIT             /* other threads to unwind and then exit */
 };