]> Zhao Yanbai Git Server - minix.git/commitdiff
A "fix" for bug no. 2 is to check if the process slot has disappeared.
authorBen Gras <ben@minix3.org>
Mon, 4 Jul 2005 15:20:46 +0000 (15:20 +0000)
committerBen Gras <ben@minix3.org>
Mon, 4 Jul 2005 15:20:46 +0000 (15:20 +0000)
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
servers/pm/main.c

index 2fd5613a42ec164c389be90445c18c8fee8e5484..d5db29770ddc7465a269203a473ad30c0721bac8 100755 (executable)
@@ -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);
       }
   }
 }
index fb15d0748cc3e0a200cc75711127d46428f40182..018c99ebd9665c10402a1395a5e7c65493e7063b 100644 (file)
@@ -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);
                        }