Home | History | Annotate | Download | only in common
      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 2006 Sun Microsystems, Inc.  All rights reserved.
     24  * Use is subject to license terms.
     25  */
     26 
     27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     28 
     29 /*
     30  * This file defines the standard set of inlines and translators to be made
     31  * available for all D programs to use to examine process model state.
     32  */
     33 
     34 #pragma D depends_on module procfs
     35 
     36 /*
     37  * The following miscellaneous constants are used by the proc(4) translators
     38  * defined below.  These are assigned the latest values from the system .h's.
     39  */
     40 inline char SSLEEP = @SSLEEP@;
     41 #pragma D binding "1.0" SSLEEP
     42 inline char SRUN = @SRUN@;
     43 #pragma D binding "1.0" SRUN
     44 inline char SZOMB = @SZOMB@;
     45 #pragma D binding "1.0" SZOMB
     46 inline char SSTOP = @SSTOP@;
     47 #pragma D binding "1.0" SSTOP
     48 inline char SIDL = @SIDL@;
     49 #pragma D binding "1.0" SIDL
     50 inline char SONPROC = @SONPROC@;
     51 #pragma D binding "1.0" SONPROC
     52 inline char SWAIT = @SWAIT@;
     53 #pragma D binding "1.0" SWAIT
     54 
     55 inline int PR_STOPPED = @PR_STOPPED@;
     56 #pragma D binding "1.0" PR_STOPPED
     57 inline int PR_ISTOP = @PR_ISTOP@;
     58 #pragma D binding "1.0" PR_ISTOP
     59 inline int PR_DSTOP = @PR_DSTOP@;
     60 #pragma D binding "1.0" PR_DSTOP
     61 inline int PR_STEP = @PR_STEP@;
     62 #pragma D binding "1.0" PR_STEP
     63 inline int PR_ASLEEP = @PR_ASLEEP@;
     64 #pragma D binding "1.0" PR_ASLEEP
     65 inline int PR_PCINVAL = @PR_PCINVAL@;
     66 #pragma D binding "1.0" PR_PCINVAL
     67 inline int PR_ASLWP = @PR_ASLWP@;
     68 #pragma D binding "1.0" PR_ASLWP
     69 inline int PR_AGENT = @PR_AGENT@;
     70 #pragma D binding "1.0" PR_AGENT
     71 inline int PR_DETACH = @PR_DETACH@;
     72 #pragma D binding "1.0" PR_DETACH
     73 inline int PR_DAEMON = @PR_DAEMON@;
     74 #pragma D binding "1.0" PR_DAEMON
     75 inline int PR_IDLE = @PR_IDLE@;
     76 #pragma D binding "1.4" PR_IDLE
     77 inline int PR_ISSYS = @PR_ISSYS@;
     78 #pragma D binding "1.0" PR_ISSYS
     79 inline int PR_VFORKP = @PR_VFORKP@;
     80 #pragma D binding "1.0" PR_VFORKP
     81 inline int PR_ORPHAN = @PR_ORPHAN@;
     82 #pragma D binding "1.0" PR_ORPHAN
     83 inline int PR_NOSIGCHLD = @PR_NOSIGCHLD@;
     84 #pragma D binding "1.4" PR_NOSIGCHLD
     85 inline int PR_WAITPID = @PR_WAITPID@;
     86 #pragma D binding "1.4" PR_WAITPID
     87 inline int PR_FORK = @PR_FORK@;
     88 #pragma D binding "1.0" PR_FORK
     89 inline int PR_RLC = @PR_RLC@;
     90 #pragma D binding "1.0" PR_RLC
     91 inline int PR_KLC = @PR_KLC@;
     92 #pragma D binding "1.0" PR_KLC
     93 inline int PR_ASYNC = @PR_ASYNC@;
     94 #pragma D binding "1.0" PR_ASYNC
     95 inline int PR_MSACCT = @PR_MSACCT@;
     96 #pragma D binding "1.0" PR_MSACCT
     97 inline int PR_BPTADJ = @PR_BPTADJ@;
     98 #pragma D binding "1.0" PR_BPTADJ
     99 inline int PR_PTRACE = @PR_PTRACE@;
    100 #pragma D binding "1.0" PR_PTRACE
    101 inline int PR_MSFORK = @PR_MSFORK@;
    102 #pragma D binding "1.0" PR_MSFORK
    103 
    104 inline char PR_MODEL_ILP32 = @PR_MODEL_ILP32@;
    105 #pragma D binding "1.0" PR_MODEL_ILP32
    106 inline char PR_MODEL_LP64 = @PR_MODEL_LP64@;
    107 #pragma D binding "1.0" PR_MODEL_LP64
    108 
    109 inline char SOBJ_NONE = @SOBJ_NONE@;
    110 #pragma D binding "1.0" SOBJ_NONE
    111 inline char SOBJ_MUTEX = @SOBJ_MUTEX@;
    112 #pragma D binding "1.0" SOBJ_MUTEX
    113 inline char SOBJ_RWLOCK = @SOBJ_RWLOCK@;
    114 #pragma D binding "1.0" SOBJ_RWLOCK
    115 inline char SOBJ_CV = @SOBJ_CV@;
    116 #pragma D binding "1.0" SOBJ_CV
    117 inline char SOBJ_SEMA = @SOBJ_SEMA@;
    118 #pragma D binding "1.0" SOBJ_SEMA
    119 inline char SOBJ_USER = @SOBJ_USER@;
    120 #pragma D binding "1.0" SOBJ_USER
    121 inline char SOBJ_USER_PI = @SOBJ_USER_PI@;
    122 #pragma D binding "1.0" SOBJ_USER_PI
    123 inline char SOBJ_SHUTTLE = @SOBJ_SHUTTLE@;
    124 #pragma D binding "1.0" SOBJ_SHUTTLE
    125 
    126 inline int SI_USER = @SI_USER@;
    127 #pragma D binding "1.0" SI_USER
    128 inline int SI_LWP = @SI_LWP@;
    129 #pragma D binding "1.0" SI_LWP
    130 inline int SI_QUEUE = @SI_QUEUE@;
    131 #pragma D binding "1.0" SI_QUEUE
    132 inline int SI_TIMER = @SI_TIMER@;
    133 #pragma D binding "1.0" SI_TIMER
    134 inline int SI_ASYNCIO = @SI_ASYNCIO@;
    135 #pragma D binding "1.0" SI_ASYNCIO
    136 inline int SI_MESGQ = @SI_MESGQ@;
    137 #pragma D binding "1.0" SI_MESGQ
    138 inline int SI_RCTL = @SI_RCTL@;
    139 #pragma D binding "1.0" SI_RCTL
    140 inline int ILL_ILLOPC = @ILL_ILLOPC@;
    141 #pragma D binding "1.0" ILL_ILLOPC
    142 inline int ILL_ILLOPN = @ILL_ILLOPN@;
    143 #pragma D binding "1.0" ILL_ILLOPN
    144 inline int ILL_ILLADR = @ILL_ILLADR@;
    145 #pragma D binding "1.0" ILL_ILLADR
    146 inline int ILL_ILLTRP = @ILL_ILLTRP@;
    147 #pragma D binding "1.0" ILL_ILLTRP
    148 inline int ILL_PRVOPC = @ILL_PRVOPC@;
    149 #pragma D binding "1.0" ILL_PRVOPC
    150 inline int ILL_PRVREG = @ILL_PRVREG@;
    151 #pragma D binding "1.0" ILL_PRVREG
    152 inline int ILL_COPROC = @ILL_COPROC@;
    153 #pragma D binding "1.0" ILL_COPROC
    154 inline int ILL_BADSTK = @ILL_BADSTK@;
    155 #pragma D binding "1.0" ILL_BADSTK
    156 inline int FPE_INTDIV = @FPE_INTDIV@;
    157 #pragma D binding "1.0" FPE_INTDIV
    158 inline int FPE_INTOVF = @FPE_INTOVF@;
    159 #pragma D binding "1.0" FPE_INTOVF
    160 inline int FPE_FLTDIV = @FPE_FLTDIV@;
    161 #pragma D binding "1.0" FPE_FLTDIV
    162 inline int FPE_FLTOVF = @FPE_FLTOVF@;
    163 #pragma D binding "1.0" FPE_FLTOVF
    164 inline int FPE_FLTUND = @FPE_FLTUND@;
    165 #pragma D binding "1.0" FPE_FLTUND
    166 inline int FPE_FLTRES = @FPE_FLTRES@;
    167 #pragma D binding "1.0" FPE_FLTRES
    168 inline int FPE_FLTINV = @FPE_FLTINV@;
    169 #pragma D binding "1.0" FPE_FLTINV
    170 inline int FPE_FLTSUB = @FPE_FLTSUB@;
    171 #pragma D binding "1.0" FPE_FLTSUB
    172 inline int SEGV_MAPERR = @SEGV_MAPERR@;
    173 #pragma D binding "1.0" SEGV_MAPERR
    174 inline int SEGV_ACCERR = @SEGV_ACCERR@;
    175 #pragma D binding "1.0" SEGV_ACCERR
    176 inline int BUS_ADRALN = @BUS_ADRALN@;
    177 #pragma D binding "1.0" BUS_ADRALN
    178 inline int BUS_ADRERR = @BUS_ADRERR@;
    179 #pragma D binding "1.0" BUS_ADRERR
    180 inline int BUS_OBJERR = @BUS_OBJERR@;
    181 #pragma D binding "1.0" BUS_OBJERR
    182 inline int TRAP_BRKPT = @TRAP_BRKPT@;
    183 #pragma D binding "1.0" TRAP_BRKPT
    184 inline int TRAP_TRACE = @TRAP_TRACE@;
    185 #pragma D binding "1.0" TRAP_TRACE
    186 inline int CLD_EXITED = @CLD_EXITED@;
    187 #pragma D binding "1.0" CLD_EXITED
    188 inline int CLD_KILLED = @CLD_KILLED@;
    189 #pragma D binding "1.0" CLD_KILLED
    190 inline int CLD_DUMPED = @CLD_DUMPED@;
    191 #pragma D binding "1.0" CLD_DUMPED
    192 inline int CLD_TRAPPED = @CLD_TRAPPED@;
    193 #pragma D binding "1.0" CLD_TRAPPED
    194 inline int CLD_STOPPED = @CLD_STOPPED@;
    195 #pragma D binding "1.0" CLD_STOPPED
    196 inline int CLD_CONTINUED = @CLD_CONTINUED@;
    197 #pragma D binding "1.0" CLD_CONTINUED
    198 inline int POLL_IN = @POLL_IN@;
    199 #pragma D binding "1.0" POLL_IN
    200 inline int POLL_OUT = @POLL_OUT@;
    201 #pragma D binding "1.0" POLL_OUT
    202 inline int POLL_MSG = @POLL_MSG@;
    203 #pragma D binding "1.0" POLL_MSG
    204 inline int POLL_ERR = @POLL_ERR@;
    205 #pragma D binding "1.0" POLL_ERR
    206 inline int POLL_PRI = @POLL_PRI@;
    207 #pragma D binding "1.0" POLL_PRI
    208 inline int POLL_HUP = @POLL_HUP@;
    209 #pragma D binding "1.0" POLL_HUP
    210 
    211 /*
    212  * Translate from the kernel's proc_t structure to a proc(4) psinfo_t struct.
    213  * We do not provide support for pr_size, pr_rssize, pr_pctcpu, and pr_pctmem.
    214  * We also do not fill in pr_lwp (the lwpsinfo_t for the representative LWP)
    215  * because we do not have the ability to select and stop any representative.
    216  * Also, for the moment, pr_wstat, pr_time, and pr_ctime are not supported,
    217  * but these could be supported by DTrace in the future using subroutines.
    218  * Note that any member added to this translator should also be added to the
    219  * kthread_t-to-psinfo_t translator, below.
    220  */
    221 #pragma D binding "1.0" translator
    222 translator psinfo_t < proc_t *T > {
    223 	pr_nlwp = T->p_lwpcnt;
    224 	pr_pid = T->p_pidp->pid_id;
    225 	pr_ppid = T->p_ppid;
    226 	pr_pgid = T->p_pgidp->pid_id;
    227 	pr_sid = T->p_sessp->s_sidp->pid_id;
    228 	pr_uid = T->p_cred->cr_ruid;
    229 	pr_euid = T->p_cred->cr_uid;
    230 	pr_gid = T->p_cred->cr_rgid;
    231 	pr_egid = T->p_cred->cr_gid;
    232 	pr_addr = (uintptr_t)T;
    233 
    234 	pr_ttydev = (T->p_sessp->s_vp == NULL) ? (dev_t)-1 :
    235 	    (T->p_sessp->s_dev == `rwsconsdev) ? `uconsdev :
    236 	    (T->p_sessp->s_dev == `rconsdev) ? `uconsdev : T->p_sessp->s_dev;
    237 
    238 	pr_start = T->p_user.u_start;
    239 	pr_fname = T->p_user.u_comm;
    240 	pr_psargs = T->p_user.u_psargs;
    241 	pr_argc = T->p_user.u_argc;
    242 	pr_argv = T->p_user.u_argv;
    243 	pr_envp = T->p_user.u_envp;
    244 
    245 	pr_dmodel = (T->p_model == @DATAMODEL_ILP32@) ?
    246 	    PR_MODEL_ILP32 : PR_MODEL_LP64;
    247 
    248 	pr_taskid = T->p_task->tk_tkid;
    249 	pr_projid = T->p_task->tk_proj->kpj_id;
    250 	pr_poolid = T->p_pool->pool_id;
    251 	pr_zoneid = T->p_zone->zone_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 };
    287 
    288 /*
    289  * Translate from the kernel's kthread_t structure to a proc(4) lwpsinfo_t.
    290  * We do not provide support for pr_nice, pr_oldpri, pr_cpu, or pr_pctcpu.
    291  * Also, for the moment, pr_start and pr_time are not supported, but these
    292  * could be supported by DTrace in the future using subroutines.
    293  */
    294 #pragma D binding "1.0" translator
    295 translator lwpsinfo_t < kthread_t *T > {
    296 	pr_flag = ((T->t_state == @TS_STOPPED@) ? (PR_STOPPED |
    297 	    ((!(T->t_schedflag & @TS_PSTART@)) ? PR_ISTOP : 0)) :
    298 	    ((T->t_proc_flag & @TP_PRVSTOP@) ? PR_STOPPED | PR_ISTOP : 0)) |
    299 	    ((T == T->t_procp->p_agenttp) ? PR_AGENT : 0) |
    300 	    ((!(T->t_proc_flag & @TP_TWAIT@)) ? PR_DETACH : 0) |
    301 	    ((T->t_proc_flag & @TP_DAEMON@) ? PR_DAEMON : 0) |
    302 	    ((T->t_procp->p_pidflag & @CLDNOSIGCHLD@) ? PR_NOSIGCHLD : 0) |
    303 	    ((T->t_procp->p_pidflag & @CLDWAITPID@) ? PR_WAITPID : 0) |
    304 	    ((T->t_procp->p_proc_flag & @P_PR_FORK@) ? PR_FORK : 0) |
    305 	    ((T->t_procp->p_proc_flag & @P_PR_RUNLCL@) ? PR_RLC : 0) |
    306 	    ((T->t_procp->p_proc_flag & @P_PR_KILLCL@) ? PR_KLC : 0) |
    307 	    ((T->t_procp->p_proc_flag & @P_PR_ASYNC@) ? PR_ASYNC : 0) |
    308 	    ((T->t_procp->p_proc_flag & @P_PR_BPTADJ@) ? PR_BPTADJ : 0) |
    309 	    ((T->t_procp->p_proc_flag & @P_PR_PTRACE@) ? PR_PTRACE : 0) |
    310 	    ((T->t_procp->p_flag & @SMSACCT@) ? PR_MSACCT : 0) |
    311 	    ((T->t_procp->p_flag & @SMSFORK@) ? PR_MSFORK : 0) |
    312 	    ((T->t_procp->p_flag & @SVFWAIT@) ? PR_VFORKP : 0) |
    313 	    (((T->t_procp->p_flag & @SSYS@) ||
    314 	    (T->t_procp->p_as == &`kas)) ? PR_ISSYS : 0) |
    315 	    ((T == T->t_cpu->cpu_idle_thread) ? PR_IDLE : 0);
    316 
    317 	pr_lwpid = T->t_tid;
    318 	pr_addr = (uintptr_t)T;
    319 	pr_wchan = (uintptr_t)T->t_lwpchan.lc_wchan;
    320 	pr_stype = T->t_sobj_ops ? T->t_sobj_ops->sobj_type : 0;
    321 
    322 	pr_state = (T->t_proc_flag & @TP_PRVSTOP@) ? SSTOP :
    323 	    (T->t_state == @TS_SLEEP@) ? SSLEEP :
    324 	    (T->t_state == @TS_RUN@) ? SRUN :
    325 	    (T->t_state == @TS_ONPROC@) ? SONPROC :
    326 	    (T->t_state == @TS_ZOMB@) ? SZOMB :
    327 	    (T->t_state == @TS_STOPPED@) ? SSTOP :
    328 	    (T->t_state == @TS_WAIT@) ? SWAIT : 0;
    329 
    330 	pr_sname = (T->t_proc_flag & @TP_PRVSTOP@) ? 'T' :
    331 	    (T->t_state == @TS_SLEEP@) ? 'S' :
    332 	    (T->t_state == @TS_RUN@) ? 'R' :
    333 	    (T->t_state == @TS_ONPROC@) ? 'O' :
    334 	    (T->t_state == @TS_ZOMB@) ? 'Z' :
    335 	    (T->t_state == @TS_STOPPED@) ? 'T' :
    336 	    (T->t_state == @TS_WAIT@) ? 'W' : '?';
    337 
    338 	pr_syscall = T->t_sysnum;
    339 	pr_pri = T->t_pri;
    340 	pr_clname = `sclass[T->t_cid].cl_name;
    341 	pr_onpro = T->t_cpu->cpu_id;
    342 	pr_bindpro = T->t_bind_cpu;
    343 	pr_bindpset = T->t_bind_pset;
    344 	pr_lgrp = T->t_lpl->lpl_lgrpid;
    345 };
    346 
    347 inline psinfo_t *curpsinfo = xlate <psinfo_t *> (curthread->t_procp);
    348 #pragma D attributes Stable/Stable/Common curpsinfo
    349 #pragma D binding "1.0" curpsinfo
    350 
    351 inline lwpsinfo_t *curlwpsinfo = xlate <lwpsinfo_t *> (curthread);
    352 #pragma D attributes Stable/Stable/Common curlwpsinfo
    353 #pragma D binding "1.0" curlwpsinfo
    354 
    355 inline string cwd = curthread->t_procp->p_user.u_cdir->v_path == NULL ?
    356     "<unknown>" : stringof(curthread->t_procp->p_user.u_cdir->v_path);
    357 #pragma D attributes Stable/Stable/Common cwd
    358 #pragma D binding "1.0" cwd
    359 
    360 inline string root = curthread->t_procp->p_user.u_rdir == NULL ? "/" :
    361     curthread->t_procp->p_user.u_rdir->v_path == NULL ? "<unknown>" :
    362     stringof(curthread->t_procp->p_user.u_rdir->v_path);
    363 #pragma D attributes Stable/Stable/Common root
    364 #pragma D binding "1.0" root
    365