Solaris 動的トレースガイド

第 25 章 proc プロバイダ

proc プロバイダは、プロセスの作成と終了、軽量プロセス (LWP) の作成と終了、新しいプログラムイメージの実行、およびシグナルの送信と処理に関連するプローブを使用できるようにします。

プローブ

表 25–1 では、proc プローブについて説明します。

表 25–1 proc プローブ

プローブ 

説明 

create

fork(2)forkall(2)fork1(2)vfork(2) のいずれかを使ってプロセスが作成されたときに起動するプローブ。args[0] は、新しい子プロセスの psinfo_t をポイントしています。vfork とその他の fork のバリエーションとの違いは、フォークスレッドの lwpsinfo_t で、pr_flag メンバー内の PR_VFORKP を調べるとわかります。fork1forkall との違いは、親プロセスの psinfo_t (curpsinfo) と子プロセスの psinfo_t (args[0]) の両方の pr_nlwp メンバーを調べるとわかります。create プローブはプロセスが正常に作成されてから起動します。また、LWP はプロセスの作成時に作成されます。このため、まずプロセス作成時に作成された LWP に対して lwp-create が起動し、その後、新しいプロセスに対して create プローブが起動します。

exec

exec(2) システムコールのバリエーション、exec(2)execle(2)execlp(2)execv(2)execve(2)execvp(2) のいずれかを使って、プロセスが新しいプロセスイメージをロードするときに起動するプローブ。exec プローブは、プロセスイメージがロードされるに起動します。したがって、execnamecurpsinfo などのプロセス変数には、イメージがロードされる前のプロセス状態が格納されます。exec プローブの起動後しばらくすると、同じスレッド内で exec-failure プローブか exec-success プローブが起動します。args[0] は、新しいプロセスイメージのパスをポイントします。

exec-failure

exec(2) のバリエーションのいずれかが失敗したときに起動するプローブ。exec-failure プローブは、同じスレッド内で exec プローブが起動したあとでのみ起動します。args[0] には、errno(3C) の値が入ります。

exec-success

exec(2) のバリエーションのいずれかが成功したときに起動するプローブ。exec-success も、exec-failure プローブと同じように、同じスレッド内で exec プローブが起動したあとでのみ起動します。exec-success プローブが起動したときにはすでに、execnamecurpsinfo などのプロセス変数には、新しいプロセスイメージがロードされたあとのプロセス状態が格納されています。

exit

現在のプロセスが終了する直前に起動するプローブ。終了理由を表す SIGCHLD siginfo.h(3HEAD) コードが、args[0] に格納されます。

fault

スレッドがマシンフォルトを検出したときに起動するプローブ。args[0] には、proc(4) に定義されているようにフォルトコードが格納されます。args[1] は、このフォルトの siginfo 構造体をポイントします。fault プローブをトリガーできるのは、シグナルを発行するフォルトだけです。

lwp-create

LWP の作成時に起動するプローブ。LWP は、通常、thr_create(3C) の結果として作成されます。args[0] は、新しいスレッドの lwpsinfo_t をポイントしています。args[1] は、このスレッドが含まれているプロセスの psinfo_t をポイントしています。

lwp-start

新しく作成された LWP のコンテキストで起動するプローブ。lwp-start プローブは、ユーザーレベルの命令が実行される前に起動します。LWP がプロセス内の最初の LWP である場合は、まず start プローブが起動し、続いて lwp-start プローブが起動します。

lwp-exit

シグナル、または thr_exit(3C) の明示的な呼び出しによって、LWP が終了する直前に起動するプローブ。

signal-discard

シングルスレッドプロセスに送信されたシグナルが、プロセスによってブロックされず、かつ無視されたときに、起動するプローブ。この条件下では、シグナルは作成後すぐに破棄されます。ターゲットプロセスとスレッドの lwpsinfo_tpsinfo_t は、それぞれ args[0]args[1] に格納されます。シグナル番号は args[2] に格納されます。

signal-send

スレッドまたはプロセスにシグナルが送信されたときに起動するプローブ。signal-send プローブは、送信側のプロセスとスレッドのコンテキストで起動します。受信側のプロセスとスレッドの lwpsinfo_tpsinfo_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 型の引数をとります。構造体 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

プロセスがフォーク時継承モードを設定しました。 

PR_RLC

プロセスが最終終了時実行モードを設定しました。 

PR_KLC

プロセスが最終終了時終了モードを設定しました。 

PR_ASYNC

プロセスが非同期停止モードを設定しました。 

PR_MSACCT

プロセスが microstate アカウンティングを有効にしました。 

PR_MSFORK

プロセスの microstate アカウンティングがフォーク時に継承されました。 

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 の実行キューが空のときにだけ実行されます。 

pr_addr フィールドは、スレッドを表す非公開のカーネル内データ構造のアドレスです。データ構造体が非公開でも、pr_addr フィールドは、スレッドの有効期限が切れるまで、そのスレッド固有のトークンとして使用できます。

pr_wchan フィールドは、同期オブジェクト上でスレッドがスリープ状態になっているときに設定されます。pr_wchan フィールドの意味はカーネル実装以外に対しては公開されませんが、フィールド自体は、同期オブジェクトに固有のトークンとして使用できます。

pr_stype フィールドは、同期オブジェクト上でスレッドがスリープ状態になっているときに設定されます。表 25–4 に、pr_stype フィールドに入る値を一覧します。

表 25–4 pr_stype の値

SOBJ_MUTEX

カーネル相互排他同期オブジェクト。カーネル内の共有データ領域へのアクセスを直列化するために使用します。カーネル相互排他同期オブジェクトの詳細については、第 18 章lockstat プロバイダmutex_init(9F) のマニュアルページを参照してください。

SOBJ_RWLOCK

カーネル読み取り/書き込み同期オブジェクト。カーネル内の共有オブジェクトへのアクセスを同期化するために使用します。カーネル内の共有オブジェクトへのアクセスでは、同時に複数の読み取り、または単一の書き込みが許可されます。カーネル読み取り/書き込み同期オブジェクトの詳細については、第 18 章lockstat プロバイダrwlock(9F) のマニュアルページを参照してください。

SOBJ_CV

条件変数同期オブジェクト。条件変数は、一定の条件が揃うまで待機し続けるように設計されています。通常、条件変数は、共有データ領域へのアクセス以外の目的で同期化を行うために使用します。条件変数は、一般的にプロセスがプログラムに従って待機するときに使用されます。たとえば、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 の実装に使用します。詳細については、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 型の引数をとります。構造体 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 フィールドには、32 ビットプロセスであることを示す PR_MODEL_ILP32 と 64 ビットプロセスであることを示す PR_MODEL_LP64 のいずれかが設定されます。

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

startexit

プログラムが作成されてから終了するまでの実行時間を調べたい場合は、次の例のように 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-startlwp-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