. 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;
|
rmp->mp_parent = INIT_PROC_NR;
|
||||||
parent_waiting = mproc[INIT_PROC_NR].mp_flags & WAITING;
|
parent_waiting = mproc[INIT_PROC_NR].mp_flags & WAITING;
|
||||||
if (parent_waiting && (rmp->mp_flags & ZOMBIE) &&
|
if (parent_waiting && (rmp->mp_flags & ZOMBIE) &&
|
||||||
|
!(rmp->mp_flags & TOLD_PARENT) &&
|
||||||
rmp->mp_fs_call != PM_EXIT) {
|
rmp->mp_fs_call != PM_EXIT) {
|
||||||
cleanup(rmp);
|
cleanup(rmp);
|
||||||
}
|
}
|
||||||
@ -369,6 +370,7 @@ PUBLIC int do_waitpid()
|
|||||||
/* The value of pidarg determines which children qualify. */
|
/* The value of pidarg determines which children qualify. */
|
||||||
if (pidarg > 0 && pidarg != rp->mp_pid) continue;
|
if (pidarg > 0 && pidarg != rp->mp_pid) continue;
|
||||||
if (pidarg < -1 && -pidarg != rp->mp_procgrp) continue;
|
if (pidarg < -1 && -pidarg != rp->mp_procgrp) continue;
|
||||||
|
if (rp->mp_flags & TOLD_PARENT) continue; /* post-ZOMBIE */
|
||||||
|
|
||||||
children++; /* this child is acceptable */
|
children++; /* this child is acceptable */
|
||||||
if (rp->mp_flags & ZOMBIE) {
|
if (rp->mp_flags & ZOMBIE) {
|
||||||
@ -430,6 +432,8 @@ register struct mproc *child; /* tells which process is exiting */
|
|||||||
mp_parent= child->mp_parent;
|
mp_parent= child->mp_parent;
|
||||||
if (mp_parent <= 0)
|
if (mp_parent <= 0)
|
||||||
panic(__FILE__, "tell_parent: bad value in mp_parent", mp_parent);
|
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];
|
parent = &mproc[mp_parent];
|
||||||
|
|
||||||
/* Wake up the parent by sending the reply message. */
|
/* 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;
|
parent->mp_reply.reply_res2 = exitstatus;
|
||||||
setreply(child->mp_parent, child->mp_pid);
|
setreply(child->mp_parent, child->mp_pid);
|
||||||
parent->mp_flags &= ~WAITING; /* parent no longer waiting */
|
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
|
/* Clean up if the parent has collected the exit
|
||||||
* status
|
* status
|
||||||
*/
|
*/
|
||||||
if (!(rmp->mp_flags & ZOMBIE))
|
if (rmp->mp_flags & TOLD_PARENT)
|
||||||
real_cleanup(rmp);
|
real_cleanup(rmp);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -909,7 +909,7 @@ message *m_ptr;
|
|||||||
/* Clean up if the parent has collected the exit
|
/* Clean up if the parent has collected the exit
|
||||||
* status
|
* status
|
||||||
*/
|
*/
|
||||||
if (!(rmp->mp_flags & ZOMBIE))
|
if (rmp->mp_flags & TOLD_PARENT)
|
||||||
real_cleanup(rmp);
|
real_cleanup(rmp);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -84,6 +84,7 @@ EXTERN struct mproc {
|
|||||||
#define PRIV_PROC 0x2000 /* system process, special privileges */
|
#define PRIV_PROC 0x2000 /* system process, special privileges */
|
||||||
#define PM_SIG_PENDING 0x4000 /* process got a signal while waiting for FS */
|
#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 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)
|
#define NIL_MPROC ((struct mproc *) 0)
|
||||||
|
|
||||||
|
@ -454,6 +454,8 @@ int signo; /* signal to send to process (1 to _NSIG) */
|
|||||||
#endif
|
#endif
|
||||||
sigflags = rmp->mp_sigact[signo].sa_flags;
|
sigflags = rmp->mp_sigact[signo].sa_flags;
|
||||||
if (sigismember(&rmp->mp_catch, signo)) {
|
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)
|
if (rmp->mp_flags & SIGSUSPENDED)
|
||||||
rmp->mp_sigmsg.sm_mask = rmp->mp_sigmask2;
|
rmp->mp_sigmsg.sm_mask = rmp->mp_sigmask2;
|
||||||
else
|
else
|
||||||
|
Loading…
x
Reference in New Issue
Block a user