Clear ps_xsig when continuing after a PS_TRACED stop.
authorclaudio <claudio@openbsd.org>
Wed, 9 Oct 2024 08:58:19 +0000 (08:58 +0000)
committerclaudio <claudio@openbsd.org>
Wed, 9 Oct 2024 08:58:19 +0000 (08:58 +0000)
Also remove the ps_xsig handling in setrunnable() it is in the wrong spot
and causes signals to be delivered over and over again.

Attaching to an already stopped process is affected by this. The SIGSTOP
sent by ptrace is now ignored in ptsignal() and as a result gdb will hang
in wait4() until a SIGCONT is delivered to the process. After that all
works as usual.

OK mpi@

sys/kern/kern_sig.c
sys/kern/sched_bsd.c

index ae226ed..db6bf45 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: kern_sig.c,v 1.340 2024/10/09 08:39:49 claudio Exp $  */
+/*     $OpenBSD: kern_sig.c,v 1.341 2024/10/09 08:58:19 claudio Exp $  */
 /*     $NetBSD: kern_sig.c,v 1.54 1996/04/22 01:38:32 christos Exp $   */
 
 /*
@@ -840,6 +840,7 @@ trapsignal(struct proc *p, int signum, u_long trapno, int code,
                        SCHED_UNLOCK();
 
                        signum = pr->ps_xsig;
+                       pr->ps_xsig = 0;
                        if ((p->p_flag & P_TRACESINGLE) == 0)
                                single_thread_clear(p, 0);
                        atomic_clearbits_int(&p->p_flag, P_TRACESINGLE);
@@ -1362,6 +1363,7 @@ cursig(struct proc *p, struct sigctx *sctx)
                         * those are not true.
                         */
                        signum = pr->ps_xsig;
+                       pr->ps_xsig = 0;
                        mask = sigmask(signum);
                        setsigctx(p, signum, sctx);
                        if (!((pr->ps_flags & PS_TRACED) == 0 ||
index 21c1ee8..4d3daa5 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: sched_bsd.c,v 1.95 2024/10/08 11:57:59 claudio Exp $  */
+/*     $OpenBSD: sched_bsd.c,v 1.96 2024/10/09 08:58:19 claudio Exp $  */
 /*     $NetBSD: kern_synch.c,v 1.37 1996/04/22 01:38:37 christos Exp $ */
 
 /*-
@@ -464,12 +464,6 @@ setrunnable(struct proc *p)
        default:
                panic("setrunnable");
        case SSTOP:
-               /*
-                * If we're being traced (possibly because someone attached us
-                * while we were stopped), check for a signal from the debugger.
-                */
-               if ((pr->ps_flags & PS_TRACED) != 0 && pr->ps_xsig != 0)
-                       atomic_setbits_int(&p->p_siglist, sigmask(pr->ps_xsig));
                prio = p->p_usrpri;
                setrunqueue(NULL, p, prio);
                break;