Solaris 动态跟踪指南

第 25 章 proc 提供器

proc 提供器提供了与以下活动有关的探测器:进程创建和终止、LWP 创建和终止、新程序映像的执行以及信号的发送和处理。

探测器

表 25–1 中对 proc 探测器进行了说明。

表 25–1 proc 探测器

探测器 

说明 

create

使用 fork(2)、forkall(2)、fork1(2) 或 vfork(2) 创建进程时将触发的探测器。args[0] 指向对应于新的子进程的 psinfo_t。可以通过检查派生线程 lwpsinfo_t 的 pr_flag 成员中的 PR_VFORKP,将 vfork 与其他 fork 变体区分开来。可以通过检查父进程的 psinfo_t (curpsinfo) 和子进程的 psinfo_t (args[0]) 的 pr_nlwp 成员,将 fork1 与 forkall 区分开来。因为 create 探测器仅在成功创建了进程之后触发,且 LWP 创建为创建进程的一部分,所以对于任何在创建进程时(为新进程触发 create 探测器之前)创建的 LWP,都将触发 lwp-create。

exec

进程使用 exec(2) 系统调用的以下变体装入新进程映像时将触发的探测器:exec(2)、execle(2)、execlp(2)、execv(2)、execve(2)、execvp(2)。exec 探测器在装入进程映像之前触发。因此进程变量(如 execname 和 curpsinfo)将包含装入映像前的进程状态。在触发 exec 探测器之后的某个时间,exec-failure 探测器或 exec-success 探测器随后将在同一线程中触发。args[0] 指向新进程映像的路径。

exec-failure

exec(2) 变体失败时将触发的探测器。exec-failure 探测器仅在同一线程中触发了 exec 探测器之后触发。args[0] 中提供了 errno(3C) 值。

exec-success

exec(2) 变体成功时将触发的探测器。与 exec-failure 探测器一样,exec-success 探测器仅在同一线程中触发了 exec 探测器之后触发。触发 exec-success 探测器时,进程变量(如 execname 和 curpsinfo)将包含装入新的进程映像之后的进程状态。

exit

当前线程正在退出时将触发的探测器。退出的原因(使用某个 SIGCHLD siginfo.h(3HEAD) 代码表示)包含在 args[0] 中。

fault

线程遇到计算机故障时将触发的探测器。故障代码(如 proc(4) 中所定义)包含在 args[0] 中。args[1] 指向对应于故障的 siginfo 结构。只有引起信号的那些故障可以触发 fault 探测器。

lwp-create

创建 LWP 时将触发的探测器,通常作为 thr_create(3C) 的结果。args[0] 指向对应于新线程的 lwpsinfo_t。args[1] 指向包含该线程进程的 psinfo_t。

lwp-start

在新创建的 LWP 的上下文中触发的探测器。lwp-start 探测器将在执行任何用户级指令之前触发。如果该 LWP 是进程中的第一个 LWP,则 start 探测器将在 lwp-start 探测器之前触发。

lwp-exit

LWP 正在退出(由于信号或对 thr_exit(3C) 的显式调用)时将触发的探测器。

signal-discard

信号被发送到单线程进程,且进程未阻塞该信号,但忽略该信号时将触发的探测器。在这些条件下,信号在生成时将被废弃。目标进程和线程的 lwpsinfo_t 和 psinfo_t 分别包含在 args[0] 和 args[1] 中。信号数字包含在 args[2] 中。

signal-send

将信号发送到线程或进程时将触发的探测器。signal-send 探测器在发送进程和线程的上下文中触发。接收进程和线程的 lwpsinfo_t 和 psinfo_t 分别包含在 args[0] 和 args[1] 中。信号数字包含在 args[2] 中。接收进程和线程时,signal-send 始终后跟 signal-handle 或 signal-clear。

signal-handle

探测器就在线程处理信号之前的瞬间触发。signal-handle 探测器在将要处理信号的线程的上下文中触发。信号数字包含在 args[0] 中。指向对应于信号的 siginfo_t 结构的指针包含在 args[1] 中。如果没有 siginfo_t 结构或者信号处理程序未设置 SA_SIGINFO 标志,args[1] 的值将为 NULL。进程中的信号处理程序的地址包含在 args[2] 中。

signal-clear

因为目标线程正在等待 sigwait(2)、sigwaitinfo(3RT) 或 sigtimedwait(3RT) 中的信号而清除暂挂信号时,将触发的探测器。在这些条件下,将清除暂挂信号并将信号数字返回到调用方。信号数字包含在 args[0] 中。signal-clear 在先前的等待线程的上下文中触发。

start

在新创建的进程的上下文中触发的探测器。start 探测器将在执行进程中任何用户级指令之前触发。

参数

表 25–2 中列出了 proc 探测器的参数类型。表 25–1 中说明了这些参数。

表 25–2 proc 探测器参数

探测器 

args[0]

args[1]

args[2]

create

psinfo_t *

— 

— 

exec

char *

— 

— 

exec-failure

int

— 

— 

exit

int

— 

— 

fault

int

siginfo_t *

— 

lwp-create

lwpsinfo_t *

psinfo_t *

— 

lwp-start

— 

— 

— 

lwp-exit

— 

— 

— 

signal-discard

lwpsinfo_t *

psinfo_t *

int

signal-discard

lwpsinfo_t *

psinfo_t *

int

signal-send

lwpsinfo_t *

psinfo_t *

int

signal-handle

int

siginfo_t *

void (*)(void)

signal-clear

int

— 

— 

start

— 

— 

— 

lwpsinfo_t

多种 proc 探测器具有 lwpsinfo_t(proc(4) 中记录的一种结构)类型的参数。DTrace 使用者可以使用的 lwpsinfo_t 结构的定义如下所示:

typedef struct lwpsinfo {
	int pr_flag;              /* flags; see below */
	id_t pr_lwpid;            /* LWP id */
	uintptr_t pr_addr;        /* internal address of thread */
	uintptr_t pr_wchan;       /* wait addr for sleeping thread */
	char pr_stype;            /* synchronization event type */
	char pr_state;            /* numeric thread state */
	char pr_sname;            /* printable character for pr_state */
	char pr_nice;             /* nice for cpu usage */
	short pr_syscall;         /* system call number (if in syscall) */
	int pr_pri;               /* priority, high value = high priority */
	char pr_clname[PRCLSZ];   /* scheduling class name */
	processorid_t pr_onpro;   /* processor which last ran this thread */
	processorid_t pr_bindpro; /* processor to which thread is bound */
	psetid_t pr_bindpset;     /* processor set to which thread is bound */
} lwpsinfo_t;

pr_flag 字段是存储用于说明进程的标志的位掩码。表 25–3 中说明了这些标志及其含义。

表 25–3 pr_flag 值

PR_ISSYS

该进程为系统进程。 

PR_VFORKP

该进程是 vfork(2) 的子进程的父进程。

PR_FORK

该进程具有从 fork 中继承的模式集。 

PR_RLC

该进程具有最后一次关闭时运行的模式集。 

PR_KLC

该进程具有最后一次关闭时中止的模式集。 

PR_ASYNC

该进程具有异步停止模式集。 

PR_MSACCT

该进程已启用微状态记帐。 

PR_MSFORK

进程微状态记帐继承于 fork。 

PR_BPTADJ

该进程具有断点调整模式集。 

PR_PTRACE

该进程具有 ptrace(3C) 兼容的模式集。

PR_STOPPED

该线程是已停止的 LWP。 

PR_ISTOP

该线程是在出现关注的事件时停止的 LWP。 

PR_DSTOP

该线程是具有正在生效的停止指令的 LWP。 

PR_STEP

该线程是具有正在生效的单步指令的 LWP。 

PR_ASLEEP

该线程是系统调用的可中断休眠中的 LWP。 

PR_DETACH

该线程是拆离的 LWP。请参见 pthread_create(3C) 和 pthread_join(3C)。

PR_DAEMON

该线程是守护进程 LWP。请参见 pthread_create(3C)。

PR_AGENT

该线程是进程的代理 LWP。 

PR_IDLE

该线程是 CPU 的空闲线程。当 CPU 的运行队列为空时,空闲线程仅在 CPU 中运行。 

pr_addr 字段是表示线程的专用、内核中的数据结构的地址。虽然该数据结构为专用,但 pr_addr 字段可用作在线程的生命周期中线程的唯一标记。

当线程在同步对象上休眠时,将设置 pr_wchan 字段。pr_wchan 字段的含义专用于内核实现,但该字段也可用作同步对象的唯一标记。

当线程在同步对象上休眠时,将设置 pr_stype 字段。表 25–4 中说明了 pr_stype 字段的可能值。

表 25–4 pr_stype 值

SOBJ_MUTEX

内核互斥同步对象。用于串行化内核中共享数据区域的访问。有关内核互斥同步对象的详细信息,请参见第 18 章和 mutex_init(9F)。

SOBJ_RWLOCK

内核读取器/写入器同步对象。用于同步内核中共享对象的访问,共享对象可以允许多个并发读取器或一个写入器。有关内核读取器/写入器同步对象的详细信息,请参见第 18 章和 rwlock(9F)。

SOBJ_CV

条件变量同步对象。条件变量的设计是无限等待,直到某个条件变为 true。条件变量通常用于同步(出于访问共享数据区域之外的原因),它通常是当进程执行程序指令的无限等待时使用的机制。例如,在 poll(2)、pause(2)、wait(3C) 中阻塞,以及类似情况。

SOBJ_SEMA

信号同步对象。一般用途的同步对象,与条件变量对象一样,不跟踪拥有权说明。由于在 Solaris 内核中实现优先级继承必须具有拥有权,所以信号对象中没有固有拥有权将使这些对象不能被广泛使用。有关详细信息,请参见 semaphore(9F)。

SOBJ_USER

用户级同步对象。所有对用户级同步对象的阻塞都使用 SOBJ_USER 同步对象处理。用户级同步对象包括使用 mutex_init(3C)、sema_init(3C)、rwlock_init(3C)、cond_init(3C) 及其 POSIX 等效项创建的对象。

SOBJ_USER_PI

实现优先级继承的用户级同步对象。一些跟踪拥有权的用户级同步对象还允许优先级继承。例如,使用 pthread_mutex_init(3C) 创建的互斥对象可以使用 pthread_mutexattr_setprotocol(3C) 设置为继承优先级。

SOBJ_SHUTTLE

互动同步对象。互动对象用于实现门。有关更多信息,请参见 door_create(3DOOR)。 

pr_state 字段设置为表 25–5 中的某个值。pr_sname 字段设置为同一个表中括号内说明的相应字符。

表 25–5 pr_state 值

SSLEEP (S)

线程处于休眠状态。sched:::sleep 探测器就在线程的状态转换为 SSLEEP 之前的瞬间触发。

SRUN (R)

该线程可运行,但当前未运行。sched:::enqueue 探测器将在线程的状态转换为 SRUN 之前的瞬间触发。

SZOMB (Z)

该线程是僵 LWP。 

SSTOP (T)

由于显式 proc(4) 指令或一些其他停止机制,该线程已停止。

SIDL (I)

该线程是进程创建期间的中间状态。 

SONPROC (O)

该线程正在 CPU 中运行。sched:::on-cpu 探测器将在线程的状态转换为 SONPROC 一段时间后,在 SONPROC 线程的上下文中触发。

psinfo_t

多种 proc 探测器具有 psinfo_t(proc(4) 中记录的一种结构)类型的参数。DTrace 使用者可以使用的 psinfo_t 结构的定义如下所示:

typedef struct psinfo {
	int     pr_nlwp;            /* number of active lwps in the process */
	pid_t   pr_pid;             /* unique process id */
	pid_t   pr_ppid;            /* process id of parent */
	pid_t   pr_pgid;            /* pid of process group leader */
	pid_t   pr_sid;             /* session id */
	uid_t   pr_uid;             /* real user id */
	uid_t   pr_euid;            /* effective user id */
	gid_t   pr_gid;             /* real group id */
	gid_t   pr_egid;            /* effective group id */
	uintptr_t pr_addr;          /* address of process */
	dev_t   pr_ttydev;          /* controlling tty device (or PRNODEV) */
	timestruc_t pr_start;       /* process start time, from the epoch */
	char    pr_fname[PRFNSZ];   /* name of execed file */
	char    pr_psargs[PRARGSZ]; /* initial characters of arg list */
	int     pr_argc;            /* initial argument count */
	uintptr_t pr_argv;          /* address of initial argument vector */
	uintptr_t pr_envp;          /* address of initial environment vector */
	char    pr_dmodel;          /* data model of the process */
	taskid_t pr_taskid;         /* task id */
	projid_t pr_projid;         /* project id */
	poolid_t pr_poolid;         /* pool id */
	zoneid_t pr_zoneid;         /* zone id */
} psinfo_t;

pr_dmodel 字段设置为 PR_MODEL_ILP32(表示 32 位进程)或 PR_MODEL_LP64(表示 64 位进程)。

示例

exec

您可以使用 exec 探测器轻松地确定正在执行哪些程序以及由哪个用户执行,如下例所示:

#pragma D option quiet

proc:::exec
{
        self->parent = execname;
}

proc:::exec-success
/self->parent != NULL/
{
	@[self->parent, execname] = count();
	self->parent = NULL;
}

proc:::exec-failure
/self->parent != NULL/
{
	self->parent = NULL;
}

END
{
	printf("%-20s %-20s %s\n", "WHO", "WHAT", "COUNT");
	printa("%-20s %-20s %@d\n", @);
}

在生成计算机上运行示例脚本一段时间后将产生与以下示例类似的输出:


# dtrace -s ./whoexec.d
^C
WHO                  WHAT                 COUNT
make.bin             yacc                 1
tcsh                 make                 1
make.bin             spec2map             1
sh                   grep                 1
lint                 lint2                1
sh                   lint                 1
sh                   ln                   1
cc                   ld                   1
make.bin             cc                   1
lint                 lint1                1
sh                   lex                  1
make.bin             mv                   2
sh                   sh                   3
sh                   make                 3
sh                   sed                  4
sh                   tr                   4
make                 make.bin             4
sh                   install.bin          5
sh                   rm                   6
cc                   ir2hf                33
cc                   ube                  33
sh                   date                 34
sh                   mcs                  34
cc                   acomp                34
sh                   cc                   34
sh                   basename             34
basename             expr                 34
make.bin             sh                   87

start 和 exit

如果要知道程序从创建到终止所运行的时间,可以启用 start 和 exit 探测器,如下例所示:

proc:::start
{
	self->start = timestamp;
}

proc:::exit
/self->start/
{
	@[execname] = quantize(timestamp - self->start);
	self->start = 0;
}

在生成服务器上运行示例脚本几秒钟后将产生与以下示例类似的输出:


# dtrace -s ./progtime.d
dtrace: script './progtime.d' matched 2 probes
^C

  ir2hf                                             
           value  ------------- Distribution ------------- count
         4194304 |                                         0        
         8388608 |@                                        1        
        16777216 |@@@@@@@@@@@@@@@@                         14       
        33554432 |@@@@@@@@@@                               9        
        67108864 |@@@                                      3        
       134217728 |@                                        1        
       268435456 |@@@@                                     4        
       536870912 |@                                        1        
      1073741824 |                                         0        

  ube                                               
           value  ------------- Distribution ------------- count
        16777216 |                                         0        
        33554432 |@@@@@@@                                  6        
        67108864 |@@@                                      3        
       134217728 |@@                                       2        
       268435456 |@@@@                                     4        
       536870912 |@@@@@@@@@@@@                             10       
      1073741824 |@@@@@@@                                  6        
      2147483648 |@@                                       2        
      4294967296 |                                         0        

  acomp                                             
           value  ------------- Distribution ------------- count
         8388608 |                                         0        
        16777216 |@@                                       2        
        33554432 |                                         0        
        67108864 |@                                        1        
       134217728 |@@@                                      3        
       268435456 |                                         0        
       536870912 |@@@@@                                    5        
      1073741824 |@@@@@@@@@@@@@@@@@@@@@@@@@                22       
      2147483648 |@                                        1        
      4294967296 |                                         0        

  cc                                                
           value  ------------- Distribution ------------- count
        33554432 |                                         0        
        67108864 |@@@                                      3        
       134217728 |@                                        1        
       268435456 |                                         0        
       536870912 |@@@@                                     4        
      1073741824 |@@@@@@@@@@@@@@                           13       
      2147483648 |@@@@@@@@@@@@                             11       
      4294967296 |@@@                                      3        
      8589934592 |                                         0        

  sh                                                
           value  ------------- Distribution ------------- count
          262144 |                                         0        
          524288 |@                                        5        
         1048576 |@@@@@@@                                  29       
         2097152 |                                         0        
         4194304 |                                         0        
         8388608 |@@@                                      12       
        16777216 |@@                                       9        
        33554432 |@@                                       9        
        67108864 |@@                                       8        
       134217728 |@                                        7        
       268435456 |@@@@@                                    20       
       536870912 |@@@@@@                                   26       
      1073741824 |@@@                                      14       
      2147483648 |@@                                       11       
      4294967296 |                                         3        
      8589934592 |                                         1        
     17179869184 |                                         0        

  make.bin                                          
           value  ------------- Distribution ------------- count
        16777216 |                                         0        
        33554432 |@                                        1        
        67108864 |@                                        1        
       134217728 |@@                                       2        
       268435456 |                                         0        
       536870912 |@@                                       2        
      1073741824 |@@@@@@@@@                                9        
      2147483648 |@@@@@@@@@@@@@@@                          14       
      4294967296 |@@@@@@                                   6        
      8589934592 |@@                                       2        
     17179869184 |                                         0

lwp-start 和 lwp-exit

您可能不需要知道特定进程运行的时间,而需要知道各个线程运行的时间。以下示例说明了如何将 lwp-start 和 lwp-exit 探测器用于此目的:

proc:::lwp-start
/tid != 1/
{
	self->start = timestamp;
}

proc:::lwp-exit
/self->start/
{
	@[execname] = quantize(timestamp - self->start);
	self->start = 0;
}

在 NFS(网络文件系统)和日历服务器上运行示例脚本将产生与以下示例类似的输出:


# dtrace -s ./lwptime.d
dtrace: script './lwptime.d' matched 3 probes
^C

  nscd                                              
           value  ------------- Distribution ------------- count
          131072 |                                         0        
          262144 |@                                        18       
          524288 |@@                                       24       
         1048576 |@@@@@@@                                  75       
         2097152 |@@@@@@@@@@@@@@@@@@@@@@@                  245      
         4194304 |@@                                       22       
         8388608 |@@                                       24       
        16777216 |                                         6        
        33554432 |                                         3        
        67108864 |                                         1        
       134217728 |                                         1        
       268435456 |                                         0        

  mountd                                            
           value  ------------- Distribution ------------- count
          524288 |                                         0        
         1048576 |@                                        15       
         2097152 |@                                        24       
         4194304 |@@@                                      51       
         8388608 |@                                        17       
        16777216 |@                                        24       
        33554432 |@                                        15       
        67108864 |@@@@                                     57       
       134217728 |@                                        28       
       268435456 |@                                        26       
       536870912 |@@                                       39       
      1073741824 |@@@                                      45       
      2147483648 |@@@@@                                    72       
      4294967296 |@@@@@                                    77       
      8589934592 |@@@                                      55       
     17179869184 |                                         14       
     34359738368 |                                         2        
     68719476736 |                                         0        

  automountd                                        
           value  ------------- Distribution ------------- count
         1048576 |                                         0        
         2097152 |                                         3        
         4194304 |@@@@                                     146      
         8388608 |                                         6        
        16777216 |                                         6        
        33554432 |                                         9        
        67108864 |@@@@@                                    203      
       134217728 |@@                                       87       
       268435456 |@@@@@@@@@@@@@@@                          534      
       536870912 |@@@@@@                                   223      
      1073741824 |@                                        45       
      2147483648 |                                         20       
      4294967296 |                                         26       
      8589934592 |                                         20       
     17179869184 |                                         19       
     34359738368 |                                         7        
     68719476736 |                                         2        
    137438953472 |                                         0        

  iCald
           value  ------------- Distribution ------------- count
         8388608 |                                         0        
        16777216 |@@@@@@@                                  20       
        33554432 |@@@                                      9        
        67108864 |@@                                       8        
       134217728 |@@@@@                                    16       
       268435456 |@@@@                                     11       
       536870912 |@@@@                                     11       
      1073741824 |@                                        4        
      2147483648 |                                         2        
      4294967296 |                                         0        
      8589934592 |@@                                       8        
     17179869184 |@                                        5        
     34359738368 |@                                        4        
     68719476736 |@@                                       6        
    137438953472 |@                                        4        
    274877906944 |                                         2        
    549755813888 |                                         0

signal-send

您可以使用 signal-send 探测器确定与任何信号关联的发送和接收进程,如下例所示:

#pragma D option quiet

proc:::signal-send
{
	@[execname, stringof(args[1]->pr_fname), args[2]] = count();
}

END
{
	printf("%20s %20s %12s %s\n",
	    "SENDER", "RECIPIENT", "SIG", "COUNT");
	printa("%20s %20s %12d %@d\n", @);
}

运行此脚本将会生成与以下示例类似的输出:


# dtrace -s ./sig.d
^C
              SENDER            RECIPIENT          SIG COUNT
               xterm               dtrace            2 1
               xterm          soffice.bin            2 1
                  tr                 init           18 1
               sched                 test           18 1
               sched                fvwm2           18 1
                bash                 bash           20 1
                 sed                 init           18 2
               sched                  ksh           18 15
               sched                 Xsun           22 471

稳定性

proc 提供器使用 DTrace 的稳定性机制描述其稳定性,如下表所示。有关稳定性机制的更多信息,请参见第 39 章。

元素 

名称稳定性 

数据稳定性 

相关性类 

提供器 

发展中 

发展中 

ISA

模块 

专用 

专用 

未知 

功能 

专用 

专用 

未知 

名称 

发展中 

发展中 

ISA

参数 

发展中 

发展中 

ISA