2  * Copyright (c) 2000-2016 Apple Inc. All rights reserved. 
   4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 
   6  * This file contains Original Code and/or Modifications of Original Code 
   7  * as defined in and that are subject to the Apple Public Source License 
   8  * Version 2.0 (the 'License'). You may not use this file except in 
   9  * compliance with the License. The rights granted to you under the License 
  10  * may not be used to create, or enable the creation or redistribution of, 
  11  * unlawful or unlicensed copies of an Apple operating system, or to 
  12  * circumvent, violate, or enable the circumvention or violation of, any 
  13  * terms of an Apple operating system software license agreement. 
  15  * Please obtain a copy of the License at 
  16  * http://www.opensource.apple.com/apsl/ and read it before using this file. 
  18  * The Original Code and all software distributed under the License are 
  19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 
  22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  23  * Please see the License for the specific language governing rights and 
  24  * limitations under the License. 
  26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 
  28 /* Copyright (c) 1995, 1997 Apple Computer, Inc. All Rights Reserved */ 
  30  * Copyright (c) 1982, 1986, 1989, 1991, 1993 
  31  *      The Regents of the University of California.  All rights reserved. 
  32  * (c) UNIX System Laboratories, Inc. 
  33  * All or some portions of this file are derived from material licensed 
  34  * to the University of California by American Telephone and Telegraph 
  35  * Co. or Unix System Laboratories, Inc. and are reproduced herein with 
  36  * the permission of UNIX System Laboratories, Inc. 
  38  * Redistribution and use in source and binary forms, with or without 
  39  * modification, are permitted provided that the following conditions 
  41  * 1. Redistributions of source code must retain the above copyright 
  42  *    notice, this list of conditions and the following disclaimer. 
  43  * 2. Redistributions in binary form must reproduce the above copyright 
  44  *    notice, this list of conditions and the following disclaimer in the 
  45  *    documentation and/or other materials provided with the distribution. 
  46  * 3. All advertising materials mentioning features or use of this software 
  47  *    must display the following acknowledgement: 
  48  *      This product includes software developed by the University of 
  49  *      California, Berkeley and its contributors. 
  50  * 4. Neither the name of the University nor the names of its contributors 
  51  *    may be used to endorse or promote products derived from this software 
  52  *    without specific prior written permission. 
  54  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 
  55  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
  56  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
  57  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 
  58  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
  59  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
  60  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
  61  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
  62  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
  63  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
  66  *      @(#)kern_exit.c 8.7 (Berkeley) 2/12/94 
  69  * NOTICE: This file was modified by SPARTA, Inc. in 2005 to introduce 
  70  * support for mandatory and extensible security protections.  This notice 
  71  * is included in support of clause 2.2 (b) of the Apple Public License, 
  75 #include <machine/reg.h> 
  76 #include <machine/psl.h> 
  78 #include "compat_43.h" 
  80 #include <sys/param.h> 
  81 #include <sys/systm.h> 
  82 #include <sys/ioctl.h> 
  83 #include <sys/proc_internal.h> 
  85 #include <sys/kauth.h> 
  88 #include <sys/resource.h> 
  89 #include <sys/kernel.h> 
  91 #include <sys/file_internal.h> 
  92 #include <sys/vnode_internal.h> 
  93 #include <sys/syslog.h> 
  94 #include <sys/malloc.h> 
  95 #include <sys/resourcevar.h> 
  96 #include <sys/ptrace.h> 
  97 #include <sys/proc_info.h> 
  98 #include <sys/reason.h> 
  99 #include <sys/_types/_timeval64.h> 
 100 #include <sys/user.h> 
 101 #include <sys/aio_kern.h> 
 102 #include <sys/sysproto.h> 
 103 #include <sys/signalvar.h> 
 104 #include <sys/kdebug.h> 
 105 #include <sys/filedesc.h>       /* fdfree */ 
 107 #include <sys/shm_internal.h>   /* shmexit */ 
 109 #include <sys/acct.h>           /* acct_process */ 
 111 #include <sys/persona.h> 
 114 #include <security/audit/audit.h> 
 115 #include <bsm/audit_kevents.h> 
 117 #include <mach/mach_types.h> 
 118 #include <kern/exc_resource.h> 
 120 #include <kern/kern_types.h> 
 121 #include <kern/kalloc.h> 
 122 #include <kern/task.h> 
 123 #include <corpses/task_corpse.h> 
 124 #include <kern/thread.h> 
 125 #include <kern/thread_call.h> 
 126 #include <kern/sched_prim.h> 
 127 #include <kern/assert.h> 
 128 #include <kern/policy_internal.h> 
 130 #include <sys/codesign.h> 
 132 #if CONFIG_MEMORYSTATUS 
 133 #include <sys/kern_memorystatus.h> 
 137 /* Do not include dtrace.h, it redefines kmem_[alloc/free] */ 
 138 void dtrace_proc_exit(proc_t p
); 
 140 #include <sys/dtrace_ptss.h> 
 144 #include <security/mac.h> 
 145 #include <security/mac_mach_internal.h> 
 146 #include <sys/syscall.h> 
 149 #include <mach/mach_types.h> 
 150 #include <mach/task.h> 
 151 #include <mach/thread_act.h> 
 153 #include <vm/vm_protos.h> 
 157 void proc_prepareexit(proc_t p
, int rv
, boolean_t perf_notify
); 
 158 void gather_populate_corpse_crashinfo(proc_t p
, void *crash_info_ptr
, mach_exception_data_type_t code
, mach_exception_data_type_t subcode
, uint64_t *udata_buffer
, int num_udata
); 
 159 mach_exception_data_type_t 
proc_encode_exit_exception_code(proc_t p
); 
 160 void vfork_exit(proc_t p
, int rv
); 
 161 void vproc_exit(proc_t p
); 
 162 __private_extern__ 
void munge_user64_rusage(struct rusage 
*a_rusage_p
, struct user64_rusage 
*a_user_rusage_p
); 
 163 __private_extern__ 
void munge_user32_rusage(struct rusage 
*a_rusage_p
, struct user32_rusage 
*a_user_rusage_p
); 
 164 static int reap_child_locked(proc_t parent
, proc_t child
, int deadparent
, int reparentedtoinit
, int locked
, int droplock
); 
 165 static void populate_corpse_crashinfo(proc_t p
, void *crash_info_ptr
, struct rusage_superset 
*rup
, mach_exception_data_type_t code
, mach_exception_data_type_t subcode
, uint64_t *udata_buffer
, int num_udata
); 
 166 static void proc_update_corpse_exception_codes(proc_t p
, mach_exception_data_type_t 
*code
, mach_exception_data_type_t 
*subcode
); 
 167 extern int proc_pidpathinfo_internal(proc_t p
, uint64_t arg
, char *buffer
, uint32_t buffersize
, int32_t *retval
); 
 168 static void abort_with_payload_internal(proc_t p
, uint32_t reason_namespace
, uint64_t reason_code
, user_addr_t payload
, 
 169                                                                         uint32_t payload_size
, user_addr_t reason_string
, uint64_t reason_flags
); 
 171 static __attribute__((noinline
)) void launchd_crashed_panic(proc_t p
, int rv
); 
 172 extern void proc_piduniqidentifierinfo(proc_t p
, struct proc_uniqidentifierinfo 
*p_uniqidinfo
); 
 173 extern void task_coalition_ids(task_t task
, uint64_t ids
[COALITION_NUM_TYPES
]); 
 174 extern uint64_t get_task_phys_footprint_limit(task_t
); 
 175 int proc_list_uptrs(void *p
, uint64_t *udata_buffer
, int size
); 
 179  * Things which should have prototypes in headers, but don't 
 181 void    proc_exit(proc_t p
); 
 182 int     wait1continue(int result
); 
 183 int     waitidcontinue(int result
); 
 184 kern_return_t 
sys_perf_notify(thread_t thread
, int pid
); 
 185 kern_return_t 
task_exception_notify(exception_type_t exception
, 
 186         mach_exception_data_type_t code
, mach_exception_data_type_t subcode
); 
 188 void gather_rusage_info(proc_t p
, rusage_info_current 
*ru
, int flavor
); 
 191  * NOTE: Source and target may *NOT* overlap! 
 192  * XXX Should share code with bsd/dev/ppc/unix_signal.c 
 195 siginfo_user_to_user32(user_siginfo_t 
*in
, user32_siginfo_t 
*out
) 
 197         out
->si_signo   
= in
->si_signo
; 
 198         out
->si_errno   
= in
->si_errno
; 
 199         out
->si_code    
= in
->si_code
; 
 200         out
->si_pid     
= in
->si_pid
; 
 201         out
->si_uid     
= in
->si_uid
; 
 202         out
->si_status  
= in
->si_status
; 
 203         out
->si_addr    
= CAST_DOWN_EXPLICIT(user32_addr_t
,in
->si_addr
); 
 204         /* following cast works for sival_int because of padding */ 
 205         out
->si_value
.sival_ptr 
= CAST_DOWN_EXPLICIT(user32_addr_t
,in
->si_value
.sival_ptr
); 
 206         out
->si_band    
= in
->si_band
;                  /* range reduction */ 
 210 siginfo_user_to_user64(user_siginfo_t 
*in
, user64_siginfo_t 
*out
) 
 212         out
->si_signo   
= in
->si_signo
; 
 213         out
->si_errno   
= in
->si_errno
; 
 214         out
->si_code    
= in
->si_code
; 
 215         out
->si_pid     
= in
->si_pid
; 
 216         out
->si_uid     
= in
->si_uid
; 
 217         out
->si_status  
= in
->si_status
; 
 218         out
->si_addr    
= in
->si_addr
; 
 219         /* following cast works for sival_int because of padding */ 
 220         out
->si_value
.sival_ptr 
= in
->si_value
.sival_ptr
; 
 221         out
->si_band    
= in
->si_band
;                  /* range reduction */ 
 225 copyoutsiginfo(user_siginfo_t 
*native
, boolean_t is64
, user_addr_t uaddr
) 
 228                 user64_siginfo_t sinfo64
; 
 230                 bzero(&sinfo64
, sizeof (sinfo64
)); 
 231                 siginfo_user_to_user64(native
, &sinfo64
); 
 232                 return (copyout(&sinfo64
, uaddr
, sizeof (sinfo64
))); 
 234                 user32_siginfo_t sinfo32
; 
 236                 bzero(&sinfo32
, sizeof (sinfo32
)); 
 237                 siginfo_user_to_user32(native
, &sinfo32
); 
 238                 return (copyout(&sinfo32
, uaddr
, sizeof (sinfo32
))); 
 242 void gather_populate_corpse_crashinfo(proc_t p
, void *crash_info_ptr
, mach_exception_data_type_t code
, mach_exception_data_type_t subcode
, uint64_t *udata_buffer
, int num_udata
) 
 244         struct rusage_superset rup
; 
 246         gather_rusage_info(p
, &rup
.ri
, RUSAGE_INFO_CURRENT
); 
 247         rup
.ri
.ri_phys_footprint 
= 0; 
 248         populate_corpse_crashinfo(p
, crash_info_ptr
, &rup
, code
, subcode
, udata_buffer
, num_udata
); 
 251 static void proc_update_corpse_exception_codes(proc_t p
, mach_exception_data_type_t 
*code
, mach_exception_data_type_t 
*subcode
) 
 253         mach_exception_data_type_t code_update 
= *code
; 
 254         mach_exception_data_type_t subcode_update 
= *subcode
; 
 255         if (p
->p_exit_reason 
== OS_REASON_NULL
) { 
 259         switch (p
->p_exit_reason
->osr_namespace
) { 
 260                 case OS_REASON_JETSAM
: 
 261                         if (p
->p_exit_reason
->osr_code 
== JETSAM_REASON_MEMORY_PERPROCESSLIMIT
) { 
 262                                 /* Update the code with EXC_RESOURCE code for high memory watermark */ 
 263                                 EXC_RESOURCE_ENCODE_TYPE(code_update
, RESOURCE_TYPE_MEMORY
); 
 264                                 EXC_RESOURCE_ENCODE_FLAVOR(code_update
, FLAVOR_HIGH_WATERMARK
); 
 265                                 EXC_RESOURCE_HWM_ENCODE_LIMIT(code_update
, ((get_task_phys_footprint_limit(p
->task
)) >> 20)); 
 276         *subcode 
= subcode_update
; 
 280 mach_exception_data_type_t 
proc_encode_exit_exception_code(proc_t p
) 
 282         uint64_t subcode 
= 0; 
 284         if (p
->p_exit_reason 
== OS_REASON_NULL
) { 
 288         /* Embed first 32 bits of osr_namespace and osr_code in exception code */ 
 289         ENCODE_OSR_NAMESPACE_TO_MACH_EXCEPTION_CODE(subcode
, p
->p_exit_reason
->osr_namespace
); 
 290         ENCODE_OSR_CODE_TO_MACH_EXCEPTION_CODE(subcode
, p
->p_exit_reason
->osr_code
); 
 291         return (mach_exception_data_type_t
)subcode
; 
 294 static void populate_corpse_crashinfo(proc_t p
, void *crash_info_ptr
, struct rusage_superset 
*rup
, mach_exception_data_type_t code
, mach_exception_data_type_t subcode
, uint64_t *udata_buffer
, int num_udata
) 
 296         mach_vm_address_t uaddr 
= 0; 
 297         mach_exception_data_type_t exc_codes
[EXCEPTION_CODE_MAX
]; 
 299         exc_codes
[1] = subcode
; 
 301         struct proc_uniqidentifierinfo p_uniqidinfo
; 
 302         struct proc_workqueueinfo pwqinfo
; 
 304         uint64_t crashed_threadid 
= thread_tid(current_thread()); 
 305         unsigned int pflags 
= 0; 
 306         uint64_t max_footprint_mb
; 
 307         uint64_t max_footprint
; 
 309 #if CONFIG_MEMORYSTATUS 
 310         int memstat_dirty_flags 
= 0; 
 313         if (KERN_SUCCESS 
== kcdata_get_memory_addr(crash_info_ptr
, TASK_CRASHINFO_EXCEPTION_CODES
, sizeof(exc_codes
), &uaddr
)) { 
 314                 kcdata_memcpy(crash_info_ptr
, uaddr
, exc_codes
, sizeof(exc_codes
)); 
 317         if (KERN_SUCCESS 
== kcdata_get_memory_addr(crash_info_ptr
, TASK_CRASHINFO_PID
, sizeof(p
->p_pid
), &uaddr
)) { 
 318                 kcdata_memcpy(crash_info_ptr
, uaddr
, &p
->p_pid
, sizeof(p
->p_pid
)); 
 321         if (KERN_SUCCESS 
== kcdata_get_memory_addr(crash_info_ptr
, TASK_CRASHINFO_PPID
, sizeof(p
->p_ppid
), &uaddr
)) { 
 322                 kcdata_memcpy(crash_info_ptr
, uaddr
, &p
->p_ppid
, sizeof(p
->p_ppid
)); 
 325         if (KERN_SUCCESS 
== kcdata_get_memory_addr(crash_info_ptr
, TASK_CRASHINFO_CRASHED_THREADID
, sizeof(uint64_t), &uaddr
)) { 
 326                 kcdata_memcpy(crash_info_ptr
, uaddr
, &crashed_threadid
, sizeof(uint64_t)); 
 330             kcdata_get_memory_addr(crash_info_ptr
, TASK_CRASHINFO_BSDINFOWITHUNIQID
, sizeof(struct proc_uniqidentifierinfo
), &uaddr
)) { 
 331                 proc_piduniqidentifierinfo(p
, &p_uniqidinfo
); 
 332                 kcdata_memcpy(crash_info_ptr
, uaddr
, &p_uniqidinfo
, sizeof(struct proc_uniqidentifierinfo
)); 
 335         if (KERN_SUCCESS 
== kcdata_get_memory_addr(crash_info_ptr
, TASK_CRASHINFO_RUSAGE_INFO
, sizeof(rusage_info_current
), &uaddr
)) { 
 336                 kcdata_memcpy(crash_info_ptr
, uaddr
, &rup
->ri
, sizeof(rusage_info_current
)); 
 339         if (KERN_SUCCESS 
== kcdata_get_memory_addr(crash_info_ptr
, TASK_CRASHINFO_PROC_CSFLAGS
, sizeof(p
->p_csflags
), &uaddr
)) { 
 340                 kcdata_memcpy(crash_info_ptr
, uaddr
, &p
->p_csflags
, sizeof(p
->p_csflags
)); 
 343         if (KERN_SUCCESS 
== kcdata_get_memory_addr(crash_info_ptr
, TASK_CRASHINFO_PROC_NAME
, sizeof(p
->p_comm
), &uaddr
)) { 
 344                 kcdata_memcpy(crash_info_ptr
, uaddr
, &p
->p_comm
, sizeof(p
->p_comm
)); 
 347         if (KERN_SUCCESS 
== kcdata_get_memory_addr(crash_info_ptr
, TASK_CRASHINFO_PROC_STARTTIME
, sizeof(p
->p_start
), &uaddr
)) { 
 348                 struct timeval64 t64
; 
 349                 t64
.tv_sec 
= (int64_t)p
->p_start
.tv_sec
; 
 350                 t64
.tv_usec 
= (int64_t)p
->p_start
.tv_usec
; 
 351                 kcdata_memcpy(crash_info_ptr
, uaddr
, &t64
, sizeof(t64
)); 
 354         if (KERN_SUCCESS 
== kcdata_get_memory_addr(crash_info_ptr
, TASK_CRASHINFO_USERSTACK
, sizeof(p
->user_stack
), &uaddr
)) { 
 355                 kcdata_memcpy(crash_info_ptr
, uaddr
, &p
->user_stack
, sizeof(p
->user_stack
)); 
 358         if (KERN_SUCCESS 
== kcdata_get_memory_addr(crash_info_ptr
, TASK_CRASHINFO_ARGSLEN
, sizeof(p
->p_argslen
), &uaddr
)) { 
 359                 kcdata_memcpy(crash_info_ptr
, uaddr
, &p
->p_argslen
, sizeof(p
->p_argslen
)); 
 362         if (KERN_SUCCESS 
== kcdata_get_memory_addr(crash_info_ptr
, TASK_CRASHINFO_PROC_ARGC
, sizeof(p
->p_argc
), &uaddr
)) { 
 363                 kcdata_memcpy(crash_info_ptr
, uaddr
, &p
->p_argc
, sizeof(p
->p_argc
)); 
 366         if (KERN_SUCCESS 
== kcdata_get_memory_addr(crash_info_ptr
, TASK_CRASHINFO_PROC_PATH
, MAXPATHLEN
, &uaddr
)) { 
 367                 char *buf 
= (char *) kalloc(MAXPATHLEN
); 
 369                         bzero(buf
, MAXPATHLEN
); 
 370                         proc_pidpathinfo_internal(p
, 0, buf
, MAXPATHLEN
, &retval
); 
 371                         kcdata_memcpy(crash_info_ptr
, uaddr
, buf
, MAXPATHLEN
); 
 372                         kfree(buf
, MAXPATHLEN
); 
 376         pflags 
= p
->p_flag 
& (P_LP64 
| P_SUGID
); 
 377         if (KERN_SUCCESS 
== kcdata_get_memory_addr(crash_info_ptr
, TASK_CRASHINFO_PROC_FLAGS
, sizeof(pflags
), &uaddr
)) { 
 378                 kcdata_memcpy(crash_info_ptr
, uaddr
, &pflags
, sizeof(pflags
)); 
 381         if (KERN_SUCCESS 
== kcdata_get_memory_addr(crash_info_ptr
, TASK_CRASHINFO_UID
, sizeof(p
->p_uid
), &uaddr
)) { 
 382                 kcdata_memcpy(crash_info_ptr
, uaddr
, &p
->p_uid
, sizeof(p
->p_uid
)); 
 385         if (KERN_SUCCESS 
== kcdata_get_memory_addr(crash_info_ptr
, TASK_CRASHINFO_GID
, sizeof(p
->p_gid
), &uaddr
)) { 
 386                 kcdata_memcpy(crash_info_ptr
, uaddr
, &p
->p_gid
, sizeof(p
->p_gid
)); 
 389         cputype 
= cpu_type() & ~CPU_ARCH_MASK
; 
 390         if (IS_64BIT_PROCESS(p
)) 
 391                 cputype 
|= CPU_ARCH_ABI64
; 
 393         if (KERN_SUCCESS 
== kcdata_get_memory_addr(crash_info_ptr
, TASK_CRASHINFO_CPUTYPE
, sizeof(cpu_type_t
), &uaddr
)) { 
 394                 kcdata_memcpy(crash_info_ptr
, uaddr
, &cputype
, sizeof(cpu_type_t
)); 
 397         if (KERN_SUCCESS 
== kcdata_get_memory_addr(crash_info_ptr
, TASK_CRASHINFO_MEMORY_LIMIT
, sizeof(max_footprint_mb
), &uaddr
)) { 
 398                 max_footprint 
= get_task_phys_footprint_limit(p
->task
); 
 399                 max_footprint_mb 
= max_footprint 
>> 20; 
 400                 kcdata_memcpy(crash_info_ptr
, uaddr
, &max_footprint_mb
, sizeof(max_footprint_mb
)); 
 403         bzero(&pwqinfo
, sizeof(struct proc_workqueueinfo
)); 
 404         retval 
= fill_procworkqueue(p
, &pwqinfo
); 
 406                 if (KERN_SUCCESS 
== kcdata_get_memory_addr(crash_info_ptr
, TASK_CRASHINFO_WORKQUEUEINFO
, sizeof(struct proc_workqueueinfo
), &uaddr
)) { 
 407                         kcdata_memcpy(crash_info_ptr
, uaddr
, &pwqinfo
, sizeof(struct proc_workqueueinfo
)); 
 411         if (KERN_SUCCESS 
== kcdata_get_memory_addr(crash_info_ptr
, TASK_CRASHINFO_RESPONSIBLE_PID
, sizeof(p
->p_responsible_pid
), &uaddr
)) { 
 412                 kcdata_memcpy(crash_info_ptr
, uaddr
, &p
->p_responsible_pid
, sizeof(p
->p_responsible_pid
)); 
 415 #if CONFIG_COALITIONS 
 416         if (KERN_SUCCESS 
== kcdata_get_memory_addr_for_array(crash_info_ptr
, TASK_CRASHINFO_COALITION_ID
, sizeof(uint64_t), COALITION_NUM_TYPES
, &uaddr
)) { 
 417                 uint64_t coalition_ids
[COALITION_NUM_TYPES
]; 
 418                 task_coalition_ids(p
->task
, coalition_ids
); 
 419                 kcdata_memcpy(crash_info_ptr
, uaddr
, coalition_ids
, sizeof(coalition_ids
)); 
 421 #endif /* CONFIG_COALITIONS */ 
 423 #if CONFIG_MEMORYSTATUS 
 424         memstat_dirty_flags 
= memorystatus_dirty_get(p
); 
 425         if (KERN_SUCCESS 
== kcdata_get_memory_addr(crash_info_ptr
, TASK_CRASHINFO_DIRTY_FLAGS
, sizeof(memstat_dirty_flags
), &uaddr
)) { 
 426                 kcdata_memcpy(crash_info_ptr
, uaddr
, &memstat_dirty_flags
, sizeof(memstat_dirty_flags
)); 
 430         if (p
->p_exit_reason 
!= OS_REASON_NULL
) { 
 431                 if (KERN_SUCCESS 
== kcdata_get_memory_addr(crash_info_ptr
, EXIT_REASON_SNAPSHOT
, sizeof(struct exit_reason_snapshot
), &uaddr
)) { 
 432                         struct exit_reason_snapshot ers 
= { 
 433                                 .ers_namespace 
= p
->p_exit_reason
->osr_namespace
, 
 434                                 .ers_code 
= p
->p_exit_reason
->osr_code
, 
 435                                 .ers_flags 
= p
->p_exit_reason
->osr_flags
 
 438                         kcdata_memcpy(crash_info_ptr
, uaddr
, &ers
, sizeof(ers
)); 
 441                 if (p
->p_exit_reason
->osr_kcd_buf 
!= 0) { 
 442                         uint32_t reason_buf_size 
= kcdata_memory_get_used_bytes(&p
->p_exit_reason
->osr_kcd_descriptor
); 
 443                         assert(reason_buf_size 
!= 0); 
 445                         if (KERN_SUCCESS 
== kcdata_get_memory_addr(crash_info_ptr
, KCDATA_TYPE_NESTED_KCDATA
, reason_buf_size
, &uaddr
)) { 
 446                                 kcdata_memcpy(crash_info_ptr
, uaddr
, p
->p_exit_reason
->osr_kcd_buf
, reason_buf_size
); 
 452                 if (KERN_SUCCESS 
== kcdata_get_memory_addr_for_array(crash_info_ptr
, TASK_CRASHINFO_UDATA_PTRS
, 
 453                                         sizeof(uint64_t), num_udata
, &uaddr
)) { 
 454                         kcdata_memcpy(crash_info_ptr
, uaddr
, udata_buffer
, sizeof(uint64_t) * num_udata
); 
 460  * We only parse exit reason kcdata blobs for launchd when it dies 
 461  * and we're going to panic. 
 463  * Meant to be called immediately before panicking. 
 466 launchd_exit_reason_get_string_desc(os_reason_t exit_reason
) 
 470         if (exit_reason 
== OS_REASON_NULL 
|| exit_reason
->osr_kcd_buf 
== NULL 
|| 
 471                         exit_reason
->osr_bufsize 
== 0) { 
 475         iter 
= kcdata_iter(exit_reason
->osr_kcd_buf
, exit_reason
->osr_bufsize
); 
 476         if (!kcdata_iter_valid(iter
)) { 
 477 #if DEBUG || DEVELOPMENT 
 478                 printf("launchd exit reason has invalid exit reason buffer\n"); 
 483         if (kcdata_iter_type(iter
) != KCDATA_BUFFER_BEGIN_OS_REASON
) { 
 484 #if DEBUG || DEVELOPMENT 
 485                 printf("launchd exit reason buffer type mismatch, expected %d got %d\n", 
 486                         KCDATA_BUFFER_BEGIN_OS_REASON
, kcdata_iter_type(iter
)); 
 491         iter 
= kcdata_iter_find_type(iter
, EXIT_REASON_USER_DESC
); 
 492         if (!kcdata_iter_valid(iter
)) { 
 496         return (char *)kcdata_iter_payload(iter
); 
 499 static __attribute__((noinline
)) void 
 500 launchd_crashed_panic(proc_t p
, int rv
) 
 502         char *launchd_exit_reason_desc 
= launchd_exit_reason_get_string_desc(p
->p_exit_reason
); 
 504         if (p
->p_exit_reason 
== OS_REASON_NULL
) { 
 505                 printf("pid 1 exited -- no exit reason available -- (signal %d, exit %d)\n", 
 506                         WTERMSIG(rv
), WEXITSTATUS(rv
)); 
 508                 printf("pid 1 exited -- exit reason namespace %d subcode 0x%llx, description %s\n", 
 509                         p
->p_exit_reason
->osr_namespace
, p
->p_exit_reason
->osr_code
, launchd_exit_reason_desc 
? 
 510                         launchd_exit_reason_desc 
: "none"); 
 513 #if (DEVELOPMENT || DEBUG) && CONFIG_COREDUMP 
 515          * For debugging purposes, generate a core file of initproc before 
 516          * panicking. Leave at least 300 MB free on the root volume, and ignore 
 517          * the process's corefile ulimit. fsync() the file to ensure it lands on disk 
 518          * before the panic hits. 
 522         uint64_t        coredump_start 
= mach_absolute_time(); 
 523         uint64_t        coredump_end
; 
 525         clock_usec_t    tv_usec
; 
 528         err 
= coredump(p
, 300, COREDUMP_IGNORE_ULIMIT 
| COREDUMP_FULLFSYNC
); 
 530         coredump_end 
= mach_absolute_time(); 
 532         absolutetime_to_microtime(coredump_end 
- coredump_start
, &tv_sec
, &tv_usec
); 
 534         tv_msec 
= tv_usec 
/ 1000; 
 537                 printf("Failed to generate initproc core file: error %d, took %d.%03d seconds\n", 
 538                        err
, (uint32_t)tv_sec
, tv_msec
); 
 540                 printf("Generated initproc core file in %d.%03d seconds\n", 
 541                        (uint32_t)tv_sec
, tv_msec
); 
 543 #endif /* (DEVELOPMENT || DEBUG) && CONFIG_COREDUMP */ 
 545         sync(p
, (void *)NULL
, (int *)NULL
); 
 547         if (p
->p_exit_reason 
== OS_REASON_NULL
) { 
 548                 panic_plain(LAUNCHD_CRASHED_PREFIX 
" -- no exit reason available -- (signal %d, exit status %d %s)", 
 549                                 WTERMSIG(rv
), WEXITSTATUS(rv
), ((p
->p_csflags 
& CS_KILLED
) ? "CS_KILLED" : "")); 
 551                 panic_plain(LAUNCHD_CRASHED_PREFIX 
" %s -- exit reason namespace %d subcode 0x%llx description: %." LAUNCHD_PANIC_REASON_STRING_MAXLEN 
"s", 
 552                                 ((p
->p_csflags 
& CS_KILLED
) ? "CS_KILLED" : ""), 
 553                                 p
->p_exit_reason
->osr_namespace
, p
->p_exit_reason
->osr_code
, 
 554                                 launchd_exit_reason_desc 
? launchd_exit_reason_desc 
: "none"); 
 559 abort_with_payload_internal(proc_t p
, uint32_t reason_namespace
, uint64_t reason_code
, user_addr_t payload
, uint32_t payload_size
, 
 560                                 user_addr_t reason_string
, uint64_t reason_flags
) 
 562         os_reason_t exit_reason 
= OS_REASON_NULL
; 
 564         KERNEL_DEBUG_CONSTANT(BSDDBG_CODE(DBG_BSD_PROC
, BSD_PROC_EXITREASON_CREATE
) | DBG_FUNC_NONE
, 
 565                                         p
->p_pid
, reason_namespace
, 
 568         exit_reason 
= build_userspace_exit_reason(reason_namespace
, reason_code
, payload
, payload_size
, reason_string
, 
 572          * We use SIGABRT (rather than calling exit directly from here) so that 
 573          * the debugger can catch abort_with_{reason,payload} calls. 
 575         psignal_try_thread_with_reason(p
, current_thread(), SIGABRT
, exit_reason
); 
 581 abort_with_payload(struct proc 
*cur_proc
, struct abort_with_payload_args 
*args
, 
 582                                 __unused 
void *retval
) 
 584         abort_with_payload_internal(cur_proc
, args
->reason_namespace
, args
->reason_code
, args
->payload
, args
->payload_size
, 
 585                                         args
->reason_string
, args
->reason_flags
); 
 595 __attribute__((noreturn
)) 
 597 exit(proc_t p
, struct exit_args 
*uap
, int *retval
) 
 599         exit1(p
, W_EXITCODE(uap
->rval
, 0), retval
); 
 601         thread_exception_return(); 
 604                 thread_block(THREAD_CONTINUE_NULL
); 
 609  * Exit: deallocate address space and other resources, change proc state 
 610  * to zombie, and unlink proc from allproc and parent's lists.  Save exit 
 611  * status and rusage for wait().  Check for child processes and orphan them. 
 614 exit1(proc_t p
, int rv
, int *retval
) 
 616         return exit1_internal(p
, rv
, retval
, TRUE
, TRUE
, 0); 
 620 exit1_internal(proc_t p
, int rv
, int *retval
, boolean_t thread_can_terminate
, boolean_t perf_notify
, 
 623         return exit_with_reason(p
, rv
, retval
, thread_can_terminate
, perf_notify
, jetsam_flags
, OS_REASON_NULL
); 
 627  * NOTE: exit_with_reason drops a reference on the passed exit_reason 
 630 exit_with_reason(proc_t p
, int rv
, int *retval
, boolean_t thread_can_terminate
, boolean_t perf_notify
, 
 631                 int jetsam_flags
, struct os_reason 
*exit_reason
) 
 633         thread_t self 
= current_thread(); 
 634         struct task 
*task 
= p
->task
; 
 639          * If a thread in this task has already 
 640          * called exit(), then halt any others 
 644          ut 
= get_bsdthread_info(self
); 
 645          if (ut
->uu_flag 
& UT_VFORK
) { 
 646                 os_reason_free(exit_reason
); 
 647                 if (!thread_can_terminate
) { 
 652                 vfork_return(p 
, retval
, p
->p_pid
); 
 653                 unix_syscall_return(0); 
 658          * The parameter list of audit_syscall_exit() was augmented to 
 659          * take the Darwin syscall number as the first parameter, 
 660          * which is currently required by mac_audit_postselect(). 
 664          * The BSM token contains two components: an exit status as passed 
 665          * to exit(), and a return value to indicate what sort of exit it  
 666          * was.  The exit status is WEXITSTATUS(rv), but it's not clear 
 667          * what the return value is. 
 669         AUDIT_ARG(exit
, WEXITSTATUS(rv
), 0); 
 670         AUDIT_SYSCALL_EXIT(SYS_exit
, p
, ut
, 0); /* Exit is always successfull */ 
 672         DTRACE_PROC1(exit
, int, CLD_EXITED
); 
 674         /* mark process is going to exit and pull out of DBG/disk throttle */ 
 675         /* TODO: This should be done after becoming exit thread */ 
 676         proc_set_task_policy(p
->task
, TASK_POLICY_ATTRIBUTE
, 
 677                              TASK_POLICY_TERMINATED
, TASK_POLICY_ENABLE
); 
 680         error 
= proc_transstart(p
, 1, (jetsam_flags 
? 1 : 0)); 
 681         if (error 
== EDEADLK
) { 
 683                  * If proc_transstart() returns EDEADLK, then another thread 
 684                  * is either exec'ing or exiting. Return an error and allow 
 685                  * the other thread to continue. 
 688                 os_reason_free(exit_reason
); 
 689                 if (current_proc() == p
){ 
 690                         if (p
->exit_thread 
== self
) { 
 691                                 printf("exit_thread failed to exit, leaving process %s[%d] in unkillable limbo\n", 
 692                                        p
->p_comm
, p
->p_pid
); 
 695                         if (thread_can_terminate
) { 
 696                                 thread_exception_return(); 
 703         while (p
->exit_thread 
!= self
) { 
 704                 if (sig_try_locked(p
) <= 0) { 
 706                         os_reason_free(exit_reason
); 
 708                         if (get_threadtask(self
) != task
) { 
 714                         thread_terminate(self
); 
 715                         if (!thread_can_terminate
) { 
 719                         thread_exception_return(); 
 725         if (exit_reason 
!= OS_REASON_NULL
) { 
 726                 KERNEL_DEBUG_CONSTANT(BSDDBG_CODE(DBG_BSD_PROC
, BSD_PROC_EXITREASON_COMMIT
) | DBG_FUNC_NONE
, 
 727                                                         p
->p_pid
, exit_reason
->osr_namespace
, 
 728                                                         exit_reason
->osr_code
, 0, 0); 
 731         assert(p
->p_exit_reason 
== OS_REASON_NULL
); 
 732         p
->p_exit_reason 
= exit_reason
; 
 734         p
->p_lflag 
|= P_LEXIT
; 
 736         p
->p_lflag 
|= jetsam_flags
; 
 741         proc_prepareexit(p
, rv
, perf_notify
); 
 743         /* Last thread to terminate will call proc_exit() */ 
 744         task_terminate_internal(task
); 
 750 proc_prepareexit(proc_t p
, int rv
, boolean_t perf_notify
)  
 752         mach_exception_data_type_t code 
= 0, subcode 
= 0; 
 755         thread_t self 
= current_thread(); 
 756         ut 
= get_bsdthread_info(self
); 
 757         struct rusage_superset 
*rup
; 
 759         int create_corpse 
= FALSE
; 
 762                 launchd_crashed_panic(p
, rv
); 
 766         /* If a core should be generated, notify crash reporter */ 
 767         if (hassigprop(WTERMSIG(rv
), SA_CORE
) || ((p
->p_csflags 
& CS_KILLED
) != 0) || 
 768                 (p
->p_exit_reason 
!= OS_REASON_NULL 
&& (p
->p_exit_reason
->osr_flags 
& 
 769                                                         OS_REASON_FLAG_GENERATE_CRASH_REPORT
))) { 
 771                  * Workaround for processes checking up on PT_DENY_ATTACH: 
 772                  * should be backed out post-Leopard (details in 5431025). 
 774                 if ((SIGSEGV 
== WTERMSIG(rv
)) &&  
 775                                 (p
->p_pptr
->p_lflag 
& P_LNOATTACH
)) { 
 780                  * Crash Reporter looks for the signal value, original exception 
 781                  * type, and low 20 bits of the original code in code[0]  
 782                  * (8, 4, and 20 bits respectively). code[1] is unmodified.  
 784                 code 
= ((WTERMSIG(rv
) & 0xff) << 24) | 
 785                         ((ut
->uu_exception 
& 0x0f) << 20) |  
 786                         ((int)ut
->uu_code 
& 0xfffff); 
 787                 subcode 
= ut
->uu_subcode
; 
 789                 kr 
= task_exception_notify(EXC_CRASH
, code
, subcode
); 
 791                 /* Nobody handled EXC_CRASH?? remember to make corpse */ 
 793                         create_corpse 
= TRUE
; 
 798         /* Notify the perf server? */ 
 800                 (void)sys_perf_notify(self
, p
->p_pid
); 
 804         /* stash the usage into corpse data if making_corpse == true */ 
 805         if (create_corpse 
== TRUE
) { 
 806                 kr 
= task_mark_corpse(current_task()); 
 807                 if (kr 
!= KERN_SUCCESS
) { 
 808                         if (kr 
== KERN_NO_SPACE
) { 
 809                                 printf("Process[%d] has no vm space for corpse info.\n", p
->p_pid
); 
 810                         } else if (kr 
== KERN_NOT_SUPPORTED
) { 
 811                                 printf("Process[%d] was destined to be corpse. But corpse is disabled by config.\n", p
->p_pid
); 
 813                                 printf("Process[%d] crashed: %s. Too many corpses being created.\n", p
->p_pid
, p
->p_comm
); 
 815                         create_corpse 
= FALSE
; 
 820          * Before this process becomes a zombie, stash resource usage 
 821          * stats in the proc for external observers to query 
 822          * via proc_pid_rusage(). 
 824          * If the zombie allocation fails, just punt the stats. 
 826         MALLOC_ZONE(rup
, struct rusage_superset 
*, 
 827                         sizeof (*rup
), M_ZOMBIE
, M_WAITOK
); 
 829                 gather_rusage_info(p
, &rup
->ri
, RUSAGE_INFO_CURRENT
); 
 830                 rup
->ri
.ri_phys_footprint 
= 0; 
 831                 rup
->ri
.ri_proc_exit_abstime 
= mach_absolute_time(); 
 834                  * Make the rusage_info visible to external observers 
 835                  * only after it has been completely filled in. 
 840                 int est_knotes 
= 0, num_knotes 
= 0; 
 841                 uint64_t *buffer 
= NULL
; 
 844                 /* Get all the udata pointers from kqueue */ 
 845                 est_knotes 
= proc_list_uptrs(p
, NULL
, 0); 
 846                 if (est_knotes 
> 0) { 
 847                         buf_size 
= (est_knotes 
+ 32) * sizeof(uint64_t); 
 848                         buffer 
= (uint64_t *) kalloc(buf_size
); 
 849                         num_knotes 
= proc_list_uptrs(p
, buffer
, buf_size
); 
 850                         if (num_knotes 
> est_knotes 
+ 32) { 
 851                                 num_knotes 
= est_knotes 
+ 32; 
 855                 /* Update the code, subcode based on exit reason */ 
 856                 proc_update_corpse_exception_codes(p
, &code
, &subcode
); 
 857                 populate_corpse_crashinfo(p
, task_get_corpseinfo(current_task()), rup
, code
, subcode
, buffer
, num_knotes
); 
 858                 if (buffer 
!= NULL
) { 
 859                         kfree(buffer
, buf_size
); 
 863          * Remove proc from allproc queue and from pidhash chain. 
 864          * Need to do this before we do anything that can block. 
 865          * Not doing causes things like mount() find this on allproc 
 866          * in partially cleaned state. 
 871 #if CONFIG_MEMORYSTATUS 
 872         memorystatus_remove(p
, TRUE
); 
 875         LIST_REMOVE(p
, p_list
); 
 876         LIST_INSERT_HEAD(&zombproc
, p
, p_list
); /* Place onto zombproc. */ 
 877         /* will not be visible via proc_find */ 
 878         p
->p_listflag 
|= P_LIST_EXITED
; 
 887          * If parent is waiting for us to exit or exec, 
 888          * P_LPPWAIT is set; we will wakeup the parent below. 
 891         p
->p_lflag 
&= ~(P_LTRACED 
| P_LPPWAIT
); 
 892         p
->p_sigignore 
= ~(sigcantmask
); 
 902         struct task 
*task 
= p
->task
; 
 903         vnode_t tvp 
= NULLVP
; 
 905         struct session 
*sessp
; 
 906         struct uthread 
* uth
; 
 911         uth 
= current_uthread(); 
 914         proc_transstart(p
, 1, 0); 
 915         if( !(p
->p_lflag 
& P_LEXIT
)) { 
 917                  * This can happen if a thread_terminate() occurs 
 918                  * in a single-threaded process. 
 920                 p
->p_lflag 
|= P_LEXIT
; 
 923                 proc_prepareexit(p
, 0, TRUE
);    
 924                 (void) task_terminate_internal(task
); 
 930         p
->p_lflag 
|= P_LPEXIT
; 
 933          * Other kernel threads may be in the middle of signalling this process. 
 934          * Wait for those threads to wrap it up before making the process 
 937         if ((p
->p_lflag 
& P_LINSIGNAL
) || (p
->p_sigwaitcnt 
> 0)) { 
 939                 while ((p
->p_lflag 
& P_LINSIGNAL
) || (p
->p_sigwaitcnt 
> 1))  
 940                         msleep(&p
->p_sigmask
, &p
->p_mlock
, PWAIT
, "proc_sigdrain", NULL
); 
 946         exitval 
= p
->p_xstat
; 
 947         KERNEL_DEBUG_CONSTANT_IST(KDEBUG_COMMON
,  
 948                 BSDDBG_CODE(DBG_BSD_PROC
, BSD_PROC_EXIT
) | DBG_FUNC_START
, 
 949                 pid
, exitval
, 0, 0, 0); 
 958          * need to cancel async IO requests that can be cancelled and wait for those 
 959          * already active.  MAY BLOCK! 
 964         /* if any pending cpu limits action, clear it */ 
 965         task_clear_cpuusage(p
->task
, TRUE
); 
 967         workqueue_mark_exiting(p
); 
 969         kqueue_dealloc(p
->p_wqkqueue
); 
 970         p
->p_wqkqueue 
= NULL
; 
 975          * Close open files and release open-file table. 
 980         if (uth
->uu_lowpri_window
) { 
 982                  * task is marked as a low priority I/O type 
 983                  * and the I/O we issued while in flushing files on close 
 984                  * collided with normal I/O operations... 
 985                  * no need to throttle this thread since its going away 
 986                  * but we do need to update our bookeeping w/r to throttled threads 
 988                 throttle_lowpri_io(0); 
 992         /* Close ref SYSV Shared memory*/ 
 997         /* Release SYSV semaphores */ 
1002         pth_proc_hashdelete(p
); 
1005         sessp 
= proc_session(p
); 
1006         if (SESS_LEADER(p
, sessp
)) { 
1008                 if (sessp
->s_ttyvp 
!= NULLVP
) { 
1009                         struct vnode 
*ttyvp
; 
1012                         struct vfs_context context
; 
1016                          * Controlling process. 
1017                          * Signal foreground pgrp, 
1018                          * drain controlling terminal 
1019                          * and revoke access to controlling terminal. 
1021                         session_lock(sessp
); 
1022                         tp 
= SESSION_TP(sessp
); 
1023                         if ((tp 
!= TTY_NULL
) && (tp
->t_session 
== sessp
)) { 
1024                                 session_unlock(sessp
); 
1027                                  * We're going to SIGHUP the foreground process 
1028                                  * group. It can't change from this point on 
1029                                  * until the revoke is complete. 
1030                                  * The process group changes under both the tty 
1031                                  * lock and proc_list_lock but we need only one 
1037                                 tty_pgsignal(tp
, SIGHUP
, 1); 
1039                                 session_lock(sessp
); 
1040                                 tp 
= SESSION_TP(sessp
); 
1042                         cttyflag 
= sessp
->s_flags 
& S_CTTYREF
; 
1043                         sessp
->s_flags 
&= ~S_CTTYREF
; 
1044                         ttyvp 
= sessp
->s_ttyvp
; 
1045                         ttyvid 
= sessp
->s_ttyvid
; 
1046                         sessp
->s_ttyvp 
= NULLVP
; 
1047                         sessp
->s_ttyvid 
= 0; 
1048                         sessp
->s_ttyp 
= TTY_NULL
; 
1049                         sessp
->s_ttypgrpid 
= NO_PID
; 
1050                         session_unlock(sessp
); 
1052                         if ((ttyvp 
!= NULLVP
) && (vnode_getwithvid(ttyvp
, ttyvid
) == 0)) { 
1053                                 if (tp 
!= TTY_NULL
) { 
1058                                 context
.vc_thread 
= proc_thread(p
); /* XXX */ 
1059                                 context
.vc_ucred 
= kauth_cred_proc_ref(p
); 
1060                                 VNOP_REVOKE(ttyvp
, REVOKEALL
, &context
); 
1063                                          * Release the extra usecount taken in cttyopen. 
1064                                          * usecount should be released after VNOP_REVOKE is called. 
1065                                          * This usecount was taken to ensure that 
1066                                          * the VNOP_REVOKE results in a close to 
1067                                          * the tty since cttyclose is a no-op. 
1072                                 kauth_cred_unref(&context
.vc_ucred
); 
1077                                  * This is cleared even if not set. This is also done in 
1078                                  * spec_close to ensure that the flag is cleared. 
1087                 session_lock(sessp
); 
1088                 sessp
->s_leader 
= NULL
; 
1089                 session_unlock(sessp
); 
1091         session_rele(sessp
); 
1097         p
->p_rlimit
[RLIMIT_FSIZE
].rlim_cur 
= RLIM_INFINITY
; 
1098         (void)acct_process(p
); 
1102         if ((p
->p_listflag 
& P_LIST_EXITCOUNT
) == P_LIST_EXITCOUNT
) { 
1103                 p
->p_listflag 
&= ~P_LIST_EXITCOUNT
; 
1104                 proc_shutdown_exitcount
--; 
1105                 if (proc_shutdown_exitcount 
== 0) 
1106                         wakeup(&proc_shutdown_exitcount
); 
1109         /* wait till parentrefs are dropped and grant no more */ 
1110         proc_childdrainstart(p
); 
1111         while ((q 
= p
->p_children
.lh_first
) != NULL
) { 
1112                 int reparentedtoinit 
= (q
->p_listflag 
& P_LIST_DEADPARENT
) ? 1 : 0; 
1113                 if (q
->p_stat 
== SZOMB
) { 
1115                                 panic("parent child linkage broken"); 
1116                         /* check for sysctl zomb lookup */ 
1117                         while ((q
->p_listflag 
& P_LIST_WAITING
) == P_LIST_WAITING
) { 
1118                                 msleep(&q
->p_stat
, proc_list_mlock
, PWAIT
, "waitcoll", 0); 
1120                         q
->p_listflag 
|= P_LIST_WAITING
; 
1122                          * This is a named reference and it is not granted 
1123                          * if the reap is already in progress. So we get 
1124                          * the reference here exclusively and their can be 
1125                          * no waiters. So there is no need for a wakeup 
1126                          * after we are done.  Also the reap frees the structure 
1127                          * and the proc struct cannot be used for wakeups as well.  
1128                          * It is safe to use q here as this is system reap 
1130                         (void)reap_child_locked(p
, q
, 1, reparentedtoinit
, 1, 0); 
1133                         * Traced processes are killed 
1134                         * since their existence means someone is messing up. 
1136                         if (q
->p_lflag 
& P_LTRACED
) { 
1140                                  * Take a reference on the child process to 
1141                                  * ensure it doesn't exit and disappear between 
1142                                  * the time we drop the list_lock and attempt 
1143                                  * to acquire its proc_lock. 
1145                                 if (proc_ref_locked(q
) != q
) 
1150                                 opp 
= proc_find(q
->p_oppid
); 
1151                                 if (opp 
!= PROC_NULL
) { 
1155                                         proc_reparentlocked(q
, opp
, 0, 0); 
1158                                         /* original parent exited while traced */ 
1160                                         q
->p_listflag 
|= P_LIST_DEADPARENT
; 
1163                                         proc_reparentlocked(q
, initproc
, 0, 0); 
1167                                 q
->p_lflag 
&= ~P_LTRACED
; 
1169                                 if (q
->sigwait_thread
) { 
1170                                         thread_t thread 
= q
->sigwait_thread
; 
1174                                         * The sigwait_thread could be stopped at a 
1175                                         * breakpoint. Wake it up to kill. 
1176                                         * Need to do this as it could be a thread which is not 
1177                                         * the first thread in the task. So any attempts to kill 
1178                                         * the process would result into a deadlock on q->sigwait. 
1180                                         thread_resume(thread
); 
1181                                         clear_wait(thread
, THREAD_INTERRUPTED
); 
1182                                         threadsignal(thread
, SIGKILL
, 0, TRUE
); 
1187                                 psignal(q
, SIGKILL
); 
1189                                 proc_rele_locked(q
); 
1191                                 q
->p_listflag 
|= P_LIST_DEADPARENT
; 
1192                                 proc_reparentlocked(q
, initproc
, 0, 1); 
1197         proc_childdrainend(p
); 
1201          * Release reference to text vnode 
1205         if (tvp 
!= NULLVP
) { 
1210          * Save exit status and final rusage info, adding in child rusage 
1211          * info and self times.  If we were unable to allocate a zombie 
1212          * structure, this information is lost. 
1214         if (p
->p_ru 
!= NULL
) { 
1215             calcru(p
, &p
->p_stats
->p_ru
.ru_utime
, &p
->p_stats
->p_ru
.ru_stime
, NULL
); 
1216             p
->p_ru
->ru 
= p
->p_stats
->p_ru
; 
1218             ruadd(&(p
->p_ru
->ru
), &p
->p_stats
->p_cru
); 
1222          * Free up profiling buffers. 
1225                 struct uprof 
*p0 
= &p
->p_stats
->p_prof
, *p1
, *pn
; 
1231                 for (; p1 
!= NULL
; p1 
= pn
) { 
1233                         kfree(p1
, sizeof *p1
); 
1237         proc_free_realitimer(p
); 
1240          * Other substructures are freed from wait(). 
1242         FREE_ZONE(p
->p_stats
, sizeof *p
->p_stats
, M_PSTATS
); 
1245         FREE_ZONE(p
->p_sigacts
, sizeof *p
->p_sigacts
, M_SIGACTS
); 
1246         p
->p_sigacts 
= NULL
; 
1248         proc_limitdrop(p
, 1); 
1251         vm_purgeable_disown(p
->task
); 
1254          * Finish up by terminating the task 
1255          * and halt this thread (only if a 
1256          * member of the task exiting). 
1258         p
->task 
= TASK_NULL
; 
1259         set_bsdtask_info(task
, NULL
); 
1261         knote_hint 
= NOTE_EXIT 
| (p
->p_xstat 
& 0xffff); 
1262         proc_knote(p
, knote_hint
); 
1264         /* mark the thread as the one that is doing proc_exit 
1265          * no need to hold proc lock in uthread_free 
1267         uth
->uu_flag 
|= UT_PROCEXIT
; 
1269          * Notify parent that we're gone. 
1271         pp 
= proc_parent(p
); 
1272         if (pp
->p_flag 
& P_NOCLDWAIT
) { 
1274                 if (p
->p_ru 
!= NULL
) { 
1278                  * If the parent is ignoring SIGCHLD, then POSIX requires 
1279                  * us to not add the resource usage to the parent process - 
1280                  * we are only going to hand it off to init to get reaped. 
1281                  * We should contest the standard in this case on the basis 
1284 #else   /* !3839178 */ 
1286                  * Add child resource usage to parent before giving 
1287                  * zombie to init.  If we were unable to allocate a 
1288                  * zombie structure, this information is lost. 
1290                         ruadd(&pp
->p_stats
->p_cru
, &p
->p_ru
->ru
); 
1291 #endif  /* !3839178 */ 
1292                         update_rusage_info_child(&pp
->p_stats
->ri_child
, &p
->p_ru
->ri
); 
1296                 /* kernel can reap this one, no need to move it to launchd */ 
1298                 p
->p_listflag 
|= P_LIST_DEADPARENT
; 
1301         if ((p
->p_listflag 
& P_LIST_DEADPARENT
) == 0 || p
->p_oppid
) { 
1302                 if (pp 
!= initproc
) { 
1304                         pp
->si_pid 
= p
->p_pid
; 
1305                         pp
->si_status 
= p
->p_xstat
; 
1306                         pp
->si_code 
= CLD_EXITED
; 
1308                          * p_ucred usage is safe as it is an exiting process 
1309                          * and reference is dropped in reap 
1311                         pp
->si_uid 
= kauth_cred_getruid(p
->p_ucred
); 
1314                 /* mark as a zombie */ 
1315                 /* No need to take proc lock as all refs are drained and 
1316                  * no one except parent (reaping ) can look at this. 
1317                  * The write is to an int and is coherent. Also parent is 
1318                  *  keyed off of list lock for reaping 
1320                 KERNEL_DEBUG_CONSTANT_IST(KDEBUG_COMMON
, 
1321                         BSDDBG_CODE(DBG_BSD_PROC
, BSD_PROC_EXIT
) | DBG_FUNC_END
, 
1322                         pid
, exitval
, 0, 0, 0); 
1325                  * The current process can be reaped so, no one 
1326                  * can depend on this 
1329                 psignal(pp
, SIGCHLD
); 
1331                 /* and now wakeup the parent */ 
1333                 wakeup((caddr_t
)pp
); 
1336                 /* should be fine as parent proc would be initproc */ 
1337                 /* mark as a zombie */ 
1338                 /* No need to take proc lock as all refs are drained and 
1339                  * no one except parent (reaping ) can look at this. 
1340                  * The write is to an int and is coherent. Also parent is 
1341                  *  keyed off of list lock for reaping 
1344                 KERNEL_DEBUG_CONSTANT_IST(KDEBUG_COMMON
, 
1345                         BSDDBG_CODE(DBG_BSD_PROC
, BSD_PROC_EXIT
) | DBG_FUNC_END
, 
1346                         pid
, exitval
, 0, 0, 0); 
1347                 /* check for sysctl zomb lookup */ 
1348                 while ((p
->p_listflag 
& P_LIST_WAITING
) == P_LIST_WAITING
) { 
1349                         msleep(&p
->p_stat
, proc_list_mlock
, PWAIT
, "waitcoll", 0); 
1351                 /* safe to use p as this is a system reap */ 
1353                 p
->p_listflag 
|= P_LIST_WAITING
; 
1356                  * This is a named reference and it is not granted 
1357                  * if the reap is already in progress. So we get 
1358                  * the reference here exclusively and their can be 
1359                  * no waiters. So there is no need for a wakeup 
1360                  * after we are done. AlsO  the reap frees the structure 
1361                  * and the proc struct cannot be used for wakeups as well.  
1362                  * It is safe to use p here as this is system reap 
1364                 (void)reap_child_locked(pp
, p
, 1, 0, 1, 1); 
1365                 /* list lock dropped by reap_child_locked */ 
1367         if (uth
->uu_lowpri_window
) { 
1369                  * task is marked as a low priority I/O type and we've 
1370                  * somehow picked up another throttle during exit processing... 
1371                  * no need to throttle this thread since its going away 
1372                  * but we do need to update our bookeeping w/r to throttled threads 
1374                 throttle_lowpri_io(0); 
1385  * Description: Given a process from which all status information needed 
1386  *              has already been extracted, if the process is a ptrace 
1387  *              attach process, detach it and give it back to its real 
1388  *              parent, else recover all resources remaining associated 
1391  * Parameters:  proc_t parent           Parent of process being reaped 
1392  *              proc_t child            Process to reap 
1394  * Returns:     0                       Process was not reaped because it 
1395  *                                      came from an attach 
1396  *              1                       Process was reaped 
1399 reap_child_locked(proc_t parent
, proc_t child
, int deadparent
, int reparentedtoinit
, int locked
, int droplock
) 
1401         proc_t trace_parent 
= PROC_NULL
;        /* Traced parent process, if tracing */ 
1407          * If we got the child via a ptrace 'attach', 
1408          * we need to give it back to the old parent. 
1410          * Exception: someone who has been reparented to launchd before being 
1411          * ptraced can simply be reaped, refer to radar 5677288 
1412          *      p_oppid                  -> ptraced 
1413          *      trace_parent == initproc -> away from launchd 
1414          *      reparentedtoinit         -> came to launchd by reparenting 
1416         if (child
->p_oppid
) { 
1421                 oppid 
= child
->p_oppid
; 
1423                 knote_hint 
= NOTE_EXIT 
| (child
->p_xstat 
& 0xffff); 
1426                 if ((trace_parent 
= proc_find(oppid
)) 
1427                         && !((trace_parent 
== initproc
) && reparentedtoinit
)) { 
1429                         if (trace_parent 
!= initproc
) { 
1431                                  * proc internal fileds  and p_ucred usage safe  
1432                                  * here as child is dead and is not reaped or  
1435                                 proc_lock(trace_parent
); 
1436                                 trace_parent
->si_pid 
= child
->p_pid
; 
1437                                 trace_parent
->si_status 
= child
->p_xstat
; 
1438                                 trace_parent
->si_code 
= CLD_CONTINUED
; 
1439                                 trace_parent
->si_uid 
= kauth_cred_getruid(child
->p_ucred
); 
1440                                 proc_unlock(trace_parent
); 
1442                         proc_reparentlocked(child
, trace_parent
, 1, 0); 
1444                         /* resend knote to original parent (and others) after reparenting */ 
1445                         proc_knote(child
, knote_hint
); 
1447                         psignal(trace_parent
, SIGCHLD
); 
1449                         wakeup((caddr_t
)trace_parent
); 
1450                         child
->p_listflag 
&= ~P_LIST_WAITING
; 
1451                         wakeup(&child
->p_stat
); 
1453                         proc_rele(trace_parent
); 
1454                         if ((locked 
== 1) && (droplock 
== 0)) 
1460                  * If we can't reparent (e.g. the original parent exited while child was being debugged, or 
1461                  * original parent is the same as the debugger currently exiting), we still need to satisfy 
1462                  * the knote lifecycle for other observers on the system. While the debugger was attached, 
1463                  * the NOTE_EXIT would not have been broadcast during initial child termination. 
1465                 proc_knote(child
, knote_hint
); 
1467                 if (trace_parent 
!= PROC_NULL
) { 
1468                         proc_rele(trace_parent
); 
1472 #pragma clang diagnostic push 
1473 #pragma clang diagnostic ignored "-Wdeprecated-declarations" 
1474         proc_knote(child
, NOTE_REAP
); 
1475 #pragma clang diagnostic pop 
1477         proc_knote_drain(child
); 
1484                  * If the parent is ignoring SIGCHLD, then POSIX requires 
1485                  * us to not add the resource usage to the parent process - 
1486                  * we are only going to hand it off to init to get reaped. 
1487                  * We should contest the standard in this case on the basis 
1490                 if (!(parent
->p_flag 
& P_NOCLDWAIT
)) 
1491 #endif  /* 3839178 */ 
1492                         ruadd(&parent
->p_stats
->p_cru
, &child
->p_ru
->ru
); 
1493                 update_rusage_info_child(&parent
->p_stats
->ri_child
, &child
->p_ru
->ri
); 
1494                 proc_unlock(parent
); 
1495                 FREE_ZONE(child
->p_ru
, sizeof *child
->p_ru
, M_ZOMBIE
); 
1498                 printf("Warning : lost p_ru for %s\n", child
->p_comm
); 
1501         AUDIT_SESSION_PROCEXIT(child
); 
1504          * Decrement the count of procs running with this uid. 
1505          * p_ucred usage is safe here as it is an exited process. 
1506          * and refernce is dropped after these calls down below 
1507          * (locking protection is provided by list lock held in chgproccnt) 
1511          * persona_proc_drop calls chgproccnt(-1) on the persona uid, 
1512          * and (+1) on the child->p_ucred uid 
1514         persona_proc_drop(child
); 
1516         (void)chgproccnt(kauth_cred_getruid(child
->p_ucred
), -1); 
1518         os_reason_free(child
->p_exit_reason
); 
1521          * Free up credentials. 
1523         if (IS_VALID_CRED(child
->p_ucred
)) { 
1524                 kauth_cred_unref(&child
->p_ucred
); 
1527         /*  XXXX Note NOT SAFE TO USE p_ucred from this point onwards */ 
1530          * Finally finished with old proc entry. 
1531          * Unlink it from its process group and free it. 
1536         LIST_REMOVE(child
, p_list
);     /* off zombproc */ 
1537         parent
->p_childrencnt
--; 
1538         LIST_REMOVE(child
, p_sibling
); 
1539         /* If there are no more children wakeup parent */ 
1540         if ((deadparent 
!= 0) && (LIST_EMPTY(&parent
->p_children
))) 
1541                 wakeup((caddr_t
)parent
);        /* with list lock held */ 
1542         child
->p_listflag 
&= ~P_LIST_WAITING
; 
1543         wakeup(&child
->p_stat
); 
1545         /* Take it out of process hash */ 
1546         LIST_REMOVE(child
, p_hash
); 
1547         child
->p_listflag 
&= ~P_LIST_INHASH
; 
1548         proc_checkdeadrefs(child
); 
1553                  * If a child zombie is being reaped because its parent 
1554                  * is exiting, make sure we update the list flag 
1556                 child
->p_listflag 
|= P_LIST_DEADPARENT
; 
1561 #if CONFIG_FINE_LOCK_GROUPS 
1562         lck_mtx_destroy(&child
->p_mlock
, proc_mlock_grp
); 
1563         lck_mtx_destroy(&child
->p_fdmlock
, proc_fdmlock_grp
); 
1564         lck_mtx_destroy(&child
->p_ucred_mlock
, proc_ucred_mlock_grp
); 
1566         lck_mtx_destroy(&child
->p_dtrace_sprlock
, proc_lck_grp
); 
1568         lck_spin_destroy(&child
->p_slock
, proc_slock_grp
); 
1569 #else /* CONFIG_FINE_LOCK_GROUPS */ 
1570         lck_mtx_destroy(&child
->p_mlock
, proc_lck_grp
); 
1571         lck_mtx_destroy(&child
->p_fdmlock
, proc_lck_grp
); 
1572         lck_mtx_destroy(&child
->p_ucred_mlock
, proc_lck_grp
); 
1574         lck_mtx_destroy(&child
->p_dtrace_sprlock
, proc_lck_grp
); 
1576         lck_spin_destroy(&child
->p_slock
, proc_lck_grp
); 
1577 #endif /* CONFIG_FINE_LOCK_GROUPS */ 
1579         FREE_ZONE(child
, sizeof *child
, M_PROC
); 
1580         if ((locked 
== 1) && (droplock 
== 0)) 
1588 wait1continue(int result
) 
1593         struct _wait4_data 
*wait4_data
; 
1594         struct wait4_nocancel_args 
*uap
; 
1601         thread 
= current_thread(); 
1602         uth 
= (struct uthread 
*)get_bsdthread_info(thread
); 
1604         wait4_data 
= &uth
->uu_kevent
.uu_wait4_data
; 
1605         uap 
= wait4_data
->args
; 
1606         retval 
= wait4_data
->retval
; 
1607         return(wait4_nocancel(p
, uap
, retval
)); 
1611 wait4(proc_t q
, struct wait4_args 
*uap
, int32_t *retval
) 
1613         __pthread_testcancel(1); 
1614         return(wait4_nocancel(q
, (struct wait4_nocancel_args 
*)uap
, retval
)); 
1618 wait4_nocancel(proc_t q
, struct wait4_nocancel_args 
*uap
, int32_t *retval
) 
1625         struct _wait4_data 
*wait4_data
; 
1627         AUDIT_ARG(pid
, uap
->pid
); 
1630                 uap
->pid 
= -q
->p_pgrpid
; 
1638         PCHILDREN_FOREACH(q
, p
) { 
1639                 if ( p
->p_sibling
.le_next 
!= 0 ) 
1641                 if (uap
->pid 
!= WAIT_ANY 
&& 
1642                     p
->p_pid 
!= uap
->pid 
&& 
1643                     p
->p_pgrpid 
!= -(uap
->pid
)) 
1648                 /* XXX This is racy because we don't get the lock!!!! */ 
1650                 if (p
->p_listflag 
& P_LIST_WAITING
) { 
1651                         (void)msleep(&p
->p_stat
, proc_list_mlock
, PWAIT
, "waitcoll", 0); 
1654                 p
->p_listflag 
|= P_LIST_WAITING
;   /* only allow single thread to wait() */ 
1657                 if (p
->p_stat 
== SZOMB
) { 
1658                         int reparentedtoinit 
= (p
->p_listflag 
& P_LIST_DEADPARENT
) ? 1 : 0; 
1662                         if ((error 
= mac_proc_check_wait(q
, p
)) != 0) 
1665                         retval
[0] = p
->p_pid
; 
1667                                 /* Legacy apps expect only 8 bits of status */ 
1668                                 status 
= 0xffff & p
->p_xstat
;   /* convert to int */ 
1669                                 error 
= copyout((caddr_t
)&status
, 
1676                                 if (p
->p_ru 
== NULL
) { 
1679                                         if (IS_64BIT_PROCESS(q
)) { 
1680                                                 struct user64_rusage    my_rusage
; 
1681                                                 munge_user64_rusage(&p
->p_ru
->ru
, &my_rusage
); 
1682                                                 error 
= copyout((caddr_t
)&my_rusage
, 
1684                                                         sizeof (my_rusage
)); 
1687                                                 struct user32_rusage    my_rusage
; 
1688                                                 munge_user32_rusage(&p
->p_ru
->ru
, &my_rusage
); 
1689                                                 error 
= copyout((caddr_t
)&my_rusage
, 
1691                                                         sizeof (my_rusage
)); 
1694                                 /* information unavailable? */ 
1699                         /* Conformance change for 6577252. 
1700                          * When SIGCHLD is blocked and wait() returns because the status 
1701                          * of a child process is available and there are no other  
1702                          * children processes, then any pending SIGCHLD signal is cleared. 
1704                         if ( sibling_count 
== 0 ) { 
1705                                 int mask 
= sigmask(SIGCHLD
); 
1706                                 uth 
= current_uthread(); 
1708                                 if ( (uth
->uu_sigmask 
& mask
) != 0 ) { 
1709                                         /* we are blocking SIGCHLD signals.  clear any pending SIGCHLD. 
1710                                          * This locking looks funny but it is protecting access to the  
1711                                          * thread via p_uthlist. 
1714                                         uth
->uu_siglist 
&= ~mask
;       /* clear pending signal */ 
1720                         (void)reap_child_locked(q
, p
, 0, reparentedtoinit
, 0, 0); 
1724                 if (p
->p_stat 
== SSTOP 
&& (p
->p_lflag 
& P_LWAITED
) == 0 && 
1725                     (p
->p_lflag 
& P_LTRACED 
|| uap
->options 
& WUNTRACED
)) { 
1728                         if ((error 
= mac_proc_check_wait(q
, p
)) != 0) 
1732                         p
->p_lflag 
|= P_LWAITED
; 
1734                         retval
[0] = p
->p_pid
; 
1736                                 status 
= W_STOPCODE(p
->p_xstat
); 
1737                                 error 
= copyout((caddr_t
)&status
, 
1745                  * If we are waiting for continued processses, and this 
1746                  * process was continued 
1748                 if ((uap
->options 
& WCONTINUED
) && 
1749                     (p
->p_flag 
& P_CONTINUED
)) { 
1752                         if ((error 
= mac_proc_check_wait(q
, p
)) != 0) 
1756                         /* Prevent other process for waiting for this event */ 
1757                         OSBitAndAtomic(~((uint32_t)P_CONTINUED
), &p
->p_flag
); 
1758                         retval
[0] = p
->p_pid
; 
1760                                 status 
= W_STOPCODE(SIGCONT
); 
1761                                 error 
= copyout((caddr_t
)&status
, 
1768                 p
->p_listflag 
&= ~P_LIST_WAITING
; 
1771         /* list lock is held when we get here any which way */ 
1777         if (uap
->options 
& WNOHANG
) { 
1783         /* Save arguments for continuation. Backing storage is in uthread->uu_arg, and will not be deallocated */ 
1784         uth 
= current_uthread(); 
1785         wait4_data 
= &uth
->uu_kevent
.uu_wait4_data
; 
1786         wait4_data
->args 
= uap
; 
1787         wait4_data
->retval 
= retval
; 
1789         if ((error 
= msleep0((caddr_t
)q
, proc_list_mlock
, PWAIT 
| PCATCH 
| PDROP
, "wait", 0, wait1continue
))) 
1795         p
->p_listflag 
&= ~P_LIST_WAITING
; 
1802 #define ASSERT_LCK_MTX_OWNED(lock)      \ 
1803                                 lck_mtx_assert(lock, LCK_MTX_ASSERT_OWNED) 
1805 #define ASSERT_LCK_MTX_OWNED(lock)      /* nothing */ 
1809 waitidcontinue(int result
) 
1814         struct _waitid_data 
*waitid_data
; 
1815         struct waitid_nocancel_args 
*uap
; 
1822         thread 
= current_thread(); 
1823         uth 
= (struct uthread 
*)get_bsdthread_info(thread
); 
1825         waitid_data 
= &uth
->uu_kevent
.uu_waitid_data
; 
1826         uap 
= waitid_data
->args
; 
1827         retval 
= waitid_data
->retval
; 
1828         return(waitid_nocancel(p
, uap
, retval
)); 
1832  * Description: Suspend the calling thread until one child of the process 
1833  *              containing the calling thread changes state. 
1835  * Parameters:  uap->idtype             one of P_PID, P_PGID, P_ALL 
1836  *              uap->id                 pid_t or gid_t or ignored 
1837  *              uap->infop              Address of siginfo_t struct in 
1838  *                                      user space into which to return status 
1839  *              uap->options            flag values 
1841  * Returns:     0                       Success 
1842  *              !0                      Error returning status to user space 
1845 waitid(proc_t q
, struct waitid_args 
*uap
, int32_t *retval
) 
1847         __pthread_testcancel(1); 
1848         return (waitid_nocancel(q
, (struct waitid_nocancel_args 
*)uap
, retval
)); 
1852 waitid_nocancel(proc_t q
, struct waitid_nocancel_args 
*uap
, 
1853         __unused 
int32_t *retval
) 
1855         user_siginfo_t  siginfo
;        /* siginfo data to return to caller */ 
1856         boolean_t caller64 
= IS_64BIT_PROCESS(q
); 
1861         struct _waitid_data 
*waitid_data
; 
1863         if (uap
->options 
== 0 || 
1864             (uap
->options 
& ~(WNOHANG
|WNOWAIT
|WCONTINUED
|WSTOPPED
|WEXITED
))) 
1865                 return (EINVAL
);        /* bits set that aren't recognized */ 
1867         switch (uap
->idtype
) { 
1868         case P_PID
:     /* child with process ID equal to... */ 
1869         case P_PGID
:    /* child with process group ID equal to... */ 
1870                 if (((int)uap
->id
) < 0) 
1873         case P_ALL
:     /* any child */ 
1882         PCHILDREN_FOREACH(q
, p
) { 
1883                 switch (uap
->idtype
) { 
1884                 case P_PID
:     /* child with process ID equal to... */ 
1885                         if (p
->p_pid 
!= (pid_t
)uap
->id
) 
1888                 case P_PGID
:    /* child with process group ID equal to... */ 
1889                         if (p
->p_pgrpid 
!= (pid_t
)uap
->id
) 
1892                 case P_ALL
:     /* any child */ 
1896                 /* XXX This is racy because we don't get the lock!!!! */ 
1899                  * Wait collision; go to sleep and restart; used to maintain 
1900                  * the single return for waited process guarantee. 
1902                 if (p
->p_listflag 
& P_LIST_WAITING
) { 
1903                         (void) msleep(&p
->p_stat
, proc_list_mlock
, 
1904                                 PWAIT
, "waitidcoll", 0); 
1907                 p
->p_listflag 
|= P_LIST_WAITING
;                /* mark busy */ 
1911                 bzero(&siginfo
, sizeof (siginfo
)); 
1913                 switch (p
->p_stat
) { 
1914                 case SZOMB
:             /* Exited */ 
1915                         if (!(uap
->options 
& WEXITED
)) 
1919                         if ((error 
= mac_proc_check_wait(q
, p
)) != 0) 
1922                         siginfo
.si_signo 
= SIGCHLD
; 
1923                         siginfo
.si_pid 
= p
->p_pid
; 
1924                         siginfo
.si_status 
= WEXITSTATUS(p
->p_xstat
); 
1925                         if (WIFSIGNALED(p
->p_xstat
)) { 
1926                                 siginfo
.si_code 
= WCOREDUMP(p
->p_xstat
) ? 
1927                                         CLD_DUMPED 
: CLD_KILLED
; 
1929                                 siginfo
.si_code 
= CLD_EXITED
; 
1931                         if ((error 
= copyoutsiginfo(&siginfo
, 
1932                             caller64
, uap
->infop
)) != 0) 
1935                         /* Prevent other process for waiting for this event? */ 
1936                         if (!(uap
->options 
& WNOWAIT
)) { 
1937                                 (void) reap_child_locked(q
, p
, 0, 0, 0, 0); 
1942                 case SSTOP
:             /* Stopped */ 
1944                          * If we are not interested in stopped processes, then 
1947                         if (!(uap
->options 
& WSTOPPED
)) 
1951                          * If someone has already waited it, we lost a race 
1952                          * to be the one to return status. 
1954                         if ((p
->p_lflag 
& P_LWAITED
) != 0) 
1958                         if ((error 
= mac_proc_check_wait(q
, p
)) != 0) 
1961                         siginfo
.si_signo 
= SIGCHLD
; 
1962                         siginfo
.si_pid 
= p
->p_pid
; 
1963                         siginfo
.si_status 
= p
->p_xstat
; /* signal number */ 
1964                         siginfo
.si_code 
= CLD_STOPPED
; 
1966                         if ((error 
= copyoutsiginfo(&siginfo
, 
1967                             caller64
, uap
->infop
)) != 0) 
1970                         /* Prevent other process for waiting for this event? */ 
1971                         if (!(uap
->options 
& WNOWAIT
)) { 
1973                                 p
->p_lflag 
|= P_LWAITED
; 
1978                 default:                /* All other states => Continued */ 
1979                         if (!(uap
->options 
& WCONTINUED
)) 
1983                          * If the flag isn't set, then this process has not 
1984                          * been stopped and continued, or the status has 
1985                          * already been reaped by another caller of waitid(). 
1987                         if ((p
->p_flag 
& P_CONTINUED
) == 0) 
1991                         if ((error 
= mac_proc_check_wait(q
, p
)) != 0) 
1994                         siginfo
.si_signo 
= SIGCHLD
; 
1995                         siginfo
.si_code 
= CLD_CONTINUED
; 
1997                         siginfo
.si_pid 
= p
->p_contproc
; 
1998                         siginfo
.si_status 
= p
->p_xstat
; 
2001                         if ((error 
= copyoutsiginfo(&siginfo
, 
2002                             caller64
, uap
->infop
)) != 0) 
2005                         /* Prevent other process for waiting for this event? */ 
2006                         if (!(uap
->options 
& WNOWAIT
)) { 
2007                                 OSBitAndAtomic(~((uint32_t)P_CONTINUED
), 
2012                 ASSERT_LCK_MTX_OWNED(proc_list_mlock
); 
2014                 /* Not a process we are interested in; go on to next child */ 
2016                 p
->p_listflag 
&= ~P_LIST_WAITING
; 
2019         ASSERT_LCK_MTX_OWNED(proc_list_mlock
); 
2021         /* No child processes that could possibly satisfy the request? */ 
2028         if (uap
->options 
& WNOHANG
) { 
2031                 if ((error 
= mac_proc_check_wait(q
, p
)) != 0) 
2035                  * The state of the siginfo structure in this case 
2036                  * is undefined.  Some implementations bzero it, some 
2037                  * (like here) leave it untouched for efficiency. 
2039                  * Thus the most portable check for "no matching pid with 
2040                  * WNOHANG" is to store a zero into si_pid before 
2041                  * invocation, then check for a non-zero value afterwards. 
2046         /* Save arguments for continuation. Backing storage is in uthread->uu_arg, and will not be deallocated */ 
2047         uth 
= current_uthread(); 
2048         waitid_data 
= &uth
->uu_kevent
.uu_waitid_data
; 
2049         waitid_data
->args 
= uap
; 
2050         waitid_data
->retval 
= retval
; 
2052         if ((error 
= msleep0(q
, proc_list_mlock
, 
2053             PWAIT 
| PCATCH 
| PDROP
, "waitid", 0, waitidcontinue
)) != 0) 
2059         p
->p_listflag 
&= ~P_LIST_WAITING
; 
2066  * make process 'parent' the new parent of process 'child'. 
2069 proc_reparentlocked(proc_t child
, proc_t parent
, int cansignal
, int locked
) 
2071         proc_t oldparent 
= PROC_NULL
; 
2073         if (child
->p_pptr 
== parent
) 
2079         oldparent 
= child
->p_pptr
; 
2080 #if __PROC_INTERNAL_DEBUG 
2081         if (oldparent 
== PROC_NULL
) 
2082                 panic("proc_reparent: process %p does not have a parent\n", child
); 
2085         LIST_REMOVE(child
, p_sibling
); 
2086 #if __PROC_INTERNAL_DEBUG 
2087         if (oldparent
->p_childrencnt 
== 0) 
2088                 panic("process children count already 0\n"); 
2090         oldparent
->p_childrencnt
--; 
2091 #if __PROC_INTERNAL_DEBUG1 
2092         if (oldparent
->p_childrencnt 
< 0) 
2093                 panic("process children count -ve\n"); 
2095         LIST_INSERT_HEAD(&parent
->p_children
, child
, p_sibling
); 
2096         parent
->p_childrencnt
++;         
2097         child
->p_pptr 
= parent
; 
2098         child
->p_ppid 
= parent
->p_pid
; 
2102         if ((cansignal 
!= 0) && (initproc 
== parent
) && (child
->p_stat 
== SZOMB
)) 
2103                 psignal(initproc
, SIGCHLD
); 
2109  * Exit: deallocate address space and other resources, change proc state 
2110  * to zombie, and unlink proc from allproc and parent's lists.  Save exit 
2111  * status and rusage for wait().  Check for child processes and orphan them. 
2115 vfork_exit(proc_t p
, int rv
) 
2117         vfork_exit_internal(p
, rv
, 0); 
2121 vfork_exit_internal(proc_t p
, int rv
, int forceexit
) 
2123         thread_t self 
= current_thread(); 
2125         struct task 
*task 
= p
->task
; 
2130          * If a thread in this task has already 
2131          * called exit(), then halt any others 
2135          ut 
= get_bsdthread_info(self
); 
2139          if ((p
->p_lflag 
& P_LPEXIT
) == P_LPEXIT
) { 
2141                 * This happens when a parent exits/killed and vfork is in progress   
2142                 * other threads. But shutdown code for ex has already called exit1() 
2147         p
->p_lflag 
|= (P_LEXIT 
| P_LPEXIT
); 
2150         if (forceexit 
== 0) { 
2152                  * parent of a vfork child has already called exit() and the  
2153                  * thread that has vfork in proress terminates. So there is no 
2154                  * separate address space here and it has already been marked for 
2155                  * termination. This was never covered before and could cause problems 
2156                  * if we block here for outside code. 
2158                 /* Notify the perf server */ 
2159                 (void)sys_perf_notify(self
, p
->p_pid
); 
2163          * Remove proc from allproc queue and from pidhash chain. 
2164          * Need to do this before we do anything that can block. 
2165          * Not doing causes things like mount() find this on allproc 
2166          * in partially cleaned state. 
2171 #if CONFIG_MEMORYSTATUS 
2172         memorystatus_remove(p
, TRUE
); 
2175         LIST_REMOVE(p
, p_list
); 
2176         LIST_INSERT_HEAD(&zombproc
, p
, p_list
); /* Place onto zombproc. */ 
2177         /* will not be visible via proc_find */ 
2178         p
->p_listflag 
|= P_LIST_EXITED
; 
2184         p
->p_lflag 
&= ~(P_LTRACED 
| P_LPPWAIT
); 
2185         p
->p_sigignore 
= ~0; 
2188         proc_free_realitimer(p
); 
2196 vproc_exit(proc_t p
) 
2203         struct task 
*task 
= p
->task
; 
2206         struct session 
*sessp
; 
2207         struct rusage_superset 
*rup
; 
2209         /* XXX Zombie allocation may fail, in which case stats get lost */ 
2210         MALLOC_ZONE(rup
, struct rusage_superset 
*, 
2211                         sizeof (*rup
), M_ZOMBIE
, M_WAITOK
); 
2216          * Close open files and release open-file table. 
2221         sessp 
= proc_session(p
); 
2222         if (SESS_LEADER(p
, sessp
)) { 
2224                 if (sessp
->s_ttyvp 
!= NULLVP
) { 
2225                         struct vnode 
*ttyvp
; 
2228                         struct vfs_context context
; 
2232                          * Controlling process. 
2233                          * Signal foreground pgrp, 
2234                          * drain controlling terminal 
2235                          * and revoke access to controlling terminal. 
2237                         session_lock(sessp
); 
2238                         tp 
= SESSION_TP(sessp
); 
2239                         if ((tp 
!= TTY_NULL
) && (tp
->t_session 
== sessp
)) { 
2240                                 session_unlock(sessp
); 
2243                                  * We're going to SIGHUP the foreground process 
2244                                  * group. It can't change from this point on 
2245                                  * until the revoke is complete. 
2246                                  * The process group changes under both the tty 
2247                                  * lock and proc_list_lock but we need only one 
2253                                 tty_pgsignal(tp
, SIGHUP
, 1); 
2255                                 session_lock(sessp
); 
2256                                 tp 
= SESSION_TP(sessp
); 
2258                         cttyflag 
= sessp
->s_flags 
& S_CTTYREF
; 
2259                         sessp
->s_flags 
&= ~S_CTTYREF
; 
2260                         ttyvp 
= sessp
->s_ttyvp
; 
2261                         ttyvid 
= sessp
->s_ttyvid
; 
2262                         sessp
->s_ttyvp 
= NULL
; 
2263                         sessp
->s_ttyvid 
= 0; 
2264                         sessp
->s_ttyp 
= TTY_NULL
; 
2265                         sessp
->s_ttypgrpid 
= NO_PID
; 
2266                         session_unlock(sessp
); 
2268                        if ((ttyvp 
!= NULLVP
) && (vnode_getwithvid(ttyvp
, ttyvid
) == 0)) { 
2269                                 if (tp 
!= TTY_NULL
) { 
2274                                 context
.vc_thread 
= proc_thread(p
); /* XXX */ 
2275                                 context
.vc_ucred 
= kauth_cred_proc_ref(p
); 
2276                                 VNOP_REVOKE(ttyvp
, REVOKEALL
, &context
); 
2279                                          * Release the extra usecount taken in cttyopen. 
2280                                          * usecount should be released after VNOP_REVOKE is called. 
2281                                          * This usecount was taken to ensure that 
2282                                          * the VNOP_REVOKE results in a close to 
2283                                          * the tty since cttyclose is a no-op. 
2288                                 kauth_cred_unref(&context
.vc_ucred
); 
2293                                  * This is cleared even if not set. This is also done in 
2294                                  * spec_close to ensure that the flag is cleared. 
2303                 session_lock(sessp
); 
2304                 sessp
->s_leader 
= NULL
; 
2305                 session_unlock(sessp
); 
2307         session_rele(sessp
); 
2313         p
->p_rlimit
[RLIMIT_FSIZE
].rlim_cur 
= RLIM_INFINITY
; 
2316         proc_childdrainstart(p
); 
2317         while ((q 
= p
->p_children
.lh_first
) != NULL
) { 
2318                 if (q
->p_stat 
== SZOMB
) { 
2320                                 panic("parent child linkage broken"); 
2321                         /* check for lookups by zomb sysctl */ 
2322                         while ((q
->p_listflag 
& P_LIST_WAITING
) == P_LIST_WAITING
) { 
2323                                 msleep(&q
->p_stat
, proc_list_mlock
, PWAIT
, "waitcoll", 0); 
2325                         q
->p_listflag 
|= P_LIST_WAITING
; 
2327                          * This is a named reference and it is not granted 
2328                          * if the reap is already in progress. So we get 
2329                          * the reference here exclusively and their can be 
2330                          * no waiters. So there is no need for a wakeup 
2331                          * after we are done. AlsO  the reap frees the structure 
2332                          * and the proc struct cannot be used for wakeups as well.  
2333                          * It is safe to use q here as this is system reap 
2335                         (void)reap_child_locked(p
, q
, 1, 0, 1, 0); 
2338                         * Traced processes are killed 
2339                         * since their existence means someone is messing up. 
2341                         if (q
->p_lflag 
& P_LTRACED
) { 
2346                                 opp 
= proc_find(q
->p_oppid
); 
2347                                 if (opp 
!= PROC_NULL
) { 
2351                                         proc_reparentlocked(q
, opp
, 0, 0); 
2354                                         /* original parent exited while traced */ 
2356                                         q
->p_listflag 
|= P_LIST_DEADPARENT
; 
2359                                         proc_reparentlocked(q
, initproc
, 0, 0); 
2363                                 q
->p_lflag 
&= ~P_LTRACED
; 
2365                                 if (q
->sigwait_thread
) { 
2366                                         thread_t thread 
= q
->sigwait_thread
; 
2370                                         * The sigwait_thread could be stopped at a 
2371                                         * breakpoint. Wake it up to kill. 
2372                                         * Need to do this as it could be a thread which is not 
2373                                         * the first thread in the task. So any attempts to kill 
2374                                         * the process would result into a deadlock on q->sigwait. 
2376                                         thread_resume(thread
); 
2377                                         clear_wait(thread
, THREAD_INTERRUPTED
); 
2378                                         threadsignal(thread
, SIGKILL
, 0, TRUE
); 
2383                                 psignal(q
, SIGKILL
); 
2386                                 q
->p_listflag 
|= P_LIST_DEADPARENT
; 
2387                                 proc_reparentlocked(q
, initproc
, 0, 1); 
2392         proc_childdrainend(p
); 
2396          * Release reference to text vnode 
2400         if (tvp 
!= NULLVP
) { 
2405          * Save exit status and final rusage info, adding in child rusage 
2406          * info and self times.  If we were unable to allocate a zombie 
2407          * structure, this information is lost. 
2410             rup
->ru 
= p
->p_stats
->p_ru
; 
2411             timerclear(&rup
->ru
.ru_utime
); 
2412             timerclear(&rup
->ru
.ru_stime
); 
2416                 mach_task_basic_info_data_t tinfo
; 
2417                 task_thread_times_info_data_t ttimesinfo
; 
2418                 int task_info_stuff
, task_ttimes_stuff
; 
2419                 struct timeval ut
,st
; 
2421                 task_info_stuff 
= MACH_TASK_BASIC_INFO_COUNT
; 
2422                 task_info(task
, MACH_TASK_BASIC_INFO
, 
2423                           &tinfo
, &task_info_stuff
); 
2424                 p
->p_ru
->ru
.ru_utime
.tv_sec 
= tinfo
.user_time
.seconds
; 
2425                 p
->p_ru
->ru
.ru_utime
.tv_usec 
= tinfo
.user_time
.microseconds
; 
2426                 p
->p_ru
->ru
.ru_stime
.tv_sec 
= tinfo
.system_time
.seconds
; 
2427                 p
->p_ru
->ru
.ru_stime
.tv_usec 
= tinfo
.system_time
.microseconds
; 
2429                 task_ttimes_stuff 
= TASK_THREAD_TIMES_INFO_COUNT
; 
2430                 task_info(task
, TASK_THREAD_TIMES_INFO
, 
2431                           &ttimesinfo
, &task_ttimes_stuff
); 
2433                 ut
.tv_sec 
= ttimesinfo
.user_time
.seconds
; 
2434                 ut
.tv_usec 
= ttimesinfo
.user_time
.microseconds
; 
2435                 st
.tv_sec 
= ttimesinfo
.system_time
.seconds
; 
2436                 st
.tv_usec 
= ttimesinfo
.system_time
.microseconds
; 
2437                 timeradd(&ut
,&p
->p_ru
->ru
.ru_utime
,&p
->p_ru
->ru
.ru_utime
); 
2438                         timeradd(&st
,&p
->p_ru
->ru
.ru_stime
,&p
->p_ru
->ru
.ru_stime
); 
2442             ruadd(&rup
->ru
, &p
->p_stats
->p_cru
); 
2444                 gather_rusage_info(p
, &rup
->ri
, RUSAGE_INFO_CURRENT
); 
2445                 rup
->ri
.ri_phys_footprint 
= 0; 
2446                 rup
->ri
.ri_proc_exit_abstime 
= mach_absolute_time(); 
2449                  * Now that we have filled in the rusage info, make it 
2450                  * visible to an external observer via proc_pid_rusage(). 
2456          * Free up profiling buffers. 
2459                 struct uprof 
*p0 
= &p
->p_stats
->p_prof
, *p1
, *pn
; 
2465                 for (; p1 
!= NULL
; p1 
= pn
) { 
2467                         kfree(p1
, sizeof *p1
); 
2472         pth_proc_hashdelete(p
); 
2476          * Other substructures are freed from wait(). 
2478         FREE_ZONE(p
->p_stats
, sizeof *p
->p_stats
, M_PSTATS
); 
2481         FREE_ZONE(p
->p_sigacts
, sizeof *p
->p_sigacts
, M_SIGACTS
); 
2482         p
->p_sigacts 
= NULL
; 
2484         proc_limitdrop(p
, 1); 
2488          * Finish up by terminating the task 
2489          * and halt this thread (only if a 
2490          * member of the task exiting). 
2492         p
->task 
= TASK_NULL
; 
2495          * Notify parent that we're gone. 
2497         pp 
= proc_parent(p
); 
2498         if ((p
->p_listflag 
& P_LIST_DEADPARENT
) == 0) { 
2499                 if (pp 
!= initproc
) { 
2501                         pp
->si_pid 
= p
->p_pid
; 
2502                         pp
->si_status 
= p
->p_xstat
; 
2503                         pp
->si_code 
= CLD_EXITED
; 
2505                          * p_ucred usage is safe as it is an exiting process 
2506                          * and reference is dropped in reap 
2508                         pp
->si_uid 
= kauth_cred_getruid(p
->p_ucred
); 
2511                 /* mark as a zombie */ 
2512                 /* mark as a zombie */ 
2513                 /* No need to take proc lock as all refs are drained and 
2514                  * no one except parent (reaping ) can look at this. 
2515                  * The write is to an int and is coherent. Also parent is 
2516                  *  keyed off of list lock for reaping 
2520                 psignal(pp
, SIGCHLD
); 
2522                 /* and now wakeup the parent */ 
2524                 wakeup((caddr_t
)pp
); 
2528                 /* check for lookups by zomb sysctl */ 
2529                 while ((p
->p_listflag 
& P_LIST_WAITING
) == P_LIST_WAITING
) { 
2530                         msleep(&p
->p_stat
, proc_list_mlock
, PWAIT
, "waitcoll", 0); 
2533                 p
->p_listflag 
|= P_LIST_WAITING
; 
2536                  * This is a named reference and it is not granted 
2537                  * if the reap is already in progress. So we get 
2538                  * the reference here exclusively and their can be 
2539                  * no waiters. So there is no need for a wakeup 
2540                  * after we are done. AlsO  the reap frees the structure 
2541                  * and the proc struct cannot be used for wakeups as well.  
2542                  * It is safe to use p here as this is system reap 
2544                 (void)reap_child_locked(pp
, p
, 0, 0, 1, 1); 
2545                 /* list lock dropped by reap_child_locked */ 
2553  *      LP64 support - long is 64 bits if we are dealing with a 64 bit user 
2554  *      process.  We munge the kernel version of rusage into the 
2557 __private_extern__  
void  
2558 munge_user64_rusage(struct rusage 
*a_rusage_p
, struct user64_rusage 
*a_user_rusage_p
) 
2560         /* timeval changes size, so utime and stime need special handling */ 
2561         a_user_rusage_p
->ru_utime
.tv_sec 
= a_rusage_p
->ru_utime
.tv_sec
; 
2562         a_user_rusage_p
->ru_utime
.tv_usec 
= a_rusage_p
->ru_utime
.tv_usec
; 
2563         a_user_rusage_p
->ru_stime
.tv_sec 
= a_rusage_p
->ru_stime
.tv_sec
; 
2564         a_user_rusage_p
->ru_stime
.tv_usec 
= a_rusage_p
->ru_stime
.tv_usec
; 
2566          * everything else can be a direct assign, since there is no loss 
2567          * of precision implied boing 32->64. 
2569         a_user_rusage_p
->ru_maxrss 
= a_rusage_p
->ru_maxrss
; 
2570         a_user_rusage_p
->ru_ixrss 
= a_rusage_p
->ru_ixrss
; 
2571         a_user_rusage_p
->ru_idrss 
= a_rusage_p
->ru_idrss
; 
2572         a_user_rusage_p
->ru_isrss 
= a_rusage_p
->ru_isrss
; 
2573         a_user_rusage_p
->ru_minflt 
= a_rusage_p
->ru_minflt
; 
2574         a_user_rusage_p
->ru_majflt 
= a_rusage_p
->ru_majflt
; 
2575         a_user_rusage_p
->ru_nswap 
= a_rusage_p
->ru_nswap
; 
2576         a_user_rusage_p
->ru_inblock 
= a_rusage_p
->ru_inblock
; 
2577         a_user_rusage_p
->ru_oublock 
= a_rusage_p
->ru_oublock
; 
2578         a_user_rusage_p
->ru_msgsnd 
= a_rusage_p
->ru_msgsnd
; 
2579         a_user_rusage_p
->ru_msgrcv 
= a_rusage_p
->ru_msgrcv
; 
2580         a_user_rusage_p
->ru_nsignals 
= a_rusage_p
->ru_nsignals
; 
2581         a_user_rusage_p
->ru_nvcsw 
= a_rusage_p
->ru_nvcsw
; 
2582         a_user_rusage_p
->ru_nivcsw 
= a_rusage_p
->ru_nivcsw
; 
2585 /* For a 64-bit kernel and 32-bit userspace, munging may be needed */ 
2586 __private_extern__  
void  
2587 munge_user32_rusage(struct rusage 
*a_rusage_p
, struct user32_rusage 
*a_user_rusage_p
) 
2589         /* timeval changes size, so utime and stime need special handling */ 
2590         a_user_rusage_p
->ru_utime
.tv_sec 
= a_rusage_p
->ru_utime
.tv_sec
; 
2591         a_user_rusage_p
->ru_utime
.tv_usec 
= a_rusage_p
->ru_utime
.tv_usec
; 
2592         a_user_rusage_p
->ru_stime
.tv_sec 
= a_rusage_p
->ru_stime
.tv_sec
; 
2593         a_user_rusage_p
->ru_stime
.tv_usec 
= a_rusage_p
->ru_stime
.tv_usec
; 
2595          * everything else can be a direct assign. We currently ignore 
2596          * the loss of precision 
2598         a_user_rusage_p
->ru_maxrss 
= a_rusage_p
->ru_maxrss
; 
2599         a_user_rusage_p
->ru_ixrss 
= a_rusage_p
->ru_ixrss
; 
2600         a_user_rusage_p
->ru_idrss 
= a_rusage_p
->ru_idrss
; 
2601         a_user_rusage_p
->ru_isrss 
= a_rusage_p
->ru_isrss
; 
2602         a_user_rusage_p
->ru_minflt 
= a_rusage_p
->ru_minflt
; 
2603         a_user_rusage_p
->ru_majflt 
= a_rusage_p
->ru_majflt
; 
2604         a_user_rusage_p
->ru_nswap 
= a_rusage_p
->ru_nswap
; 
2605         a_user_rusage_p
->ru_inblock 
= a_rusage_p
->ru_inblock
; 
2606         a_user_rusage_p
->ru_oublock 
= a_rusage_p
->ru_oublock
; 
2607         a_user_rusage_p
->ru_msgsnd 
= a_rusage_p
->ru_msgsnd
; 
2608         a_user_rusage_p
->ru_msgrcv 
= a_rusage_p
->ru_msgrcv
; 
2609         a_user_rusage_p
->ru_nsignals 
= a_rusage_p
->ru_nsignals
; 
2610         a_user_rusage_p
->ru_nvcsw 
= a_rusage_p
->ru_nvcsw
; 
2611         a_user_rusage_p
->ru_nivcsw 
= a_rusage_p
->ru_nivcsw
;