root/kern/kern_exit.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sys_exit
  2. sys_threxit
  3. exit1
  4. exit2
  5. reaper
  6. sys_wait4
  7. proc_reparent
  8. proc_zap

    1 /*      $OpenBSD: kern_exit.c,v 1.71 2007/04/12 22:14:15 tedu Exp $     */
    2 /*      $NetBSD: kern_exit.c,v 1.39 1996/04/22 01:38:25 christos Exp $  */
    3 
    4 /*
    5  * Copyright (c) 1982, 1986, 1989, 1991, 1993
    6  *      The Regents of the University of California.  All rights reserved.
    7  * (c) UNIX System Laboratories, Inc.
    8  * All or some portions of this file are derived from material licensed
    9  * to the University of California by American Telephone and Telegraph
   10  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
   11  * the permission of UNIX System Laboratories, Inc.
   12  *
   13  * Redistribution and use in source and binary forms, with or without
   14  * modification, are permitted provided that the following conditions
   15  * are met:
   16  * 1. Redistributions of source code must retain the above copyright
   17  *    notice, this list of conditions and the following disclaimer.
   18  * 2. Redistributions in binary form must reproduce the above copyright
   19  *    notice, this list of conditions and the following disclaimer in the
   20  *    documentation and/or other materials provided with the distribution.
   21  * 3. Neither the name of the University nor the names of its contributors
   22  *    may be used to endorse or promote products derived from this software
   23  *    without specific prior written permission.
   24  *
   25  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   28  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   29  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   30  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   31  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   34  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   35  * SUCH DAMAGE.
   36  *
   37  *      @(#)kern_exit.c 8.7 (Berkeley) 2/12/94
   38  */
   39 
   40 #include <sys/param.h>
   41 #include <sys/systm.h>
   42 #include <sys/ioctl.h>
   43 #include <sys/proc.h>
   44 #include <sys/tty.h>
   45 #include <sys/time.h>
   46 #include <sys/resource.h>
   47 #include <sys/kernel.h>
   48 #include <sys/buf.h>
   49 #include <sys/wait.h>
   50 #include <sys/file.h>
   51 #include <sys/vnode.h>
   52 #include <sys/syslog.h>
   53 #include <sys/malloc.h>
   54 #include <sys/resourcevar.h>
   55 #include <sys/ptrace.h>
   56 #include <sys/acct.h>
   57 #include <sys/filedesc.h>
   58 #include <sys/signalvar.h>
   59 #include <sys/sched.h>
   60 #include <sys/ktrace.h>
   61 #include <sys/pool.h>
   62 #include <sys/mutex.h>
   63 #ifdef SYSVSHM
   64 #include <sys/shm.h>
   65 #endif
   66 #ifdef SYSVSEM
   67 #include <sys/sem.h>
   68 #endif
   69 
   70 #include "systrace.h"
   71 #include <dev/systrace.h>
   72 
   73 #include <sys/mount.h>
   74 #include <sys/syscallargs.h>
   75 
   76 #include <machine/cpu.h>
   77 
   78 #include <uvm/uvm_extern.h>
   79 
   80 /*
   81  * exit --
   82  *      Death of process.
   83  */
   84 int
   85 sys_exit(struct proc *p, void *v, register_t *retval)
   86 {
   87         struct sys_exit_args /* {
   88                 syscallarg(int) rval;
   89         } */ *uap = v;
   90 
   91         exit1(p, W_EXITCODE(SCARG(uap, rval), 0), EXIT_NORMAL);
   92         /* NOTREACHED */
   93         return (0);
   94 }
   95 
   96 #ifdef RTHREADS
   97 int
   98 sys_threxit(struct proc *p, void *v, register_t *retval)
   99 {
  100         struct sys_threxit_args *uap = v;
  101 
  102         exit1(p, W_EXITCODE(SCARG(uap, rval), 0), EXIT_THREAD);
  103 
  104         return (0);
  105 }
  106 #endif
  107 
  108 /*
  109  * Exit: deallocate address space and other resources, change proc state
  110  * to zombie, and unlink proc from allproc and parent's lists.  Save exit
  111  * status and rusage for wait().  Check for child processes and orphan them.
  112  */
  113 void
  114 exit1(struct proc *p, int rv, int flags)
  115 {
  116         struct proc *q, *nq;
  117 
  118         if (p->p_pid == 1)
  119                 panic("init died (signal %d, exit %d)",
  120                     WTERMSIG(rv), WEXITSTATUS(rv));
  121         
  122         /* unlink ourselves from the active threads */
  123         TAILQ_REMOVE(&p->p_p->ps_threads, p, p_thr_link);
  124 #ifdef RTHREADS
  125         if (TAILQ_EMPTY(&p->p_p->ps_threads))
  126                 wakeup(&p->p_p->ps_threads);
  127         /*
  128          * if one thread calls exit, we take down everybody.
  129          * we have to be careful not to get recursively caught.
  130          * this is kinda sick.
  131          */
  132         if (flags == EXIT_NORMAL && p->p_p->ps_mainproc != p &&
  133             (p->p_p->ps_mainproc->p_flag & P_WEXIT) == 0) {
  134                 /*
  135                  * we are one of the threads.  we SIGKILL the parent,
  136                  * it will wake us up again, then we proceed.
  137                  */
  138                 atomic_setbits_int(&p->p_p->ps_mainproc->p_flag, P_IGNEXITRV);
  139                 p->p_p->ps_mainproc->p_xstat = rv;
  140                 psignal(p->p_p->ps_mainproc, SIGKILL);
  141                 tsleep(p->p_p, PUSER, "thrdying", 0);
  142         } else if (p == p->p_p->ps_mainproc) {
  143                 atomic_setbits_int(&p->p_flag, P_WEXIT);
  144                 if (flags == EXIT_NORMAL) {
  145                         q = TAILQ_FIRST(&p->p_p->ps_threads);
  146                         for (; q != NULL; q = nq) {
  147                                 nq = TAILQ_NEXT(q, p_thr_link);
  148                                 atomic_setbits_int(&q->p_flag, P_IGNEXITRV);
  149                                 q->p_xstat = rv;
  150                                 psignal(q, SIGKILL);
  151                         }
  152                 }
  153                 wakeup(p->p_p);
  154                 while (!TAILQ_EMPTY(&p->p_p->ps_threads))
  155                         tsleep(&p->p_p->ps_threads, PUSER, "thrdeath", 0);
  156         }
  157 #endif
  158 
  159         if (p->p_flag & P_PROFIL)
  160                 stopprofclock(p);
  161         p->p_ru = pool_get(&rusage_pool, PR_WAITOK);
  162         /*
  163          * If parent is waiting for us to exit or exec, P_PPWAIT is set; we
  164          * wake up the parent early to avoid deadlock.
  165          */
  166         atomic_setbits_int(&p->p_flag, P_WEXIT);
  167         atomic_clearbits_int(&p->p_flag, P_TRACED);
  168         if (p->p_flag & P_PPWAIT) {
  169                 atomic_clearbits_int(&p->p_flag, P_PPWAIT);
  170                 wakeup(p->p_pptr);
  171         }
  172         p->p_sigignore = ~0;
  173         p->p_siglist = 0;
  174         timeout_del(&p->p_realit_to);
  175         timeout_del(&p->p_stats->p_virt_to);
  176         timeout_del(&p->p_stats->p_prof_to);
  177 
  178         /*
  179          * Close open files and release open-file table.
  180          * This may block!
  181          */
  182         fdfree(p);
  183 
  184 #ifdef SYSVSEM
  185         semexit(p);
  186 #endif
  187         if (SESS_LEADER(p)) {
  188                 struct session *sp = p->p_session;
  189 
  190                 if (sp->s_ttyvp) {
  191                         /*
  192                          * Controlling process.
  193                          * Signal foreground pgrp,
  194                          * drain controlling terminal
  195                          * and revoke access to controlling terminal.
  196                          */
  197                         if (sp->s_ttyp->t_session == sp) {
  198                                 if (sp->s_ttyp->t_pgrp)
  199                                         pgsignal(sp->s_ttyp->t_pgrp, SIGHUP, 1);
  200                                 (void) ttywait(sp->s_ttyp);
  201                                 /*
  202                                  * The tty could have been revoked
  203                                  * if we blocked.
  204                                  */
  205                                 if (sp->s_ttyvp)
  206                                         VOP_REVOKE(sp->s_ttyvp, REVOKEALL);
  207                         }
  208                         if (sp->s_ttyvp)
  209                                 vrele(sp->s_ttyvp);
  210                         sp->s_ttyvp = NULL;
  211                         /*
  212                          * s_ttyp is not zero'd; we use this to indicate
  213                          * that the session once had a controlling terminal.
  214                          * (for logging and informational purposes)
  215                          */
  216                 }
  217                 sp->s_leader = NULL;
  218         }
  219         fixjobc(p, p->p_pgrp, 0);
  220 #ifdef ACCOUNTING
  221         (void)acct_process(p);
  222 #endif
  223 #ifdef KTRACE
  224         /* 
  225          * release trace file
  226          */
  227         p->p_traceflag = 0;     /* don't trace the vrele() */
  228         if (p->p_tracep)
  229                 ktrsettracevnode(p, NULL);
  230 #endif
  231 #if NSYSTRACE > 0
  232         if (ISSET(p->p_flag, P_SYSTRACE))
  233                 systrace_exit(p);
  234 #endif
  235         /*
  236          * NOTE: WE ARE NO LONGER ALLOWED TO SLEEP!
  237          */
  238         p->p_stat = SDEAD;
  239 
  240         /*
  241          * Remove proc from pidhash chain so looking it up won't
  242          * work.  Move it from allproc to zombproc, but do not yet
  243          * wake up the reaper.  We will put the proc on the
  244          * deadproc list later (using the p_hash member), and
  245          * wake up the reaper when we do.
  246          */
  247         LIST_REMOVE(p, p_hash);
  248         LIST_REMOVE(p, p_list);
  249         LIST_INSERT_HEAD(&zombproc, p, p_list);
  250 
  251         /*
  252          * Give orphaned children to init(8).
  253          */
  254         q = LIST_FIRST(&p->p_children);
  255         if (q)          /* only need this if any child is S_ZOMB */
  256                 wakeup(initproc);
  257         for (; q != 0; q = nq) {
  258                 nq = LIST_NEXT(q, p_sibling);
  259                 proc_reparent(q, initproc);
  260                 /*
  261                  * Traced processes are killed
  262                  * since their existence means someone is screwing up.
  263                  */
  264                 if (q->p_flag & P_TRACED) {
  265                         atomic_clearbits_int(&q->p_flag, P_TRACED);
  266                         psignal(q, SIGKILL);
  267                 }
  268         }
  269 
  270 
  271         /*
  272          * Save exit status and final rusage info, adding in child rusage
  273          * info and self times.
  274          */
  275         if (!(p->p_flag & P_IGNEXITRV))
  276                 p->p_xstat = rv;
  277         *p->p_ru = p->p_stats->p_ru;
  278         calcru(p, &p->p_ru->ru_utime, &p->p_ru->ru_stime, NULL);
  279         ruadd(p->p_ru, &p->p_stats->p_cru);
  280 
  281         /*
  282          * clear %cpu usage during swap
  283          */
  284         p->p_pctcpu = 0;
  285 
  286         /*
  287          * notify interested parties of our demise.
  288          */
  289         KNOTE(&p->p_klist, NOTE_EXIT);
  290 
  291         /*
  292          * Notify parent that we're gone.  If we have P_NOZOMBIE or parent has
  293          * the P_NOCLDWAIT flag set, notify process 1 instead (and hope it
  294          * will handle this situation).
  295          */
  296         if ((p->p_flag & P_NOZOMBIE) || (p->p_pptr->p_flag & P_NOCLDWAIT)) {
  297                 struct proc *pp = p->p_pptr;
  298                 proc_reparent(p, initproc);
  299                 /*
  300                  * If this was the last child of our parent, notify
  301                  * parent, so in case he was wait(2)ing, he will
  302                  * continue.
  303                  */
  304                 if (LIST_EMPTY(&pp->p_children))
  305                         wakeup(pp);
  306         }
  307 
  308         if (p->p_exitsig != 0)
  309                 psignal(p->p_pptr, P_EXITSIG(p));
  310         wakeup(p->p_pptr);
  311 
  312         /*
  313          * Release the process's signal state.
  314          */
  315         sigactsfree(p);
  316 
  317         /*
  318          * Clear curproc after we've done all operations
  319          * that could block, and before tearing down the rest
  320          * of the process state that might be used from clock, etc.
  321          * Also, can't clear curproc while we're still runnable,
  322          * as we're not on a run queue (we are current, just not
  323          * a proper proc any longer!).
  324          *
  325          * Other substructures are freed from wait().
  326          */
  327         curproc = NULL;
  328 
  329         /*
  330          * If emulation has process exit hook, call it now.
  331          */
  332         if (p->p_emul->e_proc_exit)
  333                 (*p->p_emul->e_proc_exit)(p);
  334 
  335         /* This process no longer needs to hold the kernel lock. */
  336         KERNEL_PROC_UNLOCK(p);
  337 
  338         /*
  339          * Finally, call machine-dependent code to switch to a new
  340          * context (possibly the idle context).  Once we are no longer
  341          * using the dead process's vmspace and stack, exit2() will be
  342          * called to schedule those resources to be released by the
  343          * reaper thread.
  344          *
  345          * Note that cpu_exit() will end with a call equivalent to
  346          * cpu_switch(), finishing our execution (pun intended).
  347          */
  348         uvmexp.swtch++;
  349         cpu_exit(p);
  350 }
  351 
  352 /*
  353  * Locking of this proclist is special; it's accessed in a
  354  * critical section of process exit, and thus locking it can't
  355  * modify interrupt state.  We use a simple spin lock for this
  356  * proclist.  Processes on this proclist are also on zombproc;
  357  * we use the p_hash member to linkup to deadproc.
  358  */
  359 struct mutex deadproc_mutex = MUTEX_INITIALIZER(IPL_NONE);
  360 struct proclist deadproc = LIST_HEAD_INITIALIZER(deadproc);
  361 
  362 /*
  363  * We are called from cpu_exit() once it is safe to schedule the
  364  * dead process's resources to be freed.
  365  *
  366  * NOTE: One must be careful with locking in this routine.  It's
  367  * called from a critical section in machine-dependent code, so
  368  * we should refrain from changing any interrupt state.
  369  *
  370  * We lock the deadproc list, place the proc on that list (using
  371  * the p_hash member), and wake up the reaper.
  372  */
  373 void
  374 exit2(struct proc *p)
  375 {
  376         int s;
  377 
  378         mtx_enter(&deadproc_mutex);
  379         LIST_INSERT_HEAD(&deadproc, p, p_hash);
  380         mtx_leave(&deadproc_mutex);
  381 
  382         wakeup(&deadproc);
  383 
  384         SCHED_LOCK(s);
  385 }
  386 
  387 /*
  388  * Process reaper.  This is run by a kernel thread to free the resources
  389  * of a dead process.  Once the resources are free, the process becomes
  390  * a zombie, and the parent is allowed to read the undead's status.
  391  */
  392 void
  393 reaper(void)
  394 {
  395         struct proc *p;
  396 
  397         KERNEL_PROC_UNLOCK(curproc);
  398 
  399         for (;;) {
  400                 mtx_enter(&deadproc_mutex);
  401                 p = LIST_FIRST(&deadproc);
  402                 if (p == NULL) {
  403                         /* No work for us; go to sleep until someone exits. */
  404                         mtx_leave(&deadproc_mutex);
  405                         (void) tsleep(&deadproc, PVM, "reaper", 0);
  406                         continue;
  407                 }
  408 
  409                 /* Remove us from the deadproc list. */
  410                 LIST_REMOVE(p, p_hash);
  411                 mtx_leave(&deadproc_mutex);
  412                 KERNEL_PROC_LOCK(curproc);
  413 
  414                 /*
  415                  * Give machine-dependent code a chance to free any
  416                  * resources it couldn't free while still running on
  417                  * that process's context.  This must be done before
  418                  * uvm_exit(), in case these resources are in the PCB.
  419                  */
  420                 cpu_wait(p);
  421 
  422                 /*
  423                  * Free the VM resources we're still holding on to.
  424                  * We must do this from a valid thread because doing
  425                  * so may block.
  426                  */
  427                 uvm_exit(p);
  428 
  429                 /* Process is now a true zombie. */
  430                 if ((p->p_flag & P_NOZOMBIE) == 0) {
  431                         p->p_stat = SZOMB;
  432 
  433                         /* Wake up the parent so it can get exit status. */
  434                         psignal(p->p_pptr, SIGCHLD);
  435                         wakeup(p->p_pptr);
  436                 } else {
  437                         /* Noone will wait for us. Just zap the process now */
  438                         proc_zap(p);
  439                 }
  440 
  441                 KERNEL_PROC_UNLOCK(curproc);
  442         }
  443 }
  444 
  445 pid_t
  446 sys_wait4(struct proc *q, void *v, register_t *retval)
  447 {
  448         struct sys_wait4_args /* {
  449                 syscallarg(pid_t) pid;
  450                 syscallarg(int *) status;
  451                 syscallarg(int) options;
  452                 syscallarg(struct rusage *) rusage;
  453         } */ *uap = v;
  454         int nfound;
  455         struct proc *p, *t;
  456         int status, error;
  457 
  458         if (SCARG(uap, pid) == 0)
  459                 SCARG(uap, pid) = -q->p_pgid;
  460         if (SCARG(uap, options) &~ (WUNTRACED|WNOHANG|WALTSIG|WCONTINUED))
  461                 return (EINVAL);
  462 
  463 loop:
  464         nfound = 0;
  465         LIST_FOREACH(p, &q->p_children, p_sibling) {
  466                 if ((p->p_flag & P_NOZOMBIE) ||
  467                     (SCARG(uap, pid) != WAIT_ANY &&
  468                     p->p_pid != SCARG(uap, pid) &&
  469                     p->p_pgid != -SCARG(uap, pid)))
  470                         continue;
  471 
  472                 /*
  473                  * Wait for processes with p_exitsig != SIGCHLD processes only
  474                  * if WALTSIG is set; wait for processes with pexitsig ==
  475                  * SIGCHLD only if WALTSIG is clear.
  476                  */
  477                 if ((SCARG(uap, options) & WALTSIG) ?
  478                     (p->p_exitsig == SIGCHLD) : (P_EXITSIG(p) != SIGCHLD))
  479                         continue;
  480 
  481                 nfound++;
  482                 if (p->p_stat == SZOMB) {
  483                         retval[0] = p->p_pid;
  484 
  485                         if (SCARG(uap, status)) {
  486                                 status = p->p_xstat;    /* convert to int */
  487                                 error = copyout(&status,
  488                                     SCARG(uap, status), sizeof(status));
  489                                 if (error)
  490                                         return (error);
  491                         }
  492                         if (SCARG(uap, rusage) &&
  493                             (error = copyout(p->p_ru,
  494                             SCARG(uap, rusage), sizeof(struct rusage))))
  495                                 return (error);
  496 
  497                         /*
  498                          * If we got the child via a ptrace 'attach',
  499                          * we need to give it back to the old parent.
  500                          */
  501                         if (p->p_oppid && (t = pfind(p->p_oppid))) {
  502                                 p->p_oppid = 0;
  503                                 proc_reparent(p, t);
  504                                 if (p->p_exitsig != 0)
  505                                         psignal(t, P_EXITSIG(p));
  506                                 wakeup(t);
  507                                 return (0);
  508                         }
  509 
  510                         scheduler_wait_hook(q, p);
  511                         p->p_xstat = 0;
  512                         ruadd(&q->p_stats->p_cru, p->p_ru);
  513 
  514                         proc_zap(p);
  515 
  516                         return (0);
  517                 }
  518                 if (p->p_stat == SSTOP && (p->p_flag & P_WAITED) == 0 &&
  519                     (p->p_flag & P_TRACED || SCARG(uap, options) & WUNTRACED)) {
  520                         atomic_setbits_int(&p->p_flag, P_WAITED);
  521                         retval[0] = p->p_pid;
  522 
  523                         if (SCARG(uap, status)) {
  524                                 status = W_STOPCODE(p->p_xstat);
  525                                 error = copyout(&status, SCARG(uap, status),
  526                                     sizeof(status));
  527                         } else
  528                                 error = 0;
  529                         return (error);
  530                 }
  531                 if ((SCARG(uap, options) & WCONTINUED) && (p->p_flag & P_CONTINUED)) {
  532                         atomic_clearbits_int(&p->p_flag, P_CONTINUED);
  533                         retval[0] = p->p_pid;
  534 
  535                         if (SCARG(uap, status)) {
  536                                 status = _WCONTINUED;
  537                                 error = copyout(&status, SCARG(uap, status),
  538                                     sizeof(status));
  539                         } else
  540                                 error = 0;
  541                         return (error);
  542                 }
  543         }
  544         if (nfound == 0)
  545                 return (ECHILD);
  546         if (SCARG(uap, options) & WNOHANG) {
  547                 retval[0] = 0;
  548                 return (0);
  549         }
  550         if ((error = tsleep(q, PWAIT | PCATCH, "wait", 0)) != 0)
  551                 return (error);
  552         goto loop;
  553 }
  554 
  555 /*
  556  * make process 'parent' the new parent of process 'child'.
  557  */
  558 void
  559 proc_reparent(struct proc *child, struct proc *parent)
  560 {
  561 
  562         if (child->p_pptr == parent)
  563                 return;
  564 
  565         if (parent == initproc)
  566                 child->p_exitsig = SIGCHLD;
  567 
  568         LIST_REMOVE(child, p_sibling);
  569         LIST_INSERT_HEAD(&parent->p_children, child, p_sibling);
  570         child->p_pptr = parent;
  571 }
  572 
  573 void
  574 proc_zap(struct proc *p)
  575 {
  576         pool_put(&rusage_pool, p->p_ru);
  577         if (p->p_ptstat)
  578                 free(p->p_ptstat, M_SUBPROC);
  579 
  580         /*
  581          * Finally finished with old proc entry.
  582          * Unlink it from its process group and free it.
  583          */
  584         leavepgrp(p);
  585         LIST_REMOVE(p, p_list); /* off zombproc */
  586         LIST_REMOVE(p, p_sibling);
  587 
  588         /*
  589          * Decrement the count of procs running with this uid.
  590          */
  591         (void)chgproccnt(p->p_cred->p_ruid, -1);
  592 
  593         /*
  594          * Release reference to text vnode
  595          */
  596         if (p->p_textvp)
  597                 vrele(p->p_textvp);
  598 
  599         /*
  600          * Remove us from our process list, possibly killing the process
  601          * in the process (pun intended).
  602          */
  603 #if 0
  604         TAILQ_REMOVE(&p->p_p->ps_threads, p, p_thr_link);
  605 #endif
  606         if (TAILQ_EMPTY(&p->p_p->ps_threads)) {
  607                 limfree(p->p_p->ps_limit);
  608                 if (--p->p_p->ps_cred->p_refcnt == 0) {
  609                         crfree(p->p_p->ps_cred->pc_ucred);
  610                         pool_put(&pcred_pool, p->p_p->ps_cred);
  611                 }
  612                 pool_put(&process_pool, p->p_p);
  613         }
  614 
  615         pool_put(&proc_pool, p);
  616         nprocs--;
  617 }
  618 

/* [<][>][^][v][top][bottom][index][help] */