1/* 2 * Copyright (c) 2005-2006 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * The contents of this file constitute Original Code as defined in and 7 * are subject to the Apple Public Source License Version 1.1 (the 8 * "License"). You may not use this file except in compliance with the 9 * License. Please obtain a copy of the License at 10 * http://www.apple.com/publicsource and read it before using this file. 11 * 12 * This Original Code and all software distributed under the License are 13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER 14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the 17 * License for the specific language governing rights and limitations 18 * under the License. 19 * 20 * @APPLE_LICENSE_HEADER_END@ 21 */ 22 23inline int UT_VFORK = 0x02000000; /* thread has vfork children */ 24#pragma D binding "1.0" UT_VFORK 25 26inline uthread_t uthread = (mach_kernel`uthread_t)(curthread->uthread); /* ` */ 27#pragma D binding "1.0" uthread 28 29inline struct proc * curproc = 30 (uthread && (uthread->uu_flag & UT_VFORK) && uthread->uu_proc) ? (struct proc *)uthread->uu_proc : 31 ((struct proc *)(curthread->task->bsd_info)) != NULL ? ((struct proc *)(curthread->task->bsd_info)) : 32 mach_kernel`kernproc; /* ` */ 33#pragma D binding "1.0" curproc 34 35/* 36 * curthread->thread_tag will have this set if the thread is the main thread 37 */ 38inline uint32_t THREAD_TAG_MAINTHREAD = 0x1; 39inline uint32_t THREAD_TAG_CALLOUT = 0x2; 40inline uint32_t THREAD_TAG_IOWORKLOOP = 0x4; 41 42/* 43 * mach thread scheduler state 44 */ 45inline int TH_WAIT = 0x01; 46#pragma D binding "1.0" TH_WAIT 47inline int TH_SUSP = 0x02; 48#pragma D binding "1.0" TH_SUSP 49inline int TH_RUN = 0x04; 50#pragma D binding "1.0" TH_RUN 51inline int TH_UNINT = 0x08; 52#pragma D binding "1.0" TH_UNINT 53inline int TH_TERMINATE = 0x10; 54#pragma D binding "1.0" TH_TERMINATE 55inline int TH_TERMINATE2 = 0x20; 56#pragma D binding "1.0" TH_TERMINATE2 57inline int TH_IDLE = 0x80; 58#pragma D binding "1.0" TH_IDLE 59 60/* 61 * The following miscellaneous constants are used by the proc(4) translators 62 * defined below. 63 */ 64inline char SIDL = 1; 65#pragma D binding "1.0" SIDL 66inline char SRUN = 2; 67#pragma D binding "1.0" SRUN 68inline char SSLEEP = 3; 69#pragma D binding "1.0" SSLEEP 70inline char SSTOP = 4; 71#pragma D binding "1.0" SSTOP 72inline char SZOMB = 5; 73#pragma D binding "1.0" SZOMB 74/* 75 * SONPROC defined here for compatability with ported scripts 76 */ 77inline char SONPROC = 6; 78#pragma D binding "1.0" SONPROC 79 80inline char SOBJ_NONE = 0; 81#pragma D binding "1.0" SOBJ_NONE 82/* 83 * SOBJ_* defined here for compatability with ported scripts 84 */ 85inline char SOBJ_MUTEX = 1; 86#pragma D binding "1.0" SOBJ_MUTEX 87inline char SOBJ_RWLOCK = 2; 88#pragma D binding "1.0" SOBJ_RWLOCK 89inline char SOBJ_CV = 3; 90#pragma D binding "1.0" SOBJ_CV 91inline char SOBJ_SEMA = 4; 92#pragma D binding "1.0" SOBJ_SEMA 93inline char SOBJ_USER = 5; 94#pragma D binding "1.0" SOBJ_USER 95inline char SOBJ_USER_PI = 6; 96#pragma D binding "1.0" SOBJ_USER_PI 97inline char SOBJ_SHUTTLE = 7; 98#pragma D binding "1.0" SOBJ_SHUTTLE 99 100inline char PR_MODEL_ILP32 = 1; 101#pragma D binding "1.0" PR_MODEL_ILP32 102inline char PR_MODEL_LP64 = 2; 103#pragma D binding "1.0" PR_MODEL_LP64 104 105/* 106 * PR_* defined here for compatability with ported scripts 107 */ 108inline int PR_STOPPED = 0x00000001; 109#pragma D binding "1.0" PR_STOPPED 110inline int PR_ISTOP = 0x00000002; 111#pragma D binding "1.0" PR_ISTOP 112inline int PR_DSTOP = 0x00000004; 113#pragma D binding "1.0" PR_DSTOP 114inline int PR_STEP = 0x00000008; 115#pragma D binding "1.0" PR_STEP 116inline int PR_ASLEEP = 0x00000010; 117#pragma D binding "1.0" PR_ASLEEP 118inline int PR_PCINVAL = 0x00000020; 119#pragma D binding "1.0" PR_PCINVAL 120inline int PR_ASLWP = 0x00000040; 121#pragma D binding "1.0" PR_ASLWP 122inline int PR_AGENT = 0x00000080; 123#pragma D binding "1.0" PR_AGENT 124inline int PR_DETACH = 0x00000100; 125#pragma D binding "1.0" PR_DETACH 126inline int PR_DAEMON = 0x00000200; 127#pragma D binding "1.0" PR_DAEMON 128inline int PR_ISSYS = 0x00001000; 129#pragma D binding "1.0" PR_ISSYS 130inline int PR_VFORKP = 0x00002000; 131#pragma D binding "1.0" PR_VFORKP 132inline int PR_ORPHAN = 0x00004000; 133#pragma D binding "1.0" PR_ORPHAN 134inline int PR_FORK = 0x00100000; 135#pragma D binding "1.0" PR_FORK 136inline int PR_RLC = 0x00200000; 137#pragma D binding "1.0" PR_RLC 138inline int PR_KLC = 0x00400000; 139#pragma D binding "1.0" PR_KLC 140inline int PR_ASYNC = 0x00800000; 141#pragma D binding "1.0" PR_ASYNC 142inline int PR_MSACCT = 0x01000000; 143#pragma D binding "1.0" PR_MSACCT 144inline int PR_BPTADJ = 0x02000000; 145#pragma D binding "1.0" PR_BPTADJ 146inline int PR_PTRACE = 0x04000000; 147#pragma D binding "1.0" PR_PTRACE 148inline int PR_MSFORK = 0x08000000; 149#pragma D binding "1.0" PR_MSFORK 150inline int PR_IDLE = 0x10000000; 151#pragma D binding "1.0" PR_IDLE 152 153/* 154 * Translate from the kernel's proc_t structure to a proc(4) psinfo_t struct. 155 * We do not provide support for pr_size, pr_rssize, pr_pctcpu, and pr_pctmem. 156 * We also do not fill in pr_lwp (the lwpsinfo_t for the representative LWP) 157 * because we do not have the ability to select and stop any representative. 158 * Also, for the moment, pr_wstat, pr_time, and pr_ctime are not supported, 159 * but these could be supported by DTrace in the future using subroutines. 160 * Note that any member added to this translator should also be added to the 161 * kthread_t-to-psinfo_t translator, below. 162 */ 163typedef int taskid_t; 164typedef int projid_t; 165typedef int poolid_t; 166typedef struct timespec timestruc_t; /* (SECONDS, NANOSECONDS) */ 167 168typedef struct psinfo { 169 int pr_nlwp; /* number of active lwps in the process */ 170 pid_t pr_pid; /* unique process id */ 171 pid_t pr_ppid; /* process id of parent */ 172 pid_t pr_pgid; /* pid of process group leader */ 173 pid_t pr_sid; /* session id */ 174 uid_t pr_uid; /* real user id */ 175 uid_t pr_euid; /* effective user id */ 176 gid_t pr_gid; /* real group id */ 177 gid_t pr_egid; /* effective group id */ 178 uintptr_t pr_addr; /* address of process */ 179 dev_t pr_ttydev; /* controlling tty device (or PRNODEV) */ 180 timestruc_t pr_start;/* process start time, DEPRECATED, see pr_start_tv below */ 181 char pr_fname[16]; /* name of execed file */ 182 char pr_psargs[80]; /* initial characters of arg list */ 183 int pr_argc; /* initial argument count */ 184 user_addr_t pr_argv; /* address of initial argument vector */ 185 user_addr_t pr_envp; /* address of initial environment vector */ 186 char pr_dmodel; /* data model of the process */ 187 taskid_t pr_taskid; /* task id */ 188 projid_t pr_projid; /* project id */ 189 poolid_t pr_poolid; /* pool id */ 190 zoneid_t pr_zoneid; /* zone id */ 191 192 struct timeval pr_start_tv; /* process start time, from the epoch (SECONDS, MICROSECONDS) */ 193} psinfo_t; 194 195inline int P_LP64 = 0x00000004; /* Process is LP64 */ 196#pragma D binding "1.0" P_LP64 197 198#pragma D binding "1.0" translator 199translator psinfo_t < struct proc * P > { 200 pr_nlwp = ((struct task *)(P->task))->thread_count; 201 pr_pid = P->p_pid; 202 pr_ppid = P->p_ppid; 203 pr_pgid = P->p_pgrp->pg_id; 204 pr_sid = P->p_pgrp->pg_session->s_sid; 205 pr_uid = P->p_ucred->cr_posix.cr_ruid; 206 pr_euid = P->p_ucred->cr_posix.cr_uid; 207 pr_gid = P->p_ucred->cr_posix.cr_rgid; 208 pr_egid = P->p_ucred->cr_posix.cr_groups[0]; 209 pr_addr = (uintptr_t)P; 210 211 pr_ttydev = (P->p_pgrp->pg_session->s_ttyvp == NULL) ? (dev_t)-1 : 212 P->p_pgrp->pg_session->s_ttyp->t_dev; 213 214 /* 215 * timestruct_t (SECONDS, NANOSECONDS) is not available directly nor can a further translation 216 * be specified here. Zero the structure. Use pr_start_tv instead. 217 */ 218 pr_start = *((timestruc_t *)`dtrace_zero); /* ` */ 219 220 pr_fname = P->p_comm; 221 pr_psargs = P->p_comm; /* XXX omits command line arguments XXX */ 222 pr_argc = P->p_argc; 223 pr_argv = P->p_dtrace_argv; 224 pr_envp = P->p_dtrace_envp; 225 226 pr_dmodel = (P->p_flag & P_LP64) ? PR_MODEL_LP64 : PR_MODEL_ILP32; 227 228 pr_taskid = 0; 229 pr_projid = 0; 230 pr_poolid = 0; 231 pr_zoneid = 0; 232 233 /* 234 * pstats->pstart is a struct timeval: (SECONDS, MICROSECONDS). 235 */ 236 pr_start_tv = P->p_start; 237}; 238 239/* 240 * Translate from the kernel's kthread_t structure to a proc(4) psinfo_t 241 * struct. Lacking a facility to define one translator only in terms of 242 * another, we explicitly define each member by using the proc_t-to-psinfo_t 243 * translator, above; any members added to that translator should also be 244 * added here. (The only exception to this is pr_start, which -- due to it 245 * being a structure -- cannot be defined in terms of a translator at all.) 246 */ 247#pragma D binding "1.0" translator 248translator psinfo_t < thread_t T > { 249 pr_nlwp = xlate <psinfo_t> ((struct proc *)(T->task->bsd_info)).pr_nlwp; 250 pr_pid = xlate <psinfo_t> ((struct proc *)(T->task->bsd_info)).pr_pid; 251 pr_ppid = xlate <psinfo_t> ((struct proc *)(T->task->bsd_info)).pr_ppid; 252 pr_pgid = xlate <psinfo_t> ((struct proc *)(T->task->bsd_info)).pr_pgid; 253 pr_sid = xlate <psinfo_t> ((struct proc *)(T->task->bsd_info)).pr_sid; 254 pr_uid = xlate <psinfo_t> ((struct proc *)(T->task->bsd_info)).pr_uid; 255 pr_euid = xlate <psinfo_t> ((struct proc *)(T->task->bsd_info)).pr_euid; 256 pr_gid = xlate <psinfo_t> ((struct proc *)(T->task->bsd_info)).pr_gid; 257 pr_egid = xlate <psinfo_t> ((struct proc *)(T->task->bsd_info)).pr_egid; 258 pr_addr = xlate <psinfo_t> ((struct proc *)(T->task->bsd_info)).pr_addr; 259 pr_ttydev = xlate <psinfo_t> ((struct proc *)(T->task->bsd_info)).pr_ttydev; 260 pr_start = xlate <psinfo_t> ((struct proc *)(T->task->bsd_info)).pr_start; 261 pr_fname = xlate <psinfo_t> ((struct proc *)(T->task->bsd_info)).pr_fname; 262 pr_psargs = xlate <psinfo_t> ((struct proc *)(T->task->bsd_info)).pr_psargs; /* XXX omits command line arguments XXX */ 263 pr_argc = xlate <psinfo_t> ((struct proc *)(T->task->bsd_info)).pr_argc; 264 pr_argv = xlate <psinfo_t> ((struct proc *)(T->task->bsd_info)).pr_argv; 265 pr_envp = xlate <psinfo_t> ((struct proc *)(T->task->bsd_info)).pr_envp; 266 pr_dmodel = xlate <psinfo_t> ((struct proc *)(T->task->bsd_info)).pr_dmodel; 267 pr_taskid = xlate <psinfo_t> ((struct proc *)(T->task->bsd_info)).pr_taskid; 268 pr_projid = xlate <psinfo_t> ((struct proc *)(T->task->bsd_info)).pr_projid; 269 pr_poolid = xlate <psinfo_t> ((struct proc *)(T->task->bsd_info)).pr_poolid; 270 pr_zoneid = xlate <psinfo_t> ((struct proc *)(T->task->bsd_info)).pr_zoneid; 271 272 pr_start_tv = xlate <psinfo_t> ((struct proc *)(T->task->bsd_info)).pr_start_tv; 273}; 274 275/* 276 * Translate from the kernel's kthread_t structure to a proc(4) lwpsinfo_t. 277 * We do not provide support for pr_nice, pr_oldpri, pr_cpu, or pr_pctcpu. 278 * Also, for the moment, pr_start and pr_time are not supported, but these 279 * could be supported by DTrace in the future using subroutines. 280 */ 281 282inline processor_t PROCESSOR_NULL = ((processor_t) 0); 283#pragma D binding "1.0" PROCESSOR_NULL 284 285typedef int psetid_t; 286 287typedef struct lwpsinfo { 288 int pr_flag; /* lwp flags (DEPRECATED; do not use) */ 289 id_t pr_lwpid; /* lwp id */ 290 uintptr_t pr_addr; /* internal address of lwp */ 291 uintptr_t pr_wchan; /* wait addr for sleeping lwp */ 292 char pr_stype; /* synchronization event type */ 293 char pr_state; /* numeric lwp state */ 294 char pr_sname; /* printable character for pr_state */ 295 short pr_syscall; /* system call number (if in syscall) */ 296 int pr_pri; /* priority, high value is high priority */ 297 char pr_clname[8]; /* scheduling class name */ 298 int pr_thstate; /* mach thread scheduler state */ 299 processorid_t pr_onpro; /* processor which last ran this lwp */ 300 processorid_t pr_bindpro; /* processor to which lwp is bound */ 301 psetid_t pr_bindpset; /* processor set to which lwp is bound */ 302} lwpsinfo_t; 303 304#pragma D binding "1.0" translator 305translator lwpsinfo_t < thread_t T > { 306 pr_flag = 0; /* lwp flags (DEPRECATED; do not use) */ 307 pr_lwpid = (id_t)T->thread_id; 308 pr_addr = (uintptr_t)T; 309 pr_wchan = (uintptr_t)(((uthread_t)(T->uthread))->uu_wchan); 310 311 pr_stype = SOBJ_NONE; /* XXX Undefined synch object (or none) XXX */ 312 pr_state = curproc->p_stat; 313 pr_sname = (curproc->p_stat == SIDL) ? 'I' : 314 (curproc->p_stat == SRUN) ? 'R' : 315 (curproc->p_stat == SSLEEP) ? 'S' : 316 (curproc->p_stat == SSTOP) ? 'T' : 317 (curproc->p_stat == SZOMB) ? 'Z' : '?'; 318 319 pr_syscall = ((uthread_t)(T->uthread))->uu_code; 320 pr_pri = T->sched_pri; 321 322 pr_clname = (T->sched_mode & 0x0001) ? "RT" : 323 (T->sched_mode & 0x0002) ? "TS" : "SYS"; 324 325 pr_onpro = (T->last_processor == PROCESSOR_NULL) ? -1 : T->last_processor->cpu_id; 326 pr_bindpro = -1; /* Darwin does not bind threads to processors. */ 327 pr_bindpset = -1; /* Darwin does not partition processors. */ 328 pr_thstate = T->state; 329}; 330 331inline psinfo_t *curpsinfo = xlate <psinfo_t *> (curproc); 332#pragma D attributes Stable/Stable/Common curpsinfo 333#pragma D binding "1.0" curpsinfo 334 335inline lwpsinfo_t *curlwpsinfo = xlate <lwpsinfo_t *> (curthread); 336#pragma D attributes Stable/Stable/Common curlwpsinfo 337#pragma D binding "1.0" curlwpsinfo 338 339/* XXX Really want vn_getpath(curproc->p_fd->fd_cdir, , ) but that takes namecache_rw_lock XXX */ 340inline string cwd = curproc->p_fd->fd_cdir->v_name == NULL ? 341 "<unknown>" : stringof(curproc->p_fd->fd_cdir->v_name); 342#pragma D attributes Stable/Stable/Common cwd 343#pragma D binding "1.0" cwd 344 345/* XXX Really want vn_getpath(curproc->p_fd->fd_rdir, , ) but that takes namecache_rw_lock XXX */ 346inline string root = curproc->p_fd->fd_rdir == NULL ? "/" : 347 curproc->p_fd->fd_rdir->v_name == NULL ? "<unknown>" : 348 stringof(curproc->p_fd->fd_rdir->v_name); 349#pragma D attributes Stable/Stable/Common root 350#pragma D binding "1.0" root 351