Indicate that a process has stopped by setting PS_STOPPED flag
authorclaudio <claudio@openbsd.org>
Tue, 15 Oct 2024 13:49:26 +0000 (13:49 +0000)
committerclaudio <claudio@openbsd.org>
Tue, 15 Oct 2024 13:49:26 +0000 (13:49 +0000)
The checks in dowait6 and orphanpg using ps_mainproc are flawed and
fail if the mainproc called pthread_exit before the other threads.
Adding the flag in proc_stop_sweep is racy but the best we have right now.
This fixes regress/sys/kern/signal/sig-stop3.

OK mpi@

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

index 5dee520..d5dd1f3 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: kern_exit.c,v 1.238 2024/10/15 11:54:07 claudio Exp $ */
+/*     $OpenBSD: kern_exit.c,v 1.239 2024/10/15 13:49:26 claudio Exp $ */
 /*     $NetBSD: kern_exit.c,v 1.39 1996/04/22 01:38:25 christos Exp $  */
 
 /*
@@ -502,7 +502,6 @@ dowait6(struct proc *q, idtype_t idtype, id_t id, int *statusp, int options,
 {
        int nfound;
        struct process *pr;
-       struct proc *p;
        int error;
 
        if (info != NULL)
@@ -516,8 +515,6 @@ loop:
                    (idtype == P_PGID && id != pr->ps_pgid))
                        continue;
 
-               p = pr->ps_mainproc;
-
                nfound++;
                if ((options & WEXITED) && (pr->ps_flags & PS_ZOMBIE)) {
                        *retval = pr->ps_pid;
@@ -571,11 +568,9 @@ loop:
                                memset(rusage, 0, sizeof(*rusage));
                        return (0);
                }
-               if (p->p_stat == SSTOP &&
+               if (((pr->ps_flags & PS_TRACED) || (options & WUNTRACED)) &&
                    (pr->ps_flags & PS_WAITED) == 0 &&
-                   (p->p_flag & P_SUSPSINGLE) == 0 &&
-                   ((pr->ps_flags & PS_TRACED) ||
-                   (options & WUNTRACED))) {
+                   (pr->ps_flags & PS_STOPPED)) {
                        if ((options & WNOWAIT) == 0)
                                atomic_setbits_int(&pr->ps_flags, PS_WAITED);
 
index d7179d0..f061b06 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: kern_proc.c,v 1.99 2024/07/08 13:17:12 claudio Exp $  */
+/*     $OpenBSD: kern_proc.c,v 1.100 2024/10/15 13:49:26 claudio Exp $ */
 /*     $NetBSD: kern_proc.c,v 1.14 1996/02/09 18:59:41 christos Exp $  */
 
 /*
@@ -462,7 +462,7 @@ orphanpg(struct pgrp *pg)
        struct process *pr;
 
        LIST_FOREACH(pr, &pg->pg_members, ps_pglist) {
-               if (pr->ps_mainproc->p_stat == SSTOP) {
+               if (pr->ps_flags & PS_STOPPED) {
                        LIST_FOREACH(pr, &pg->pg_members, ps_pglist) {
                                prsignal(pr, SIGHUP);
                                prsignal(pr, SIGCONT);
index db6bf45..c057609 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: kern_sig.c,v 1.341 2024/10/09 08:58:19 claudio Exp $  */
+/*     $OpenBSD: kern_sig.c,v 1.342 2024/10/15 13:49:26 claudio Exp $  */
 /*     $NetBSD: kern_sig.c,v 1.54 1996/04/22 01:38:32 christos Exp $   */
 
 /*
@@ -1100,6 +1100,8 @@ ptsignal(struct proc *p, int signum, enum signal_type type)
                         * Otherwise, process goes back to sleep state.
                         */
                        atomic_setbits_int(&pr->ps_flags, PS_CONTINUED);
+                       atomic_clearbits_int(&pr->ps_flags,
+                           PS_WAITED | PS_STOPPED);
                        atomic_clearbits_int(&p->p_flag, P_SUSPSIG);
                        wakeparent = 1;
                        if (action == SIG_DFL)
@@ -1512,6 +1514,7 @@ proc_stop_sweep(void *v)
        LIST_FOREACH(pr, &allprocess, ps_list) {
                if ((pr->ps_flags & PS_STOPPING) == 0)
                        continue;
+               atomic_setbits_int(&pr->ps_flags, PS_STOPPED);
                atomic_clearbits_int(&pr->ps_flags, PS_STOPPING);
 
                if ((pr->ps_pptr->ps_sigacts->ps_sigflags & SAS_NOCLDSTOP) == 0)
index 0a6fee0..4667ddb 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: proc.h,v 1.374 2024/10/08 12:02:24 claudio Exp $      */
+/*     $OpenBSD: proc.h,v 1.375 2024/10/15 13:49:26 claudio Exp $      */
 /*     $NetBSD: proc.h,v 1.44 1996/04/22 01:23:21 christos Exp $       */
 
 /*-
@@ -304,15 +304,16 @@ struct process {
 #define        PS_NOBTCFI      0x02000000      /* No Branch Target CFI */
 #define        PS_ITIMER       0x04000000      /* Virtual interval timers running */
 #define        PS_CONTINUED    0x20000000      /* Continued proc not yet waited for */
+#define        PS_STOPPED      0x40000000      /* Stopped process */
 
 #define        PS_BITS \
     ("\20" "\01CONTROLT" "\02EXEC" "\03INEXEC" "\04EXITING" "\05SUGID" \
      "\06SUGIDEXEC" "\07PPWAIT" "\010ISPWAIT" "\011PROFIL" "\012TRACED" \
      "\013WAITED" "\014COREDUMP" "\015SINGLEEXIT" "\016SINGLEUNWIND" \
-     "\017NOZOMBIE" "\020STOPPED" "\021SYSTEM" "\022EMBRYO" "\023ZOMBIE" \
+     "\017NOZOMBIE" "\020STOPPING" "\021SYSTEM" "\022EMBRYO" "\023ZOMBIE" \
      "\024NOBROADCASTKILL" "\025PLEDGE" "\026WXNEEDED" "\027EXECPLEDGE" \
-     "\030ORPHAN" "\031CHROOT" "\032NOBTCFI" "\033ITIMER" "\034PIN" \
-     "\035LIBCPIN" "\036CONTINUED")
+     "\030ORPHAN" "\031CHROOT" "\032NOBTCFI" "\033ITIMER" "\036CONTINUED" \
+     "\037STOPPED")
 
 struct kcov_dev;
 struct lock_list_entry;