diff options
author | Martin Pieuchot <mpi@cvs.openbsd.org> | 2021-05-10 18:01:25 +0000 |
---|---|---|
committer | Martin Pieuchot <mpi@cvs.openbsd.org> | 2021-05-10 18:01:25 +0000 |
commit | 405b3d4402434a7427ba0135b9c95946ca569c46 (patch) | |
tree | d676eef9d381a9baaeb79c4da2396c42cec5f585 /sys/kern/kern_sig.c | |
parent | ecd435a29eda5ed9bfcd92a16445e2db601bc0c4 (diff) |
Revert previous, it introduced a regression with breakpoints in gdb.
Diffstat (limited to 'sys/kern/kern_sig.c')
-rw-r--r-- | sys/kern/kern_sig.c | 80 |
1 files changed, 34 insertions, 46 deletions
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index f92de3126f9..80952582fb5 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_sig.c,v 1.280 2021/05/06 09:33:22 mpi Exp $ */ +/* $OpenBSD: kern_sig.c,v 1.281 2021/05/10 18:01:24 mpi Exp $ */ /* $NetBSD: kern_sig.c,v 1.54 1996/04/22 01:38:32 christos Exp $ */ /* @@ -124,7 +124,7 @@ const int sigprop[NSIG + 1] = { void setsigvec(struct proc *, int, struct sigaction *); -int proc_stop(struct proc *p, int, int); +void proc_stop(struct proc *p, int); void proc_stop_sweep(void *); void *proc_stop_si; @@ -1061,7 +1061,8 @@ ptsignal(struct proc *p, int signum, enum signal_type type) if (pr->ps_flags & PS_PPWAIT) goto out; atomic_clearbits_int(siglist, mask); - proc_stop(p, signum, 0); + pr->ps_xsig = signum; + proc_stop(p, 0); goto out; } /* @@ -1169,12 +1170,17 @@ out: * * while (signum = cursig(curproc)) * postsig(signum); + * + * Assumes that if the P_SINTR flag is set, we're holding both the + * kernel and scheduler locks. */ int cursig(struct proc *p) { struct process *pr = p->p_p; int sigpending, signum, mask, prop; + int dolock = (p->p_flag & P_SINTR) == 0; + int s; KERNEL_ASSERT_LOCKED(); @@ -1211,22 +1217,31 @@ cursig(struct proc *p) */ if (((pr->ps_flags & (PS_TRACED | PS_PPWAIT)) == PS_TRACED) && signum != SIGKILL) { + pr->ps_xsig = signum; single_thread_set(p, SINGLE_SUSPEND, 0); - signum = proc_stop(p, signum, 1); + + if (dolock) + SCHED_LOCK(s); + proc_stop(p, 1); + if (dolock) + SCHED_UNLOCK(s); + single_thread_clear(p, 0); /* * If we are no longer being traced, or the parent * didn't give us a signal, look for more signals. */ - if ((pr->ps_flags & PS_TRACED) == 0 || signum == 0) + if ((pr->ps_flags & PS_TRACED) == 0 || + pr->ps_xsig == 0) continue; /* * If the new signal is being masked, look for other * signals. */ + signum = pr->ps_xsig; mask = sigmask(signum); if ((p->p_sigmask & mask) != 0) continue; @@ -1271,7 +1286,12 @@ cursig(struct proc *p) (pr->ps_pgrp->pg_jobc == 0 && prop & SA_TTYSTOP)) break; /* == ignore */ - proc_stop(p, signum, 1); + pr->ps_xsig = signum; + if (dolock) + SCHED_LOCK(s); + proc_stop(p, 1); + if (dolock) + SCHED_UNLOCK(s); break; } else if (prop & SA_IGNORE) { /* @@ -1311,21 +1331,15 @@ keep: * Put the argument process into the stopped state and notify the parent * via wakeup. Signals are handled elsewhere. The process must not be * on the run queue. - * - * Assumes that if the P_SINTR flag is set, we're holding the scheduler - * lock. */ -int -proc_stop(struct proc *p, int signum, int sw) +void +proc_stop(struct proc *p, int sw) { struct process *pr = p->p_p; - int dolock = (p->p_flag & P_SINTR) == 0; - int s; - - pr->ps_xsig = signum; - if (dolock) - SCHED_LOCK(s); +#ifdef MULTIPROCESSOR + SCHED_ASSERT_LOCKED(); +#endif p->p_stat = SSTOP; atomic_clearbits_int(&pr->ps_flags, PS_WAITED); @@ -1338,11 +1352,6 @@ proc_stop(struct proc *p, int signum, int sw) softintr_schedule(proc_stop_si); if (sw) mi_switch(); - - if (dolock) - SCHED_UNLOCK(s); - - return pr->ps_xsig; } /* @@ -1367,27 +1376,6 @@ proc_stop_sweep(void *v) } } -void -proc_unstop(struct proc *p, int signum) -{ - struct process *pr = p->p_p; - - KASSERT(signum >= 0); - KASSERT(p->p_stat == SSTOP); - - if (signum != 0) - pr->ps_xsig = signum; - - /* - * 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)); - - setrunnable(p); -} - /* * Take the action for the specified signal * from the current set of pending signals. @@ -2054,7 +2042,7 @@ single_thread_set(struct proc *p, enum single_thread_mode mode, int wait) if (q->p_flag & P_WEXIT) { if (mode == SINGLE_EXIT) { if (q->p_stat == SSTOP) { - proc_unstop(q, 0); + setrunnable(q); atomic_inc_int(&pr->ps_singlecount); } } @@ -2081,7 +2069,7 @@ single_thread_set(struct proc *p, enum single_thread_mode mode, int wait) break; case SSTOP: if (mode == SINGLE_EXIT) { - proc_unstop(q, 0); + setrunnable(q); atomic_inc_int(&pr->ps_singlecount); } break; @@ -2150,7 +2138,7 @@ single_thread_clear(struct proc *p, int flag) */ if (q->p_stat == SSTOP && (q->p_flag & flag) == 0) { if (q->p_wchan == 0) - proc_unstop(q, 0); + setrunnable(q); else q->p_stat = SSLEEP; } |