]> Zhao Yanbai Git Server - minix.git/commitdiff
Miscellaneous PM fixes:
authorDavid van Moolenbroek <david@minix3.org>
Sun, 5 Jul 2009 22:48:18 +0000 (22:48 +0000)
committerDavid van Moolenbroek <david@minix3.org>
Sun, 5 Jul 2009 22:48:18 +0000 (22:48 +0000)
o Don't call vm_willexit() more than once upon normal process exit
o Correct two cases of indenting of the no-discussion-possible kind
o Perform slightly stricter ptrace(2) checks:
  - process calling ptrace must be target process's parent
  - process must call wait/waitpid before using ptrace on stopped child
  - no ptrace on zombies
o Allow user processes to use ptrace(T_STOP) to stop an active child

servers/pm/forkexit.c
servers/pm/signal.c
servers/pm/trace.c

index 4bfe4ad3054d9a73ffacc526a423bda35f71cd22..eae82993dc0250430d1feabe4106c21ec7b32897 100644 (file)
@@ -226,8 +226,8 @@ int for_trace;
    * such as copying to/ from the exiting process, before it is gone.
    */
   sys_nice(proc_nr_e, PRIO_STOP);      /* stop the process */
-  if(vm_willexit(proc_nr_e) != OK) {
-       panic(__FILE__, "pm_exit: vm_willexit failed", proc_nr_e);
+  if((r=vm_willexit(proc_nr_e)) != OK) {
+       panic(__FILE__, "pm_exit: vm_willexit failed", r);
   }
 
   if (proc_nr_e == INIT_PROC_NR)
index 23c2cb4d1be38aa2c8dd2472c6460570972fd7e6..f80dc0ba4cfdeb242e5f644cb710099fb5c97ad1 100644 (file)
@@ -260,7 +260,7 @@ sigset_t sig_map;
   if ((rmp->mp_flags & (IN_USE | ZOMBIE)) != IN_USE) {
        printf("PM: handle_ksig: %d?? zombie / not in use\n", proc_nr_e);
        return;
-}
+  }
   proc_id = rmp->mp_pid;
   mp = &mproc[0];                      /* pretend signals are from PM */
   mp->mp_procgrp = rmp->mp_procgrp;    /* get process group right */
@@ -517,13 +517,6 @@ doterminate:
   /* Signal should not or cannot be caught.  Take default action. */
   if (sigismember(&ign_sset, signo)) {
        return;
-}
-
-  /* This process will exit, with or without dumping core. 
-   * Announce this fact to VM.
-   */
-  if((s=vm_willexit(rmp->mp_endpoint)) != OK) {
-       panic(__FILE__,"sig_proc: vm_willexit failed", s);
   }
 
   rmp->mp_sigstatus = (char) signo;
@@ -745,6 +738,9 @@ register struct mproc *rmp; /* whose core is to be dumped */
    * such as copying to/ from the exiting process, before it is gone.
    */
   sys_nice(proc_nr_e, PRIO_STOP);      /* stop the process */
+  if((r=vm_willexit(proc_nr_e)) != OK) {
+       panic(__FILE__,"dump_core: vm_willexit failed", r);
+  }
 
   if(proc_nr_e != FS_PROC_NR)          /* if it is not FS that is exiting.. */
   {
index 943169602f787e8065f9020ddf16f524ad2a1393..ec7b35a9a07f9cd5caeeaf225afbf21623a10580 100644 (file)
@@ -87,12 +87,29 @@ PUBLIC int do_trace()
        return(OK);
   }
 
-  if ((child=find_proc(m_in.pid))==NIL_MPROC || !(child->mp_flags & STOPPED)) {
-       return(ESRCH);
-  }
   /* all the other calls are made by the parent fork of the debugger to 
    * control execution of the child
    */
+  if ((child=find_proc(m_in.pid))==NIL_MPROC || child->mp_parent != who_p)
+       return(ESRCH);
+
+  if (m_in.request == T_STOP) {
+       if ((r = sys_trace(T_STOP, child->mp_endpoint, 0L, (long *) 0)) != OK)
+               return(r);
+
+       child->mp_flags |= STOPPED;
+       child->mp_sigstatus = 0;
+
+       mp->mp_reply.reply_trace = 0;
+       return(OK);
+  }
+
+  /* for calls other than T_STOP, the child must be stopped and the parent
+   * must have waited for it
+   */
+  if (!(child->mp_flags & STOPPED) || child->mp_sigstatus > 0)
+       return(ESRCH);
+
   switch (m_in.request) {
   case T_EXIT:         /* exit */
        pm_exit(child, (int) m_in.data, TRUE /*for_trace*/);
@@ -127,7 +144,10 @@ pid_t lpid;
   register struct mproc *rmp;
 
   for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++)
-       if (rmp->mp_flags & IN_USE && rmp->mp_pid == lpid) return(rmp);
+       if ((rmp->mp_flags & (IN_USE | ZOMBIE)) == IN_USE &&
+               rmp->mp_pid == lpid) {
+               return(rmp);
+       }
   return(NIL_MPROC);
 }
 
@@ -143,7 +163,7 @@ int signo;
   register struct mproc *rpmp = mproc + rmp->mp_parent;
   int r;
 
-  r= sys_trace(-1, rmp->mp_endpoint, 0L, (long *) 0);
+  r= sys_trace(T_STOP, rmp->mp_endpoint, 0L, (long *) 0);
   if (r != OK) panic("pm", "sys_trace failed", r);
  
   rmp->mp_flags |= STOPPED;