. processes stay ZOMBIE, even after wait(), to avoid wrongly seeing them
as living processes before they are cleaned up (fixes wait()/waitpid() hanging forever on previously-ZOMBIE processes) . stop processes from running using sys_nice() with PRIO_STOP when a handled signal is delivered, before computing stack locations for sys_sigsend(). (fixes race condition when runnable processes get signals, and e.g. get scheduled before FS sends a reply to unpause(), which can make the signal stack location wrong.)
This commit is contained in:
parent
4933f34715
commit
1e656b349d
@ -326,6 +326,7 @@ int for_trace;
|
||||
rmp->mp_parent = INIT_PROC_NR;
|
||||
parent_waiting = mproc[INIT_PROC_NR].mp_flags & WAITING;
|
||||
if (parent_waiting && (rmp->mp_flags & ZOMBIE) &&
|
||||
!(rmp->mp_flags & TOLD_PARENT) &&
|
||||
rmp->mp_fs_call != PM_EXIT) {
|
||||
cleanup(rmp);
|
||||
}
|
||||
@ -369,6 +370,7 @@ PUBLIC int do_waitpid()
|
||||
/* The value of pidarg determines which children qualify. */
|
||||
if (pidarg > 0 && pidarg != rp->mp_pid) continue;
|
||||
if (pidarg < -1 && -pidarg != rp->mp_procgrp) continue;
|
||||
if (rp->mp_flags & TOLD_PARENT) continue; /* post-ZOMBIE */
|
||||
|
||||
children++; /* this child is acceptable */
|
||||
if (rp->mp_flags & ZOMBIE) {
|
||||
@ -430,6 +432,8 @@ register struct mproc *child; /* tells which process is exiting */
|
||||
mp_parent= child->mp_parent;
|
||||
if (mp_parent <= 0)
|
||||
panic(__FILE__, "tell_parent: bad value in mp_parent", mp_parent);
|
||||
if(child->mp_flags & TOLD_PARENT)
|
||||
panic(__FILE__, "tell_parent: telling parent again", NO_NUM);
|
||||
parent = &mproc[mp_parent];
|
||||
|
||||
/* Wake up the parent by sending the reply message. */
|
||||
@ -437,7 +441,7 @@ register struct mproc *child; /* tells which process is exiting */
|
||||
parent->mp_reply.reply_res2 = exitstatus;
|
||||
setreply(child->mp_parent, child->mp_pid);
|
||||
parent->mp_flags &= ~WAITING; /* parent no longer waiting */
|
||||
child->mp_flags &= ~ZOMBIE; /* avoid informing parent twice */
|
||||
child->mp_flags |= TOLD_PARENT; /* avoid informing parent twice */
|
||||
}
|
||||
|
||||
/*===========================================================================*
|
||||
|
@ -794,7 +794,7 @@ message *m_ptr;
|
||||
/* Clean up if the parent has collected the exit
|
||||
* status
|
||||
*/
|
||||
if (!(rmp->mp_flags & ZOMBIE))
|
||||
if (rmp->mp_flags & TOLD_PARENT)
|
||||
real_cleanup(rmp);
|
||||
|
||||
break;
|
||||
@ -909,7 +909,7 @@ message *m_ptr;
|
||||
/* Clean up if the parent has collected the exit
|
||||
* status
|
||||
*/
|
||||
if (!(rmp->mp_flags & ZOMBIE))
|
||||
if (rmp->mp_flags & TOLD_PARENT)
|
||||
real_cleanup(rmp);
|
||||
|
||||
break;
|
||||
|
@ -84,6 +84,7 @@ EXTERN struct mproc {
|
||||
#define PRIV_PROC 0x2000 /* system process, special privileges */
|
||||
#define PM_SIG_PENDING 0x4000 /* process got a signal while waiting for FS */
|
||||
#define PARTIAL_EXEC 0x8000 /* Process got a new map but no content */
|
||||
#define TOLD_PARENT 0x10000 /* Parent wait() completed, ZOMBIE off */
|
||||
|
||||
#define NIL_MPROC ((struct mproc *) 0)
|
||||
|
||||
|
@ -454,6 +454,8 @@ int signo; /* signal to send to process (1 to _NSIG) */
|
||||
#endif
|
||||
sigflags = rmp->mp_sigact[signo].sa_flags;
|
||||
if (sigismember(&rmp->mp_catch, signo)) {
|
||||
/* Stop process from running before we do stack calculations. */
|
||||
sys_nice(rmp->mp_endpoint, PRIO_STOP);
|
||||
if (rmp->mp_flags & SIGSUSPENDED)
|
||||
rmp->mp_sigmsg.sm_mask = rmp->mp_sigmask2;
|
||||
else
|
||||
|
Loading…
x
Reference in New Issue
Block a user