Index: kern/kern_event.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_event.c,v retrieving revision 1.85 diff -u -u -r1.85 kern_event.c --- kern/kern_event.c 31 Jan 2016 04:40:01 -0000 1.85 +++ kern/kern_event.c 4 Apr 2016 16:50:24 -0000 @@ -551,7 +551,7 @@ struct proc *p = kn->kn_obj; if (p != NULL) - kn->kn_data = p->p_xstat; + kn->kn_data = P_WAITSTATUS(p); /* * Process is gone, so flag the event as finished. * Index: kern/kern_exec.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_exec.c,v retrieving revision 1.424 diff -u -u -r1.424 kern_exec.c --- kern/kern_exec.c 20 Mar 2016 14:58:10 -0000 1.424 +++ kern/kern_exec.c 4 Apr 2016 16:50:24 -0000 @@ -1350,7 +1350,7 @@ /* Acquire the sched-state mutex (exit1() will release it). */ if (!is_spawn) { mutex_enter(p->p_lock); - exit1(l, W_EXITCODE(error, SIGABRT)); + exit1(l, error, SIGABRT, 0); } return error; @@ -2229,7 +2229,7 @@ * A NetBSD specific workaround is POSIX_SPAWN_RETURNERROR as * flag bit in the attrp argument to posix_spawn(2), see above. */ - exit1(l, W_EXITCODE(127, 0)); + exit1(l, 127, 0, 0); } void Index: kern/kern_exit.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_exit.c,v retrieving revision 1.250 diff -u -u -r1.250 kern_exit.c --- kern/kern_exit.c 3 Apr 2016 02:28:46 -0000 1.250 +++ kern/kern_exit.c 4 Apr 2016 16:50:24 -0000 @@ -138,14 +138,19 @@ KSI_INIT(ksi); if ((ksi->ksi_signo = P_EXITSIG(p)) == SIGCHLD) { - if (WIFSIGNALED(p->p_xstat)) { - if (WCOREDUMP(p->p_xstat)) + if (p->p_xsig) { + if (p->p_sflag & PS_COREDUMP) ksi->ksi_code = CLD_DUMPED; else ksi->ksi_code = CLD_KILLED; + ksi->ksi_status = p->p_xsig; } else { ksi->ksi_code = CLD_EXITED; + ksi->ksi_status = p->p_xexit; } + } else { + ksi->ksi_code = SI_USER; + ksi->ksi_status = p->p_xsig; } /* * We fill those in, even for non-SIGCHLD. @@ -153,7 +158,6 @@ */ ksi->ksi_pid = p->p_pid; ksi->ksi_uid = kauth_cred_geteuid(p->p_cred); - ksi->ksi_status = p->p_xstat; /* XXX: is this still valid? */ ksi->ksi_utime = p->p_stats->p_ru.ru_utime.tv_sec; ksi->ksi_stime = p->p_stats->p_ru.ru_stime.tv_sec; @@ -179,7 +183,7 @@ } /* exit1() will release the mutex. */ - exit1(l, W_EXITCODE(SCARG(uap, rval), 0)); + exit1(l, SCARG(uap, rval), 0, 0); /* NOTREACHED */ return (0); } @@ -192,7 +196,7 @@ * Must be called with p->p_lock held. Does not return. */ void -exit1(struct lwp *l, int rv) +exit1(struct lwp *l, int exitcode, int signo, int coredump) { struct proc *p, *child, *next_child, *old_parent, *new_parent; struct pgrp *pgrp; @@ -206,8 +210,7 @@ KASSERT(p->p_vmspace != NULL); if (__predict_false(p == initproc)) { - panic("init died (signal %d, exit %d)", - WTERMSIG(rv), WEXITSTATUS(rv)); + panic("init died (signal %d, exit %d)", signo, exitcode); } p->p_sflag |= PS_WEXIT; @@ -269,7 +272,7 @@ */ rw_enter(&p->p_reflock, RW_WRITER); - DPRINTF(("exit1: %d.%d exiting.\n", p->p_pid, l->l_lid)); + DPRINTF(("%s: %d.%d exiting.\n", __func__, p->p_pid, l->l_lid)); timers_free(p, TIMERS_ALL); #if defined(__HAVE_RAS) @@ -302,13 +305,17 @@ } #endif + p->p_xexit = exitcode; + p->p_xsig = signo; + if (coredump) + p->p_sflag |= PS_COREDUMP; + /* * If emulation has process exit hook, call it now. * Set the exit status now so that the exit hook has * an opportunity to tweak it (COMPAT_LINUX requires * this for thread group emulation) */ - p->p_xstat = rv; if (p->p_emul->e_proc_exit) (*p->p_emul->e_proc_exit)(p); @@ -423,8 +430,8 @@ KNOTE(&p->p_klist, NOTE_EXIT); SDT_PROBE(proc, kernel, , exit, - (WCOREDUMP(rv) ? CLD_DUMPED : - (WIFSIGNALED(rv) ? CLD_KILLED : CLD_EXITED)), + ((p->p_sflag & PS_COREDUMP) ? CLD_DUMPED : + (p->p_xsig ? CLD_KILLED : CLD_EXITED)), 0,0,0,0); #if PERFCTRS @@ -858,15 +865,15 @@ * This is still a rough estimate. We will fix the * cases TRAPPED, STOPPED, and CONTINUED later. */ - if (WCOREDUMP(p->p_xstat)) { + if (p->p_sflag & PS_COREDUMP)) { siginfo->si_code = CLD_DUMPED; - siginfo->si_status = WTERMSIG(p->p_xstat); - } else if (WIFSIGNALED(p->p_xstat)) { + siginfo->si_status = p->p_xsig; + } else if (p->p_xsig) { siginfo->si_code = CLD_KILLED; - siginfo->si_status = WTERMSIG(p->p_xstat); + siginfo->si_status = p->p_xsig; } else { siginfo->si_code = CLD_EXITED; - siginfo->si_status = WEXITSTATUS(p->p_xstat); + siginfo->si_status = p->p_xexit; } siginfo->si_pid = p->p_pid; @@ -976,13 +983,13 @@ } if ((options & WCONTINUED) != 0 && - child->p_xstat == SIGCONT) { + child->p_xsig == SIGCONT) { if ((options & WNOWAIT) == 0) { child->p_waited = 1; parent->p_nstopchild--; } if (si) { - si->si_status = child->p_xstat; + si->si_status = child->p_xsig; si->si_code = CLD_CONTINUED; } break; @@ -998,7 +1005,7 @@ parent->p_nstopchild--; } if (si) { - si->si_status = child->p_xstat; + si->si_status = child->p_xsig; si->si_code = (child->p_slflag & PSL_TRACED) ? CLD_TRAPPED : CLD_STOPPED; @@ -1015,7 +1022,7 @@ if (child != NULL || error != 0 || ((options & WNOHANG) != 0 && dead == NULL)) { if (child != NULL) { - *status_p = child->p_xstat; + *status_p = child->p_xsig; } *child_p = child; return error; @@ -1094,7 +1101,8 @@ wru->wru_self = p->p_stats->p_ru; wru->wru_children = p->p_stats->p_cru; } - p->p_xstat = 0; + p->p_xsig = 0; + p->p_xexit = 0; /* * At this point we are going to start freeing the final resources. Index: kern/kern_lwp.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_lwp.c,v retrieving revision 1.182 diff -u -u -r1.182 kern_lwp.c --- kern/kern_lwp.c 26 Nov 2015 13:15:34 -0000 1.182 +++ kern/kern_lwp.c 4 Apr 2016 16:50:24 -0000 @@ -509,7 +509,7 @@ if (l->l_wchan == NULL) { /* setrunnable() will release the lock. */ setrunnable(l); - } else if (p->p_xstat && (l->l_flag & LW_SINTR) != 0) { + } else if (p->p_xsig && (l->l_flag & LW_SINTR) != 0) { /* setrunnable() so we can receive the signal */ setrunnable(l); } else { @@ -1043,7 +1043,7 @@ KASSERT(current == true); KASSERT(p != &proc0); /* XXXSMP kernel_lock not held */ - exit1(l, 0); + exit1(l, 0, 0, 0); /* NOTREACHED */ } p->p_nzlwps++; Index: kern/kern_proc.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_proc.c,v retrieving revision 1.194 diff -u -u -r1.194 kern_proc.c --- kern/kern_proc.c 24 Sep 2015 14:33:01 -0000 1.194 +++ kern/kern_proc.c 4 Apr 2016 16:50:24 -0000 @@ -2283,7 +2283,7 @@ ki->p_stat = p->p_stat; /* Will likely be overridden by LWP status */ ki->p_realstat = p->p_stat; ki->p_nice = p->p_nice; - ki->p_xstat = p->p_xstat; + ki->p_xstat = P_WAITSTATUS(p); ki->p_acflag = p->p_acflag; strncpy(ki->p_comm, p->p_comm, Index: kern/kern_sig.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_sig.c,v retrieving revision 1.321 diff -u -u -r1.321 kern_sig.c --- kern/kern_sig.c 13 Oct 2015 07:00:59 -0000 1.321 +++ kern/kern_sig.c 4 Apr 2016 16:50:24 -0000 @@ -916,19 +916,19 @@ { ksiginfo_t ksi; struct proc *q; - int xstat; + int xsig; KASSERT(mutex_owned(proc_lock)); KASSERT(mutex_owned(p->p_lock)); - xstat = p->p_xstat; + xsig = p->p_xsig; KSI_INIT(&ksi); ksi.ksi_signo = SIGCHLD; - ksi.ksi_code = (xstat == SIGCONT ? CLD_CONTINUED : CLD_STOPPED); + ksi.ksi_code = (xsig == SIGCONT ? CLD_CONTINUED : CLD_STOPPED); ksi.ksi_pid = p->p_pid; ksi.ksi_uid = kauth_cred_geteuid(p->p_cred); - ksi.ksi_status = xstat; + ksi.ksi_status = xsig; ksi.ksi_utime = p->p_stats->p_ru.ru_utime.tv_sec; ksi.ksi_stime = p->p_stats->p_ru.ru_stime.tv_sec; @@ -1566,7 +1566,7 @@ * If we are no longer being traced, or the parent didn't * give us a signal, or we're stopping, look for more signals. */ - if ((p->p_slflag & PSL_TRACED) == 0 || p->p_xstat == 0 || + if ((p->p_slflag & PSL_TRACED) == 0 || p->p_xsig == 0 || (p->p_sflag & PS_STOPPING) != 0) return 0; @@ -1574,8 +1574,8 @@ * If the new signal is being masked, look for other signals. * `p->p_sigctx.ps_siglist |= mask' is done in setrunnable(). */ - signo = p->p_xstat; - p->p_xstat = 0; + signo = p->p_xsig; + p->p_xsig = 0; if (sigismember(&l->l_sigmask, signo)) { signo = 0; } @@ -1685,7 +1685,7 @@ */ if (sp) sigdelset(&sp->sp_set, signo); - p->p_xstat = signo; + p->p_xsig = signo; /* Emulation-specific handling of signal trace */ if (p->p_emul->e_tracesig == NULL || @@ -1742,9 +1742,9 @@ } /* Take the signal. */ (void)sigget(sp, NULL, signo, NULL); - p->p_xstat = signo; + p->p_xsig = signo; signo = 0; - sigswitch(true, PS_NOCLDSTOP, p->p_xstat); + sigswitch(true, PS_NOCLDSTOP, p->p_xsig); } else if (prop & SA_IGNORE) { /* * Except for SIGCONT, shouldn't get here. @@ -1946,7 +1946,7 @@ void sigexit(struct lwp *l, int signo) { - int exitsig, error, docore; + int exitsig, error, docore, coreflag = 0; struct proc *p; struct lwp *t; @@ -2018,7 +2018,7 @@ if (docore) { mutex_exit(p->p_lock); if ((error = (*coredump_vec)(l, NULL)) == 0) - exitsig |= WCOREFLAG; + coreflag = 1; if (kern_logsigexit) { int uid = l->l_cred ? @@ -2042,7 +2042,7 @@ /* No longer dumping core. */ p->p_sflag &= ~PS_WCORE; - exit1(l, W_EXITCODE(0, exitsig)); + exit1(l, 0, exitsig, coreflag); /* NOTREACHED */ } @@ -2183,7 +2183,7 @@ p->p_stat = SACTIVE; p->p_sflag &= ~PS_STOPPING; - sig = p->p_xstat; + sig = p->p_xsig; if (!p->p_waited) p->p_pptr->p_nstopchild--; Index: kern/sys_process.c =================================================================== RCS file: /cvsroot/src/sys/kern/sys_process.c,v retrieving revision 1.167 diff -u -u -r1.167 sys_process.c --- kern/sys_process.c 9 Jan 2016 07:52:38 -0000 1.167 +++ kern/sys_process.c 4 Apr 2016 16:50:24 -0000 @@ -740,7 +740,7 @@ * signal, make all efforts to ensure that at * an LWP runs to see it. */ - t->p_xstat = signo; + t->p_xsig = signo; if (resume_all) proc_unstop(t); else @@ -1146,7 +1146,7 @@ return; } - p->p_xstat = SIGTRAP; + p->p_xsig = SIGTRAP; proc_stop(p, 1, SIGSTOP); mutex_exit(proc_lock); Index: sys/proc.h =================================================================== RCS file: /cvsroot/src/sys/sys/proc.h,v retrieving revision 1.327 diff -u -u -r1.327 proc.h --- sys/proc.h 1 Dec 2015 01:19:02 -0000 1.327 +++ sys/proc.h 4 Apr 2016 16:50:24 -0000 @@ -326,12 +326,12 @@ vaddr_t p_psstrp; /* :: address of process's ps_strings */ u_int p_pax; /* :: PAX flags */ + int p_xexit; /* p: exit code */ /* * End area that is copied on creation */ -#define p_endcopy p_xstat - - u_short p_xstat; /* p: Exit status for wait; also stop signal */ +#define p_endcopy p_xsig + u_short p_xsig; /* p: stop signal */ u_short p_acflag; /* p: Acc. flags; see struct lwp also */ struct mdproc p_md; /* p: Any machine-dependent fields */ vaddr_t p_stackbase; /* :: ASLR randomized stack base */ @@ -383,10 +383,11 @@ #define PS_STOPEXEC 0x01000000 /* Will be stopped on exec(2) */ #define PS_STOPEXIT 0x02000000 /* Will be stopped at process exit */ #define PS_NOTIFYSTOP 0x10000000 /* Notify parent of successful STOP */ +#define PS_COREDUMP 0x20000000 /* Process core-dumped */ #define PS_STOPPING 0x80000000 /* Transitioning SACTIVE -> SSTOP */ /* - * These flags are kept in p_sflag and are protected by the proc_lock + * These flags are kept in p_slflag and are protected by the proc_lock * and p_lock. Access from process context only. */ #define PSL_TRACEFORK 0x00000001 /* traced process wants fork events */ @@ -402,7 +403,7 @@ #define PST_PROFIL 0x00000020 /* Has started profiling */ /* - * The final set are protected by the proc_lock. Access + * Kept in p_lflag and protected by the proc_lock. Access * from process context only. */ #define PL_CONTROLT 0x00000002 /* Has a controlling terminal */ @@ -417,6 +418,11 @@ */ #define P_EXITSIG(p) \ (((p)->p_slflag & (PSL_TRACED|PSL_FSTRACE)) ? SIGCHLD : p->p_exitsig) +/* + * Compute a wait(2) 16 bit exit status code + */ +#define P_WAITSTATUS(p) W_EXITCODE((p)->p_xexit, (p)->p_xsig | \ + ((p)->p_sflag & PS_COREDUMP) ? WCOREDUMP : 0) LIST_HEAD(proclist, proc); /* A list of processes */ @@ -485,7 +491,7 @@ int mtsleep(wchan_t, pri_t, const char *, int, kmutex_t *); void wakeup(wchan_t); int kpause(const char *, bool, int, kmutex_t *); -void exit1(struct lwp *, int) __dead; +void exit1(struct lwp *, int, int, int) __dead; int kill1(struct lwp *l, pid_t pid, ksiginfo_t *ksi, register_t *retval); int do_sys_wait(int *, int *, int, struct rusage *); struct proc *proc_alloc(void);