From 904cf1f84d4a31d0e1fad6c68170e83269ff81fb Mon Sep 17 00:00:00 2001 From: Ben Gras Date: Mon, 4 Jul 2005 15:20:46 +0000 Subject: [PATCH] A "fix" for bug no. 2 is to check if the process slot has disappeared. Not a really good solution (as it might not catch situations in which this is caused by another bug), but the forrest of checks necessary might be worse than this quick fix - because when looking for the cause, I found some other cases in which the PM would panic as well. See info in bug 2 for details. Another fix is to delay notification of PM by SYSTASK of signals delivered internally until after the reply (e.g. of exec()), because the reply would be messed up otherwise (receiving the notify instead of reply). This caused SIGTRAP not to be delivered properly with traced processes. --- kernel/system.c | 7 ++++++- servers/pm/main.c | 8 +++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/kernel/system.c b/kernel/system.c index 2fd5613a4..d5db29770 100755 --- a/kernel/system.c +++ b/kernel/system.c @@ -79,6 +79,11 @@ PUBLIC void sys_task() /* Handle the request. */ if ((unsigned) m.m_type < NR_SYS_CALLS) { result = (*call_vec[m.m_type])(&m); /* do system call */ + } else if(m.NOTIFY_TYPE == KSIG_PENDING) { + message pmm; + pmm.NOTIFY_TYPE = KSIG_PENDING; + lock_notify(PM_PROC_NR, &pmm); + continue; } else { kprintf("Warning, illegal SYSTASK request from %d.\n", m.m_source); result = EBADREQUEST; /* illegal message type */ @@ -318,7 +323,7 @@ int sig_nr; /* signal to be sent, 1 to _NSIG */ if (rp->p_rts_flags == 0) lock_unready(rp); /* make not ready */ rp->p_rts_flags |= SIGNALED | SIG_PENDING; /* update flags */ m.NOTIFY_TYPE = KSIG_PENDING; - lock_notify(PM_PROC_NR, &m); + lock_notify(SYSTASK, &m); } } } diff --git a/servers/pm/main.c b/servers/pm/main.c index fb15d0748..018c99ebd 100644 --- a/servers/pm/main.c +++ b/servers/pm/main.c @@ -75,7 +75,13 @@ PUBLIC void main() * the call just made above. The processes must not be swapped out. */ for (proc_nr=0, rmp=mproc; proc_nr < NR_PROCS; proc_nr++, rmp++) { - if ((rmp->mp_flags & (REPLY | ONSWAP)) == REPLY) { + /* In the meantime, the process may have been killed by a + * signal (e.g. if a lethal pending signal was unblocked) + * without the PM realizing it. If the slot is no longer in + * use or just a zombie, don't try to reply. + */ + if ((rmp->mp_flags & (REPLY | ONSWAP | IN_USE | ZOMBIE)) == + (REPLY | IN_USE)) { if ((s=send(proc_nr, &rmp->mp_reply)) != OK) { panic(__FILE__,"PM can't reply to", proc_nr); } -- 2.44.0