]>
Commit | Line | Data |
---|---|---|
39236c6e A |
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 | ||
23 | inline int UT_VFORK = 0x02000000; /* thread has vfork children */ | |
24 | #pragma D binding "1.0" UT_VFORK | |
25 | ||
26 | inline uthread_t uthread = (mach_kernel`uthread_t)(curthread->uthread); /* ` */ | |
27 | #pragma D binding "1.0" uthread | |
28 | ||
29 | inline 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 | */ | |
38 | inline uint32_t THREAD_TAG_MAINTHREAD = 0x1; | |
39 | inline uint32_t THREAD_TAG_CALLOUT = 0x2; | |
40 | inline uint32_t THREAD_TAG_IOWORKLOOP = 0x4; | |
41 | ||
fe8ab488 A |
42 | /* |
43 | * mach thread scheduler state | |
44 | */ | |
45 | inline int TH_WAIT = 0x01; | |
46 | #pragma D binding "1.0" TH_WAIT | |
47 | inline int TH_SUSP = 0x02; | |
48 | #pragma D binding "1.0" TH_SUSP | |
49 | inline int TH_RUN = 0x04; | |
50 | #pragma D binding "1.0" TH_RUN | |
51 | inline int TH_UNINT = 0x08; | |
52 | #pragma D binding "1.0" TH_UNINT | |
53 | inline int TH_TERMINATE = 0x10; | |
54 | #pragma D binding "1.0" TH_TERMINATE | |
55 | inline int TH_TERMINATE2 = 0x20; | |
56 | #pragma D binding "1.0" TH_TERMINATE2 | |
57 | inline int TH_IDLE = 0x80; | |
58 | #pragma D binding "1.0" TH_IDLE | |
59 | ||
39236c6e A |
60 | /* |
61 | * The following miscellaneous constants are used by the proc(4) translators | |
62 | * defined below. | |
63 | */ | |
64 | inline char SIDL = 1; | |
65 | #pragma D binding "1.0" SIDL | |
66 | inline char SRUN = 2; | |
67 | #pragma D binding "1.0" SRUN | |
68 | inline char SSLEEP = 3; | |
69 | #pragma D binding "1.0" SSLEEP | |
70 | inline char SSTOP = 4; | |
71 | #pragma D binding "1.0" SSTOP | |
72 | inline char SZOMB = 5; | |
73 | #pragma D binding "1.0" SZOMB | |
74 | /* | |
75 | * SONPROC defined here for compatability with ported scripts | |
76 | */ | |
77 | inline char SONPROC = 6; | |
78 | #pragma D binding "1.0" SONPROC | |
79 | ||
80 | inline char SOBJ_NONE = 0; | |
81 | #pragma D binding "1.0" SOBJ_NONE | |
82 | /* | |
83 | * SOBJ_* defined here for compatability with ported scripts | |
84 | */ | |
85 | inline char SOBJ_MUTEX = 1; | |
86 | #pragma D binding "1.0" SOBJ_MUTEX | |
87 | inline char SOBJ_RWLOCK = 2; | |
88 | #pragma D binding "1.0" SOBJ_RWLOCK | |
89 | inline char SOBJ_CV = 3; | |
90 | #pragma D binding "1.0" SOBJ_CV | |
91 | inline char SOBJ_SEMA = 4; | |
92 | #pragma D binding "1.0" SOBJ_SEMA | |
93 | inline char SOBJ_USER = 5; | |
94 | #pragma D binding "1.0" SOBJ_USER | |
95 | inline char SOBJ_USER_PI = 6; | |
96 | #pragma D binding "1.0" SOBJ_USER_PI | |
97 | inline char SOBJ_SHUTTLE = 7; | |
98 | #pragma D binding "1.0" SOBJ_SHUTTLE | |
99 | ||
100 | inline char PR_MODEL_ILP32 = 1; | |
101 | #pragma D binding "1.0" PR_MODEL_ILP32 | |
102 | inline 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 | */ | |
108 | inline int PR_STOPPED = 0x00000001; | |
109 | #pragma D binding "1.0" PR_STOPPED | |
110 | inline int PR_ISTOP = 0x00000002; | |
111 | #pragma D binding "1.0" PR_ISTOP | |
112 | inline int PR_DSTOP = 0x00000004; | |
113 | #pragma D binding "1.0" PR_DSTOP | |
114 | inline int PR_STEP = 0x00000008; | |
115 | #pragma D binding "1.0" PR_STEP | |
116 | inline int PR_ASLEEP = 0x00000010; | |
117 | #pragma D binding "1.0" PR_ASLEEP | |
118 | inline int PR_PCINVAL = 0x00000020; | |
119 | #pragma D binding "1.0" PR_PCINVAL | |
120 | inline int PR_ASLWP = 0x00000040; | |
121 | #pragma D binding "1.0" PR_ASLWP | |
122 | inline int PR_AGENT = 0x00000080; | |
123 | #pragma D binding "1.0" PR_AGENT | |
124 | inline int PR_DETACH = 0x00000100; | |
125 | #pragma D binding "1.0" PR_DETACH | |
126 | inline int PR_DAEMON = 0x00000200; | |
127 | #pragma D binding "1.0" PR_DAEMON | |
128 | inline int PR_ISSYS = 0x00001000; | |
129 | #pragma D binding "1.0" PR_ISSYS | |
130 | inline int PR_VFORKP = 0x00002000; | |
131 | #pragma D binding "1.0" PR_VFORKP | |
132 | inline int PR_ORPHAN = 0x00004000; | |
133 | #pragma D binding "1.0" PR_ORPHAN | |
134 | inline int PR_FORK = 0x00100000; | |
135 | #pragma D binding "1.0" PR_FORK | |
136 | inline int PR_RLC = 0x00200000; | |
137 | #pragma D binding "1.0" PR_RLC | |
138 | inline int PR_KLC = 0x00400000; | |
139 | #pragma D binding "1.0" PR_KLC | |
140 | inline int PR_ASYNC = 0x00800000; | |
141 | #pragma D binding "1.0" PR_ASYNC | |
142 | inline int PR_MSACCT = 0x01000000; | |
143 | #pragma D binding "1.0" PR_MSACCT | |
144 | inline int PR_BPTADJ = 0x02000000; | |
145 | #pragma D binding "1.0" PR_BPTADJ | |
146 | inline int PR_PTRACE = 0x04000000; | |
147 | #pragma D binding "1.0" PR_PTRACE | |
148 | inline int PR_MSFORK = 0x08000000; | |
149 | #pragma D binding "1.0" PR_MSFORK | |
150 | inline 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 | */ | |
163 | typedef int taskid_t; | |
164 | typedef int projid_t; | |
165 | typedef int poolid_t; | |
166 | typedef struct timespec timestruc_t; /* (SECONDS, NANOSECONDS) */ | |
167 | ||
168 | typedef 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 | ||
195 | inline int P_LP64 = 0x00000004; /* Process is LP64 */ | |
196 | #pragma D binding "1.0" P_LP64 | |
197 | ||
198 | #pragma D binding "1.0" translator | |
199 | translator 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 | |
248 | translator 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 | ||
282 | inline processor_t PROCESSOR_NULL = ((processor_t) 0); | |
283 | #pragma D binding "1.0" PROCESSOR_NULL | |
284 | ||
285 | typedef int psetid_t; | |
286 | ||
287 | typedef 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 */ | |
fe8ab488 | 298 | int pr_thstate; /* mach thread scheduler state */ |
39236c6e A |
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 | |
305 | translator 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. */ | |
fe8ab488 | 328 | pr_thstate = T->state; |
39236c6e A |
329 | }; |
330 | ||
331 | inline psinfo_t *curpsinfo = xlate <psinfo_t *> (curproc); | |
332 | #pragma D attributes Stable/Stable/Common curpsinfo | |
333 | #pragma D binding "1.0" curpsinfo | |
334 | ||
335 | inline 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 */ | |
340 | inline 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 */ | |
346 | inline 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 |