The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kern/kern_exit.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 1982, 1986, 1989, 1991, 1993
    3  *      The Regents of the University of California.  All rights reserved.
    4  * (c) UNIX System Laboratories, Inc.
    5  * All or some portions of this file are derived from material licensed
    6  * to the University of California by American Telephone and Telegraph
    7  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
    8  * the permission of UNIX System Laboratories, Inc.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  * 4. Neither the name of the University nor the names of its contributors
   19  *    may be used to endorse or promote products derived from this software
   20  *    without specific prior written permission.
   21  *
   22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   32  * SUCH DAMAGE.
   33  *
   34  *      @(#)kern_exit.c 8.7 (Berkeley) 2/12/94
   35  */
   36 
   37 #include <sys/cdefs.h>
   38 __FBSDID("$FreeBSD: releng/8.4/sys/kern/kern_exit.c 247350 2013-02-26 21:05:06Z jhb $");
   39 
   40 #include "opt_compat.h"
   41 #include "opt_kdtrace.h"
   42 #include "opt_ktrace.h"
   43 
   44 #include <sys/param.h>
   45 #include <sys/systm.h>
   46 #include <sys/sysproto.h>
   47 #include <sys/eventhandler.h>
   48 #include <sys/kernel.h>
   49 #include <sys/malloc.h>
   50 #include <sys/lock.h>
   51 #include <sys/mutex.h>
   52 #include <sys/proc.h>
   53 #include <sys/pioctl.h>
   54 #include <sys/jail.h>
   55 #include <sys/tty.h>
   56 #include <sys/wait.h>
   57 #include <sys/vmmeter.h>
   58 #include <sys/vnode.h>
   59 #include <sys/resourcevar.h>
   60 #include <sys/sbuf.h>
   61 #include <sys/signalvar.h>
   62 #include <sys/sched.h>
   63 #include <sys/sx.h>
   64 #include <sys/syscallsubr.h>
   65 #include <sys/syslog.h>
   66 #include <sys/ptrace.h>
   67 #include <sys/acct.h>           /* for acct_process() function prototype */
   68 #include <sys/filedesc.h>
   69 #include <sys/sdt.h>
   70 #include <sys/shm.h>
   71 #include <sys/sem.h>
   72 #ifdef KTRACE
   73 #include <sys/ktrace.h>
   74 #endif
   75 
   76 #include <security/audit/audit.h>
   77 #include <security/mac/mac_framework.h>
   78 
   79 #include <vm/vm.h>
   80 #include <vm/vm_extern.h>
   81 #include <vm/vm_param.h>
   82 #include <vm/pmap.h>
   83 #include <vm/vm_map.h>
   84 #include <vm/vm_page.h>
   85 #include <vm/uma.h>
   86 
   87 #ifdef KDTRACE_HOOKS
   88 #include <sys/dtrace_bsd.h>
   89 dtrace_execexit_func_t  dtrace_fasttrap_exit;
   90 #endif
   91 
   92 SDT_PROVIDER_DECLARE(proc);
   93 SDT_PROBE_DEFINE(proc, kernel, , exit, exit);
   94 SDT_PROBE_ARGTYPE(proc, kernel, , exit, 0, "int");
   95 
   96 /* Hook for NFS teardown procedure. */
   97 void (*nlminfo_release_p)(struct proc *p);
   98 
   99 /*
  100  * exit -- death of process.
  101  */
  102 void
  103 sys_exit(struct thread *td, struct sys_exit_args *uap)
  104 {
  105 
  106         exit1(td, W_EXITCODE(uap->rval, 0));
  107         /* NOTREACHED */
  108 }
  109 
  110 /*
  111  * Exit: deallocate address space and other resources, change proc state to
  112  * zombie, and unlink proc from allproc and parent's lists.  Save exit status
  113  * and rusage for wait().  Check for child processes and orphan them.
  114  */
  115 void
  116 exit1(struct thread *td, int rv)
  117 {
  118         struct proc *p, *nq, *q;
  119         struct vnode *vtmp;
  120         struct vnode *ttyvp = NULL;
  121         struct plimit *plim;
  122         int locked;
  123 
  124         mtx_assert(&Giant, MA_NOTOWNED);
  125 
  126         p = td->td_proc;
  127         /*
  128          * XXX in case we're rebooting we just let init die in order to
  129          * work around an unsolved stack overflow seen very late during
  130          * shutdown on sparc64 when the gmirror worker process exists.
  131          */ 
  132         if (p == initproc && rebooting == 0) {
  133                 printf("init died (signal %d, exit %d)\n",
  134                     WTERMSIG(rv), WEXITSTATUS(rv));
  135                 panic("Going nowhere without my init!");
  136         }
  137 
  138         /*
  139          * MUST abort all other threads before proceeding past here.
  140          */
  141         PROC_LOCK(p);
  142         while (p->p_flag & P_HADTHREADS) {
  143                 /*
  144                  * First check if some other thread got here before us..
  145                  * if so, act apropriatly, (exit or suspend);
  146                  */
  147                 thread_suspend_check(0);
  148 
  149                 /*
  150                  * Kill off the other threads. This requires
  151                  * some co-operation from other parts of the kernel
  152                  * so it may not be instantaneous.  With this state set
  153                  * any thread entering the kernel from userspace will
  154                  * thread_exit() in trap().  Any thread attempting to
  155                  * sleep will return immediately with EINTR or EWOULDBLOCK
  156                  * which will hopefully force them to back out to userland
  157                  * freeing resources as they go.  Any thread attempting
  158                  * to return to userland will thread_exit() from userret().
  159                  * thread_exit() will unsuspend us when the last of the
  160                  * other threads exits.
  161                  * If there is already a thread singler after resumption,
  162                  * calling thread_single will fail; in that case, we just
  163                  * re-check all suspension request, the thread should
  164                  * either be suspended there or exit.
  165                  */
  166                 if (! thread_single(SINGLE_EXIT))
  167                         break;
  168 
  169                 /*
  170                  * All other activity in this process is now stopped.
  171                  * Threading support has been turned off.
  172                  */
  173         }
  174         KASSERT(p->p_numthreads == 1,
  175             ("exit1: proc %p exiting with %d threads", p, p->p_numthreads));
  176         /*
  177          * Wakeup anyone in procfs' PIOCWAIT.  They should have a hold
  178          * on our vmspace, so we should block below until they have
  179          * released their reference to us.  Note that if they have
  180          * requested S_EXIT stops we will block here until they ack
  181          * via PIOCCONT.
  182          */
  183         _STOPEVENT(p, S_EXIT, rv);
  184 
  185         /*
  186          * Ignore any pending request to stop due to a stop signal.
  187          * Once P_WEXIT is set, future requests will be ignored as
  188          * well.
  189          */
  190         p->p_flag &= ~P_STOPPED_SIG;
  191         KASSERT(!P_SHOULDSTOP(p), ("exiting process is stopped"));
  192 
  193         /*
  194          * Note that we are exiting and do another wakeup of anyone in
  195          * PIOCWAIT in case they aren't listening for S_EXIT stops or
  196          * decided to wait again after we told them we are exiting.
  197          */
  198         p->p_flag |= P_WEXIT;
  199         wakeup(&p->p_stype);
  200 
  201         /*
  202          * Wait for any processes that have a hold on our vmspace to
  203          * release their reference.
  204          */
  205         while (p->p_lock > 0)
  206                 msleep(&p->p_lock, &p->p_mtx, PWAIT, "exithold", 0);
  207 
  208         p->p_xstat = rv;        /* Let event handler change exit status */
  209         PROC_UNLOCK(p);
  210         /* Drain the limit callout while we don't have the proc locked */
  211         callout_drain(&p->p_limco);
  212 
  213 #ifdef AUDIT
  214         /*
  215          * The Sun BSM exit token contains two components: an exit status as
  216          * passed to exit(), and a return value to indicate what sort of exit
  217          * it was.  The exit status is WEXITSTATUS(rv), but it's not clear
  218          * what the return value is.
  219          */
  220         AUDIT_ARG_EXIT(WEXITSTATUS(rv), 0);
  221         AUDIT_SYSCALL_EXIT(0, td);
  222 #endif
  223 
  224         /* Are we a task leader? */
  225         if (p == p->p_leader) {
  226                 mtx_lock(&ppeers_lock);
  227                 q = p->p_peers;
  228                 while (q != NULL) {
  229                         PROC_LOCK(q);
  230                         psignal(q, SIGKILL);
  231                         PROC_UNLOCK(q);
  232                         q = q->p_peers;
  233                 }
  234                 while (p->p_peers != NULL)
  235                         msleep(p, &ppeers_lock, PWAIT, "exit1", 0);
  236                 mtx_unlock(&ppeers_lock);
  237         }
  238 
  239         /*
  240          * Check if any loadable modules need anything done at process exit.
  241          * E.g. SYSV IPC stuff
  242          * XXX what if one of these generates an error?
  243          */
  244         EVENTHANDLER_INVOKE(process_exit, p);
  245 
  246         /*
  247          * If parent is waiting for us to exit or exec,
  248          * P_PPWAIT is set; we will wakeup the parent below.
  249          */
  250         PROC_LOCK(p);
  251         rv = p->p_xstat;        /* Event handler could change exit status */
  252         stopprofclock(p);
  253         p->p_flag &= ~(P_TRACED | P_PPWAIT);
  254 
  255         /*
  256          * Stop the real interval timer.  If the handler is currently
  257          * executing, prevent it from rearming itself and let it finish.
  258          */
  259         if (timevalisset(&p->p_realtimer.it_value) &&
  260             callout_stop(&p->p_itcallout) == 0) {
  261                 timevalclear(&p->p_realtimer.it_interval);
  262                 msleep(&p->p_itcallout, &p->p_mtx, PWAIT, "ritwait", 0);
  263                 KASSERT(!timevalisset(&p->p_realtimer.it_value),
  264                     ("realtime timer is still armed"));
  265         }
  266         PROC_UNLOCK(p);
  267 
  268         /*
  269          * Reset any sigio structures pointing to us as a result of
  270          * F_SETOWN with our pid.
  271          */
  272         funsetownlst(&p->p_sigiolst);
  273 
  274         /*
  275          * If this process has an nlminfo data area (for lockd), release it
  276          */
  277         if (nlminfo_release_p != NULL && p->p_nlminfo != NULL)
  278                 (*nlminfo_release_p)(p);
  279 
  280         /*
  281          * Close open files and release open-file table.
  282          * This may block!
  283          */
  284         fdfree(td);
  285 
  286         /*
  287          * If this thread tickled GEOM, we need to wait for the giggling to
  288          * stop before we return to userland
  289          */
  290         if (td->td_pflags & TDP_GEOM)
  291                 g_waitidle();
  292 
  293         /*
  294          * Remove ourself from our leader's peer list and wake our leader.
  295          */
  296         mtx_lock(&ppeers_lock);
  297         if (p->p_leader->p_peers) {
  298                 q = p->p_leader;
  299                 while (q->p_peers != p)
  300                         q = q->p_peers;
  301                 q->p_peers = p->p_peers;
  302                 wakeup(p->p_leader);
  303         }
  304         mtx_unlock(&ppeers_lock);
  305 
  306         vmspace_exit(td);
  307 
  308         sx_xlock(&proctree_lock);
  309         if (SESS_LEADER(p)) {
  310                 struct session *sp = p->p_session;
  311                 struct tty *tp;
  312 
  313                 /*
  314                  * s_ttyp is not zero'd; we use this to indicate that
  315                  * the session once had a controlling terminal. (for
  316                  * logging and informational purposes)
  317                  */
  318                 SESS_LOCK(sp);
  319                 ttyvp = sp->s_ttyvp;
  320                 tp = sp->s_ttyp;
  321                 sp->s_ttyvp = NULL;
  322                 sp->s_leader = NULL;
  323                 SESS_UNLOCK(sp);
  324 
  325                 /*
  326                  * Signal foreground pgrp and revoke access to
  327                  * controlling terminal if it has not been revoked
  328                  * already.
  329                  *
  330                  * Because the TTY may have been revoked in the mean
  331                  * time and could already have a new session associated
  332                  * with it, make sure we don't send a SIGHUP to a
  333                  * foreground process group that does not belong to this
  334                  * session.
  335                  */
  336 
  337                 if (tp != NULL) {
  338                         tty_lock(tp);
  339                         if (tp->t_session == sp)
  340                                 tty_signal_pgrp(tp, SIGHUP);
  341                         tty_unlock(tp);
  342                 }
  343 
  344                 if (ttyvp != NULL) {
  345                         sx_xunlock(&proctree_lock);
  346                         if (vn_lock(ttyvp, LK_EXCLUSIVE) == 0) {
  347                                 VOP_REVOKE(ttyvp, REVOKEALL);
  348                                 VOP_UNLOCK(ttyvp, 0);
  349                         }
  350                         sx_xlock(&proctree_lock);
  351                 }
  352         }
  353         fixjobc(p, p->p_pgrp, 0);
  354         sx_xunlock(&proctree_lock);
  355         (void)acct_process(td);
  356 
  357         /* Release the TTY now we've unlocked everything. */
  358         if (ttyvp != NULL)
  359                 vrele(ttyvp);
  360 #ifdef KTRACE
  361         ktrprocexit(td);
  362 #endif
  363         /*
  364          * Release reference to text vnode
  365          */
  366         if ((vtmp = p->p_textvp) != NULL) {
  367                 p->p_textvp = NULL;
  368                 locked = VFS_LOCK_GIANT(vtmp->v_mount);
  369                 vrele(vtmp);
  370                 VFS_UNLOCK_GIANT(locked);
  371         }
  372 
  373         /*
  374          * Release our limits structure.
  375          */
  376         PROC_LOCK(p);
  377         plim = p->p_limit;
  378         p->p_limit = NULL;
  379         PROC_UNLOCK(p);
  380         lim_free(plim);
  381 
  382         /*
  383          * Remove proc from allproc queue and pidhash chain.
  384          * Place onto zombproc.  Unlink from parent's child list.
  385          */
  386         sx_xlock(&allproc_lock);
  387         LIST_REMOVE(p, p_list);
  388         LIST_INSERT_HEAD(&zombproc, p, p_list);
  389         LIST_REMOVE(p, p_hash);
  390         sx_xunlock(&allproc_lock);
  391 
  392         /*
  393          * Call machine-dependent code to release any
  394          * machine-dependent resources other than the address space.
  395          * The address space is released by "vmspace_exitfree(p)" in
  396          * vm_waitproc().
  397          */
  398         cpu_exit(td);
  399 
  400         WITNESS_WARN(WARN_PANIC, NULL, "process (pid %d) exiting", p->p_pid);
  401 
  402         /*
  403          * Reparent all of our children to init.
  404          */
  405         sx_xlock(&proctree_lock);
  406         q = LIST_FIRST(&p->p_children);
  407         if (q != NULL)          /* only need this if any child is S_ZOMB */
  408                 wakeup(initproc);
  409         for (; q != NULL; q = nq) {
  410                 nq = LIST_NEXT(q, p_sibling);
  411                 PROC_LOCK(q);
  412                 proc_reparent(q, initproc);
  413                 q->p_sigparent = SIGCHLD;
  414                 /*
  415                  * Traced processes are killed
  416                  * since their existence means someone is screwing up.
  417                  */
  418                 if (q->p_flag & P_TRACED) {
  419                         struct thread *temp;
  420 
  421                         q->p_flag &= ~(P_TRACED | P_STOPPED_TRACE);
  422                         FOREACH_THREAD_IN_PROC(q, temp)
  423                                 temp->td_dbgflags &= ~TDB_SUSPEND;
  424                         psignal(q, SIGKILL);
  425                 }
  426                 PROC_UNLOCK(q);
  427         }
  428 
  429         /* Save exit status. */
  430         PROC_LOCK(p);
  431         p->p_xthread = td;
  432 
  433         /* Tell the prison that we are gone. */
  434         prison_proc_free(p->p_ucred->cr_prison);
  435 
  436 #ifdef KDTRACE_HOOKS
  437         /*
  438          * Tell the DTrace fasttrap provider about the exit if it
  439          * has declared an interest.
  440          */
  441         if (dtrace_fasttrap_exit)
  442                 dtrace_fasttrap_exit(p);
  443 #endif
  444 
  445         /*
  446          * Notify interested parties of our demise.
  447          */
  448         KNOTE_LOCKED(&p->p_klist, NOTE_EXIT);
  449 
  450 #ifdef KDTRACE_HOOKS
  451         int reason = CLD_EXITED;
  452         if (WCOREDUMP(rv))
  453                 reason = CLD_DUMPED;
  454         else if (WIFSIGNALED(rv))
  455                 reason = CLD_KILLED;
  456         SDT_PROBE(proc, kernel, , exit, reason, 0, 0, 0, 0);
  457 #endif
  458 
  459         /*
  460          * Just delete all entries in the p_klist. At this point we won't
  461          * report any more events, and there are nasty race conditions that
  462          * can beat us if we don't.
  463          */
  464         knlist_clear(&p->p_klist, 1);
  465 
  466         /*
  467          * Notify parent that we're gone.  If parent has the PS_NOCLDWAIT
  468          * flag set, or if the handler is set to SIG_IGN, notify process
  469          * 1 instead (and hope it will handle this situation).
  470          */
  471         PROC_LOCK(p->p_pptr);
  472         mtx_lock(&p->p_pptr->p_sigacts->ps_mtx);
  473         if (p->p_pptr->p_sigacts->ps_flag & (PS_NOCLDWAIT | PS_CLDSIGIGN)) {
  474                 struct proc *pp;
  475 
  476                 mtx_unlock(&p->p_pptr->p_sigacts->ps_mtx);
  477                 pp = p->p_pptr;
  478                 PROC_UNLOCK(pp);
  479                 proc_reparent(p, initproc);
  480                 p->p_sigparent = SIGCHLD;
  481                 PROC_LOCK(p->p_pptr);
  482 
  483                 /*
  484                  * Notify parent, so in case he was wait(2)ing or
  485                  * executing waitpid(2) with our pid, he will
  486                  * continue.
  487                  */
  488                 wakeup(pp);
  489         } else
  490                 mtx_unlock(&p->p_pptr->p_sigacts->ps_mtx);
  491 
  492         if (p->p_pptr == initproc)
  493                 psignal(p->p_pptr, SIGCHLD);
  494         else if (p->p_sigparent != 0) {
  495                 if (p->p_sigparent == SIGCHLD)
  496                         childproc_exited(p);
  497                 else    /* LINUX thread */
  498                         psignal(p->p_pptr, p->p_sigparent);
  499         }
  500         sx_xunlock(&proctree_lock);
  501 
  502         /*
  503          * The state PRS_ZOMBIE prevents other proesses from sending
  504          * signal to the process, to avoid memory leak, we free memory
  505          * for signal queue at the time when the state is set.
  506          */
  507         sigqueue_flush(&p->p_sigqueue);
  508         sigqueue_flush(&td->td_sigqueue);
  509 
  510         /*
  511          * We have to wait until after acquiring all locks before
  512          * changing p_state.  We need to avoid all possible context
  513          * switches (including ones from blocking on a mutex) while
  514          * marked as a zombie.  We also have to set the zombie state
  515          * before we release the parent process' proc lock to avoid
  516          * a lost wakeup.  So, we first call wakeup, then we grab the
  517          * sched lock, update the state, and release the parent process'
  518          * proc lock.
  519          */
  520         wakeup(p->p_pptr);
  521         cv_broadcast(&p->p_pwait);
  522         sched_exit(p->p_pptr, td);
  523         PROC_SLOCK(p);
  524         p->p_state = PRS_ZOMBIE;
  525         PROC_UNLOCK(p->p_pptr);
  526 
  527         /*
  528          * Hopefully no one will try to deliver a signal to the process this
  529          * late in the game.
  530          */
  531         knlist_destroy(&p->p_klist);
  532 
  533         /*
  534          * Save our children's rusage information in our exit rusage.
  535          */
  536         ruadd(&p->p_ru, &p->p_rux, &p->p_stats->p_cru, &p->p_crux);
  537 
  538         /*
  539          * Make sure the scheduler takes this thread out of its tables etc.
  540          * This will also release this thread's reference to the ucred.
  541          * Other thread parts to release include pcb bits and such.
  542          */
  543         thread_exit();
  544 }
  545 
  546 
  547 #ifndef _SYS_SYSPROTO_H_
  548 struct abort2_args {
  549         char *why;
  550         int nargs;
  551         void **args;
  552 };
  553 #endif
  554 
  555 int
  556 abort2(struct thread *td, struct abort2_args *uap)
  557 {
  558         struct proc *p = td->td_proc;
  559         struct sbuf *sb;
  560         void *uargs[16];
  561         int error, i, sig;
  562 
  563         /*
  564          * Do it right now so we can log either proper call of abort2(), or
  565          * note, that invalid argument was passed. 512 is big enough to
  566          * handle 16 arguments' descriptions with additional comments.
  567          */
  568         sb = sbuf_new(NULL, NULL, 512, SBUF_FIXEDLEN);
  569         sbuf_clear(sb);
  570         sbuf_printf(sb, "%s(pid %d uid %d) aborted: ",
  571             p->p_comm, p->p_pid, td->td_ucred->cr_uid);
  572         /* 
  573          * Since we can't return from abort2(), send SIGKILL in cases, where
  574          * abort2() was called improperly
  575          */
  576         sig = SIGKILL;
  577         /* Prevent from DoSes from user-space. */
  578         if (uap->nargs < 0 || uap->nargs > 16)
  579                 goto out;
  580         if (uap->nargs > 0) {
  581                 if (uap->args == NULL)
  582                         goto out;
  583                 error = copyin(uap->args, uargs, uap->nargs * sizeof(void *));
  584                 if (error != 0)
  585                         goto out;
  586         }
  587         /*
  588          * Limit size of 'reason' string to 128. Will fit even when
  589          * maximal number of arguments was chosen to be logged.
  590          */
  591         if (uap->why != NULL) {
  592                 error = sbuf_copyin(sb, uap->why, 128);
  593                 if (error < 0)
  594                         goto out;
  595         } else {
  596                 sbuf_printf(sb, "(null)");
  597         }
  598         if (uap->nargs > 0) {
  599                 sbuf_printf(sb, "(");
  600                 for (i = 0;i < uap->nargs; i++)
  601                         sbuf_printf(sb, "%s%p", i == 0 ? "" : ", ", uargs[i]);
  602                 sbuf_printf(sb, ")");
  603         }
  604         /*
  605          * Final stage: arguments were proper, string has been
  606          * successfully copied from userspace, and copying pointers
  607          * from user-space succeed.
  608          */
  609         sig = SIGABRT;
  610 out:
  611         if (sig == SIGKILL) {
  612                 sbuf_trim(sb);
  613                 sbuf_printf(sb, " (Reason text inaccessible)");
  614         }
  615         sbuf_cat(sb, "\n");
  616         sbuf_finish(sb);
  617         log(LOG_INFO, "%s", sbuf_data(sb));
  618         sbuf_delete(sb);
  619         exit1(td, W_EXITCODE(0, sig));
  620         return (0);
  621 }
  622 
  623 
  624 #ifdef COMPAT_43
  625 /*
  626  * The dirty work is handled by kern_wait().
  627  */
  628 int
  629 owait(struct thread *td, struct owait_args *uap __unused)
  630 {
  631         int error, status;
  632 
  633         error = kern_wait(td, WAIT_ANY, &status, 0, NULL);
  634         if (error == 0)
  635                 td->td_retval[1] = status;
  636         return (error);
  637 }
  638 #endif /* COMPAT_43 */
  639 
  640 /*
  641  * The dirty work is handled by kern_wait().
  642  */
  643 int
  644 wait4(struct thread *td, struct wait_args *uap)
  645 {
  646         struct rusage ru, *rup;
  647         int error, status;
  648 
  649         if (uap->rusage != NULL)
  650                 rup = &ru;
  651         else
  652                 rup = NULL;
  653         error = kern_wait(td, uap->pid, &status, uap->options, rup);
  654         if (uap->status != NULL && error == 0)
  655                 error = copyout(&status, uap->status, sizeof(status));
  656         if (uap->rusage != NULL && error == 0)
  657                 error = copyout(&ru, uap->rusage, sizeof(struct rusage));
  658         return (error);
  659 }
  660 
  661 /*
  662  * Reap the remains of a zombie process and optionally return status and
  663  * rusage.  Asserts and will release both the proctree_lock and the process
  664  * lock as part of its work.
  665  */
  666 static void
  667 proc_reap(struct thread *td, struct proc *p, int *status, int options,
  668     struct rusage *rusage)
  669 {
  670         struct proc *q, *t;
  671 
  672         sx_assert(&proctree_lock, SA_XLOCKED);
  673         PROC_LOCK_ASSERT(p, MA_OWNED);
  674         PROC_SLOCK_ASSERT(p, MA_OWNED);
  675         KASSERT(p->p_state == PRS_ZOMBIE, ("proc_reap: !PRS_ZOMBIE"));
  676 
  677         q = td->td_proc;
  678         if (rusage) {
  679                 *rusage = p->p_ru;
  680                 calcru(p, &rusage->ru_utime, &rusage->ru_stime);
  681         }
  682         PROC_SUNLOCK(p);
  683         td->td_retval[0] = p->p_pid;
  684         if (status)
  685                 *status = p->p_xstat;   /* convert to int */
  686         if (options & WNOWAIT) {
  687                 /*
  688                  *  Only poll, returning the status.  Caller does not wish to
  689                  * release the proc struct just yet.
  690                  */
  691                 PROC_UNLOCK(p);
  692                 sx_xunlock(&proctree_lock);
  693                 return;
  694         }
  695 
  696         PROC_LOCK(q);
  697         sigqueue_take(p->p_ksi);
  698         PROC_UNLOCK(q);
  699         PROC_UNLOCK(p);
  700 
  701         /*
  702          * If we got the child via a ptrace 'attach', we need to give it back
  703          * to the old parent.
  704          */
  705         if (p->p_oppid && (t = pfind(p->p_oppid)) != NULL) {
  706                 PROC_LOCK(p);
  707                 p->p_oppid = 0;
  708                 proc_reparent(p, t);
  709                 PROC_UNLOCK(p);
  710                 tdsignal(t, NULL, SIGCHLD, p->p_ksi);
  711                 wakeup(t);
  712                 cv_broadcast(&p->p_pwait);
  713                 PROC_UNLOCK(t);
  714                 sx_xunlock(&proctree_lock);
  715                 return;
  716         }
  717 
  718         /*
  719          * Remove other references to this process to ensure we have an
  720          * exclusive reference.
  721          */
  722         sx_xlock(&allproc_lock);
  723         LIST_REMOVE(p, p_list); /* off zombproc */
  724         sx_xunlock(&allproc_lock);
  725         LIST_REMOVE(p, p_sibling);
  726         leavepgrp(p);
  727         sx_xunlock(&proctree_lock);
  728 
  729         /*
  730          * As a side effect of this lock, we know that all other writes to
  731          * this proc are visible now, so no more locking is needed for p.
  732          */
  733         PROC_LOCK(p);
  734         p->p_xstat = 0;         /* XXX: why? */
  735         PROC_UNLOCK(p);
  736         PROC_LOCK(q);
  737         ruadd(&q->p_stats->p_cru, &q->p_crux, &p->p_ru, &p->p_rux);
  738         PROC_UNLOCK(q);
  739 
  740         /*
  741          * Decrement the count of procs running with this uid.
  742          */
  743         (void)chgproccnt(p->p_ucred->cr_ruidinfo, -1, 0);
  744 
  745         /*
  746          * Free credentials, arguments, and sigacts.
  747          */
  748         crfree(p->p_ucred);
  749         p->p_ucred = NULL;
  750         pargs_drop(p->p_args);
  751         p->p_args = NULL;
  752         sigacts_free(p->p_sigacts);
  753         p->p_sigacts = NULL;
  754 
  755         /*
  756          * Do any thread-system specific cleanups.
  757          */
  758         thread_wait(p);
  759 
  760         /*
  761          * Give vm and machine-dependent layer a chance to free anything that
  762          * cpu_exit couldn't release while still running in process context.
  763          */
  764         vm_waitproc(p);
  765 #ifdef MAC
  766         mac_proc_destroy(p);
  767 #endif
  768         KASSERT(FIRST_THREAD_IN_PROC(p),
  769             ("proc_reap: no residual thread!"));
  770         uma_zfree(proc_zone, p);
  771         sx_xlock(&allproc_lock);
  772         nprocs--;
  773         sx_xunlock(&allproc_lock);
  774 }
  775 
  776 int
  777 kern_wait(struct thread *td, pid_t pid, int *status, int options,
  778     struct rusage *rusage)
  779 {
  780         struct proc *p, *q;
  781         int error, nfound;
  782 
  783         AUDIT_ARG_PID(pid);
  784         AUDIT_ARG_VALUE(options);
  785 
  786         q = td->td_proc;
  787         if (pid == 0) {
  788                 PROC_LOCK(q);
  789                 pid = -q->p_pgid;
  790                 PROC_UNLOCK(q);
  791         }
  792         if (options &~ (WUNTRACED|WNOHANG|WCONTINUED|WNOWAIT|WLINUXCLONE))
  793                 return (EINVAL);
  794 loop:
  795         if (q->p_flag & P_STATCHILD) {
  796                 PROC_LOCK(q);
  797                 q->p_flag &= ~P_STATCHILD;
  798                 PROC_UNLOCK(q);
  799         }
  800         nfound = 0;
  801         sx_xlock(&proctree_lock);
  802         LIST_FOREACH(p, &q->p_children, p_sibling) {
  803                 PROC_LOCK(p);
  804                 if (pid != WAIT_ANY &&
  805                     p->p_pid != pid && p->p_pgid != -pid) {
  806                         PROC_UNLOCK(p);
  807                         continue;
  808                 }
  809                 if (p_canwait(td, p)) {
  810                         PROC_UNLOCK(p);
  811                         continue;
  812                 }
  813 
  814                 /*
  815                  * This special case handles a kthread spawned by linux_clone
  816                  * (see linux_misc.c).  The linux_wait4 and linux_waitpid
  817                  * functions need to be able to distinguish between waiting
  818                  * on a process and waiting on a thread.  It is a thread if
  819                  * p_sigparent is not SIGCHLD, and the WLINUXCLONE option
  820                  * signifies we want to wait for threads and not processes.
  821                  */
  822                 if ((p->p_sigparent != SIGCHLD) ^
  823                     ((options & WLINUXCLONE) != 0)) {
  824                         PROC_UNLOCK(p);
  825                         continue;
  826                 }
  827 
  828                 nfound++;
  829                 PROC_SLOCK(p);
  830                 if (p->p_state == PRS_ZOMBIE) {
  831                         proc_reap(td, p, status, options, rusage);
  832                         return (0);
  833                 }
  834                 if ((p->p_flag & P_STOPPED_SIG) &&
  835                     (p->p_suspcount == p->p_numthreads) &&
  836                     (p->p_flag & P_WAITED) == 0 &&
  837                     (p->p_flag & P_TRACED || options & WUNTRACED)) {
  838                         PROC_SUNLOCK(p);
  839                         p->p_flag |= P_WAITED;
  840                         sx_xunlock(&proctree_lock);
  841                         td->td_retval[0] = p->p_pid;
  842                         if (status)
  843                                 *status = W_STOPCODE(p->p_xstat);
  844 
  845                         PROC_LOCK(q);
  846                         sigqueue_take(p->p_ksi);
  847                         PROC_UNLOCK(q);
  848                         PROC_UNLOCK(p);
  849 
  850                         return (0);
  851                 }
  852                 PROC_SUNLOCK(p);
  853                 if (options & WCONTINUED && (p->p_flag & P_CONTINUED)) {
  854                         sx_xunlock(&proctree_lock);
  855                         td->td_retval[0] = p->p_pid;
  856                         p->p_flag &= ~P_CONTINUED;
  857 
  858                         PROC_LOCK(q);
  859                         sigqueue_take(p->p_ksi);
  860                         PROC_UNLOCK(q);
  861                         PROC_UNLOCK(p);
  862 
  863                         if (status)
  864                                 *status = SIGCONT;
  865                         return (0);
  866                 }
  867                 PROC_UNLOCK(p);
  868         }
  869         if (nfound == 0) {
  870                 sx_xunlock(&proctree_lock);
  871                 return (ECHILD);
  872         }
  873         if (options & WNOHANG) {
  874                 sx_xunlock(&proctree_lock);
  875                 td->td_retval[0] = 0;
  876                 return (0);
  877         }
  878         PROC_LOCK(q);
  879         sx_xunlock(&proctree_lock);
  880         if (q->p_flag & P_STATCHILD) {
  881                 q->p_flag &= ~P_STATCHILD;
  882                 error = 0;
  883         } else
  884                 error = msleep(q, &q->p_mtx, PWAIT | PCATCH, "wait", 0);
  885         PROC_UNLOCK(q);
  886         if (error)
  887                 return (error); 
  888         goto loop;
  889 }
  890 
  891 /*
  892  * Make process 'parent' the new parent of process 'child'.
  893  * Must be called with an exclusive hold of proctree lock.
  894  */
  895 void
  896 proc_reparent(struct proc *child, struct proc *parent)
  897 {
  898 
  899         sx_assert(&proctree_lock, SX_XLOCKED);
  900         PROC_LOCK_ASSERT(child, MA_OWNED);
  901         if (child->p_pptr == parent)
  902                 return;
  903 
  904         PROC_LOCK(child->p_pptr);
  905         sigqueue_take(child->p_ksi);
  906         PROC_UNLOCK(child->p_pptr);
  907         LIST_REMOVE(child, p_sibling);
  908         LIST_INSERT_HEAD(&parent->p_children, child, p_sibling);
  909         child->p_pptr = parent;
  910 }

Cache object: c7b6d5e9cbc3aba75429dcceaaf73c71


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.