1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* 28 * This file defines the standard set of inlines and translators to be made 29 * available for all D programs to use to examine process model state. 30 */ 31 32 #pragma D depends_on module procfs 33 34 /* 35 * The following miscellaneous constants are used by the proc(4) translators 36 * defined below. These are assigned the latest values from the system .h's. 37 */ 38 inline char SSLEEP = 1; 39 #pragma D binding "1.0" SSLEEP 40 inline char SRUN = 2; 41 #pragma D binding "1.0" SRUN 42 inline char SZOMB = 3; 43 #pragma D binding "1.0" SZOMB 44 inline char SSTOP = 4; 45 #pragma D binding "1.0" SSTOP 46 inline char SIDL = 5; 47 #pragma D binding "1.0" SIDL 48 inline char SONPROC = 6; 49 #pragma D binding "1.0" SONPROC 50 inline char SWAIT = 7; 51 #pragma D binding "1.0" SWAIT 52 53 inline int PR_STOPPED = 0x00000001; 54 #pragma D binding "1.0" PR_STOPPED 55 inline int PR_ISTOP = 0x00000002; 56 #pragma D binding "1.0" PR_ISTOP 57 inline int PR_DSTOP = 0x00000004; 58 #pragma D binding "1.0" PR_DSTOP 59 inline int PR_STEP = 0x00000008; 60 #pragma D binding "1.0" PR_STEP 61 inline int PR_ASLEEP = 0x00000010; 62 #pragma D binding "1.0" PR_ASLEEP 63 inline int PR_PCINVAL = 0x00000020; 64 #pragma D binding "1.0" PR_PCINVAL 65 inline int PR_ASLWP = 0x00000040; 66 #pragma D binding "1.0" PR_ASLWP 67 inline int PR_AGENT = 0x00000080; 68 #pragma D binding "1.0" PR_AGENT 69 inline int PR_DETACH = 0x00000100; 70 #pragma D binding "1.0" PR_DETACH 71 inline int PR_DAEMON = 0x00000200; 72 #pragma D binding "1.0" PR_DAEMON 73 inline int PR_IDLE = 0x00000400; 74 #pragma D binding "1.4" PR_IDLE 75 inline int PR_ISSYS = 0x00001000; 76 #pragma D binding "1.0" PR_ISSYS 77 inline int PR_VFORKP = 0x00002000; 78 #pragma D binding "1.0" PR_VFORKP 79 inline int PR_ORPHAN = 0x00004000; 80 #pragma D binding "1.0" PR_ORPHAN 81 inline int PR_NOSIGCHLD = 0x00008000; 82 #pragma D binding "1.4" PR_NOSIGCHLD 83 inline int PR_WAITPID = 0x00010000; 84 #pragma D binding "1.4" PR_WAITPID 85 inline int PR_FORK = 0x00100000; 86 #pragma D binding "1.0" PR_FORK 87 inline int PR_RLC = 0x00200000; 88 #pragma D binding "1.0" PR_RLC 89 inline int PR_KLC = 0x00400000; 90 #pragma D binding "1.0" PR_KLC 91 inline int PR_ASYNC = 0x00800000; 92 #pragma D binding "1.0" PR_ASYNC 93 inline int PR_MSACCT = 0x01000000; 94 #pragma D binding "1.0" PR_MSACCT 95 inline int PR_BPTADJ = 0x02000000; 96 #pragma D binding "1.0" PR_BPTADJ 97 inline int PR_PTRACE = 0x04000000; 98 #pragma D binding "1.0" PR_PTRACE 99 inline int PR_MSFORK = 0x08000000; 100 #pragma D binding "1.0" PR_MSFORK 101 102 inline char PR_MODEL_ILP32 = 1; 103 #pragma D binding "1.0" PR_MODEL_ILP32 104 inline char PR_MODEL_LP64 = 2; 105 #pragma D binding "1.0" PR_MODEL_LP64 106 107 inline char SOBJ_NONE = 0; 108 #pragma D binding "1.0" SOBJ_NONE 109 inline char SOBJ_MUTEX = 1; 110 #pragma D binding "1.0" SOBJ_MUTEX 111 inline char SOBJ_RWLOCK = 2; 112 #pragma D binding "1.0" SOBJ_RWLOCK 113 inline char SOBJ_CV = 3; 114 #pragma D binding "1.0" SOBJ_CV 115 inline char SOBJ_SEMA = 4; 116 #pragma D binding "1.0" SOBJ_SEMA 117 inline char SOBJ_USER = 5; 118 #pragma D binding "1.0" SOBJ_USER 119 inline char SOBJ_USER_PI = 6; 120 #pragma D binding "1.0" SOBJ_USER_PI 121 inline char SOBJ_SHUTTLE = 7; 122 #pragma D binding "1.0" SOBJ_SHUTTLE 123 124 inline int SI_USER = 0; 125 #pragma D binding "1.0" SI_USER 126 inline int SI_LWP = (-1); 127 #pragma D binding "1.0" SI_LWP 128 inline int SI_QUEUE = (-2); 129 #pragma D binding "1.0" SI_QUEUE 130 inline int SI_TIMER = (-3); 131 #pragma D binding "1.0" SI_TIMER 132 inline int SI_ASYNCIO = (-4); 133 #pragma D binding "1.0" SI_ASYNCIO 134 inline int SI_MESGQ = (-5); 135 #pragma D binding "1.0" SI_MESGQ 136 inline int SI_RCTL = 2049; 137 #pragma D binding "1.0" SI_RCTL 138 inline int ILL_ILLOPC = 1; 139 #pragma D binding "1.0" ILL_ILLOPC 140 inline int ILL_ILLOPN = 2; 141 #pragma D binding "1.0" ILL_ILLOPN 142 inline int ILL_ILLADR = 3; 143 #pragma D binding "1.0" ILL_ILLADR 144 inline int ILL_ILLTRP = 4; 145 #pragma D binding "1.0" ILL_ILLTRP 146 inline int ILL_PRVOPC = 5; 147 #pragma D binding "1.0" ILL_PRVOPC 148 inline int ILL_PRVREG = 6; 149 #pragma D binding "1.0" ILL_PRVREG 150 inline int ILL_COPROC = 7; 151 #pragma D binding "1.0" ILL_COPROC 152 inline int ILL_BADSTK = 8; 153 #pragma D binding "1.0" ILL_BADSTK 154 inline int FPE_INTDIV = 1; 155 #pragma D binding "1.0" FPE_INTDIV 156 inline int FPE_INTOVF = 2; 157 #pragma D binding "1.0" FPE_INTOVF 158 inline int FPE_FLTDIV = 3; 159 #pragma D binding "1.0" FPE_FLTDIV 160 inline int FPE_FLTOVF = 4; 161 #pragma D binding "1.0" FPE_FLTOVF 162 inline int FPE_FLTUND = 5; 163 #pragma D binding "1.0" FPE_FLTUND 164 inline int FPE_FLTRES = 6; 165 #pragma D binding "1.0" FPE_FLTRES 166 inline int FPE_FLTINV = 7; 167 #pragma D binding "1.0" FPE_FLTINV 168 inline int FPE_FLTSUB = 8; 169 #pragma D binding "1.0" FPE_FLTSUB 170 inline int SEGV_MAPERR = 1; 171 #pragma D binding "1.0" SEGV_MAPERR 172 inline int SEGV_ACCERR = 2; 173 #pragma D binding "1.0" SEGV_ACCERR 174 inline int BUS_ADRALN = 1; 175 #pragma D binding "1.0" BUS_ADRALN 176 inline int BUS_ADRERR = 2; 177 #pragma D binding "1.0" BUS_ADRERR 178 inline int BUS_OBJERR = 3; 179 #pragma D binding "1.0" BUS_OBJERR 180 inline int TRAP_BRKPT = 1; 181 #pragma D binding "1.0" TRAP_BRKPT 182 inline int TRAP_TRACE = 2; 183 #pragma D binding "1.0" TRAP_TRACE 184 inline int CLD_EXITED = 1; 185 #pragma D binding "1.0" CLD_EXITED 186 inline int CLD_KILLED = 2; 187 #pragma D binding "1.0" CLD_KILLED 188 inline int CLD_DUMPED = 3; 189 #pragma D binding "1.0" CLD_DUMPED 190 inline int CLD_TRAPPED = 4; 191 #pragma D binding "1.0" CLD_TRAPPED 192 inline int CLD_STOPPED = 5; 193 #pragma D binding "1.0" CLD_STOPPED 194 inline int CLD_CONTINUED = 6; 195 #pragma D binding "1.0" CLD_CONTINUED 196 inline int POLL_IN = 1; 197 #pragma D binding "1.0" POLL_IN 198 inline int POLL_OUT = 2; 199 #pragma D binding "1.0" POLL_OUT 200 inline int POLL_MSG = 3; 201 #pragma D binding "1.0" POLL_MSG 202 inline int POLL_ERR = 4; 203 #pragma D binding "1.0" POLL_ERR 204 inline int POLL_PRI = 5; 205 #pragma D binding "1.0" POLL_PRI 206 inline int POLL_HUP = 6; 207 #pragma D binding "1.0" POLL_HUP 208 209 /* 210 * Translate from the kernel's proc_t structure to a proc(4) psinfo_t struct. 211 * We do not provide support for pr_size, pr_rssize, pr_pctcpu, and pr_pctmem. 212 * We also do not fill in pr_lwp (the lwpsinfo_t for the representative LWP) 213 * because we do not have the ability to select and stop any representative. 214 * Also, for the moment, pr_wstat, pr_time, and pr_ctime are not supported, 215 * but these could be supported by DTrace in the future using subroutines. 216 * Note that any member added to this translator should also be added to the 217 * kthread_t-to-psinfo_t translator, below. 218 */ 219 #pragma D binding "1.0" translator 220 translator psinfo_t < proc_t *T > { 221 pr_nlwp = T->p_lwpcnt; 222 pr_pid = T->p_pidp->pid_id; 223 pr_ppid = T->p_ppid; 224 pr_pgid = T->p_pgidp->pid_id; 225 pr_sid = T->p_sessp->s_sidp->pid_id; 226 pr_uid = T->p_cred->cr_ruid; 227 pr_euid = T->p_cred->cr_uid; 228 pr_gid = T->p_cred->cr_rgid; 229 pr_egid = T->p_cred->cr_gid; 230 pr_addr = (uintptr_t)T; 231 232 pr_ttydev = (T->p_sessp->s_vp == NULL) ? (dev_t)-1 : 233 (T->p_sessp->s_dev == `rwsconsdev) ? `uconsdev : 234 (T->p_sessp->s_dev == `rconsdev) ? `uconsdev : T->p_sessp->s_dev; 235 236 pr_start = T->p_user.u_start; 237 pr_fname = T->p_user.u_comm; 238 pr_psargs = T->p_user.u_psargs; 239 pr_argc = T->p_user.u_argc; 240 pr_argv = T->p_user.u_argv; 241 pr_envp = T->p_user.u_envp; 242 243 pr_dmodel = (T->p_model == 0x00100000) ? 244 PR_MODEL_ILP32 : PR_MODEL_LP64; 245 246 pr_taskid = T->p_task->tk_tkid; 247 pr_projid = T->p_task->tk_proj->kpj_id; 248 pr_poolid = T->p_pool->pool_id; 249 pr_zoneid = T->p_zone->zone_id; 250 pr_contract = (T->p_ct_process == NULL) ? -1 : 251 T->p_ct_process->conp_contract.ct_id; 252 }; 253 254 /* 255 * Translate from the kernel's kthread_t structure to a proc(4) psinfo_t 256 * struct. Lacking a facility to define one translator only in terms of 257 * another, we explicitly define each member by using the proc_t-to-psinfo_t 258 * translator, above; any members added to that translator should also be 259 * added here. (The only exception to this is pr_start, which -- due to it 260 * being a structure -- cannot be defined in terms of a translator at all.) 261 */ 262 #pragma D binding "1.0" translator 263 translator psinfo_t < kthread_t *T > { 264 pr_nlwp = xlate <psinfo_t> (T->t_procp).pr_nlwp; 265 pr_pid = xlate <psinfo_t> (T->t_procp).pr_pid; 266 pr_ppid = xlate <psinfo_t> (T->t_procp).pr_ppid; 267 pr_pgid = xlate <psinfo_t> (T->t_procp).pr_pgid; 268 pr_sid = xlate <psinfo_t> (T->t_procp).pr_sid; 269 pr_uid = xlate <psinfo_t> (T->t_procp).pr_uid; 270 pr_euid = xlate <psinfo_t> (T->t_procp).pr_euid; 271 pr_gid = xlate <psinfo_t> (T->t_procp).pr_gid; 272 pr_egid = xlate <psinfo_t> (T->t_procp).pr_egid; 273 pr_addr = xlate <psinfo_t> (T->t_procp).pr_addr; 274 pr_ttydev = xlate <psinfo_t> (T->t_procp).pr_ttydev; 275 pr_start = (timestruc_t)xlate <psinfo_t> (T->t_procp).pr_start; 276 pr_fname = xlate <psinfo_t> (T->t_procp).pr_fname; 277 pr_psargs = xlate <psinfo_t> (T->t_procp).pr_psargs; 278 pr_argc = xlate <psinfo_t> (T->t_procp).pr_argc; 279 pr_argv = xlate <psinfo_t> (T->t_procp).pr_argv; 280 pr_envp = xlate <psinfo_t> (T->t_procp).pr_envp; 281 pr_dmodel = xlate <psinfo_t> (T->t_procp).pr_dmodel; 282 pr_taskid = xlate <psinfo_t> (T->t_procp).pr_taskid; 283 pr_projid = xlate <psinfo_t> (T->t_procp).pr_projid; 284 pr_poolid = xlate <psinfo_t> (T->t_procp).pr_poolid; 285 pr_zoneid = xlate <psinfo_t> (T->t_procp).pr_zoneid; 286 pr_contract = xlate <psinfo_t> (T->t_procp).pr_contract; 287 }; 288 289 /* 290 * Translate from the kernel's kthread_t structure to a proc(4) lwpsinfo_t. 291 * We do not provide support for pr_nice, pr_oldpri, pr_cpu, or pr_pctcpu. 292 * Also, for the moment, pr_start and pr_time are not supported, but these 293 * could be supported by DTrace in the future using subroutines. 294 */ 295 #pragma D binding "1.0" translator 296 translator lwpsinfo_t < kthread_t *T > { 297 pr_flag = ((T->t_state == 0x10) ? (PR_STOPPED | 298 ((!(T->t_schedflag & 0x0800)) ? PR_ISTOP : 0)) : 299 ((T->t_proc_flag & 0x0080) ? PR_STOPPED | PR_ISTOP : 0)) | 300 ((T == T->t_procp->p_agenttp) ? PR_AGENT : 0) | 301 ((!(T->t_proc_flag & 0x0004)) ? PR_DETACH : 0) | 302 ((T->t_proc_flag & 0x0001) ? PR_DAEMON : 0) | 303 ((T->t_procp->p_pidflag & 0x0004) ? PR_NOSIGCHLD : 0) | 304 ((T->t_procp->p_pidflag & 0x0008) ? PR_WAITPID : 0) | 305 ((T->t_procp->p_proc_flag & 0x0004) ? PR_FORK : 0) | 306 ((T->t_procp->p_proc_flag & 0x0080) ? PR_RLC : 0) | 307 ((T->t_procp->p_proc_flag & 0x0100) ? PR_KLC : 0) | 308 ((T->t_procp->p_proc_flag & 0x0010) ? PR_ASYNC : 0) | 309 ((T->t_procp->p_proc_flag & 0x0040) ? PR_BPTADJ : 0) | 310 ((T->t_procp->p_proc_flag & 0x0002) ? PR_PTRACE : 0) | 311 ((T->t_procp->p_flag & 0x02000000) ? PR_MSACCT : 0) | 312 ((T->t_procp->p_flag & 0x40000000) ? PR_MSFORK : 0) | 313 ((T->t_procp->p_flag & 0x00080000) ? PR_VFORKP : 0) | 314 (((T->t_procp->p_flag & 0x00000001) || 315 (T->t_procp->p_as == &`kas)) ? PR_ISSYS : 0) | 316 ((T == T->t_cpu->cpu_idle_thread) ? PR_IDLE : 0); 317 318 pr_lwpid = T->t_tid; 319 pr_addr = (uintptr_t)T; 320 pr_wchan = (uintptr_t)T->t_lwpchan.lc_wchan; 321 pr_stype = T->t_sobj_ops ? T->t_sobj_ops->sobj_type : 0; 322 323 pr_state = (T->t_proc_flag & 0x0080) ? SSTOP : 324 (T->t_state == 0x01) ? SSLEEP : 325 (T->t_state == 0x02) ? SRUN : 326 (T->t_state == 0x04) ? SONPROC : 327 (T->t_state == 0x08) ? SZOMB : 328 (T->t_state == 0x10) ? SSTOP : 329 (T->t_state == 0x20) ? SWAIT : 0; 330 331 pr_sname = (T->t_proc_flag & 0x0080) ? 'T' : 332 (T->t_state == 0x01) ? 'S' : 333 (T->t_state == 0x02) ? 'R' : 334 (T->t_state == 0x04) ? 'O' : 335 (T->t_state == 0x08) ? 'Z' : 336 (T->t_state == 0x10) ? 'T' : 337 (T->t_state == 0x20) ? 'W' : '?'; 338 339 pr_syscall = T->t_sysnum; 340 pr_pri = T->t_pri; 341 pr_clname = `sclass[T->t_cid].cl_name; 342 pr_onpro = T->t_cpu->cpu_id; 343 pr_bindpro = T->t_bind_cpu; 344 pr_bindpset = T->t_bind_pset; 345 pr_lgrp = T->t_lpl->lpl_lgrpid; 346 }; 347 348 inline psinfo_t *curpsinfo = xlate <psinfo_t *> (curthread->t_procp); 349 #pragma D attributes Stable/Stable/Common curpsinfo 350 #pragma D binding "1.0" curpsinfo 351 352 inline lwpsinfo_t *curlwpsinfo = xlate <lwpsinfo_t *> (curthread); 353 #pragma D attributes Stable/Stable/Common curlwpsinfo 354 #pragma D binding "1.0" curlwpsinfo 355 356 inline string cwd = curthread->t_procp->p_user.u_cdir->v_path == NULL ? 357 "<unknown>" : stringof(curthread->t_procp->p_user.u_cdir->v_path); 358 #pragma D attributes Stable/Stable/Common cwd 359 #pragma D binding "1.0" cwd 360 361 inline string root = curthread->t_procp->p_user.u_rdir == NULL ? "/" : 362 curthread->t_procp->p_user.u_rdir->v_path == NULL ? "<unknown>" : 363 stringof(curthread->t_procp->p_user.u_rdir->v_path); 364 #pragma D attributes Stable/Stable/Common root 365 #pragma D binding "1.0" root 366