Guia de rastreamento dinâmico Solaris

Capítulo 25 Provedor proc

O provedor proc disponibiliza os testes que pertencem às seguintes atividades: criação e finalização de processo, criação e finalização de LWP, execução de novas imagens de programa e envio e tratamento de sinais.

Testes

Os testes proc são descritos na Tabela 25–1.

Tabela 25–1 Testes proc

Teste 

Descrição 

create

Teste que é acionado quando um processo é criado usando fork(2), forkall(2), fork1(2) ou vfork(2). A psinfo_t correspondente ao novo processo filho é apontada por args[0]. Você pode distinguir vfork das outras variantes de fork procurando por PR_VFORKPno membro pr_flag da lwpsinfo_t do segmento de fork. Você pode distinguir fork1 de forkall examinando os membros pr_nlwp de psinfo_t (curpsinfo) do processo pai e psinfo_t (args[0]) do processo filho. Como o teste create só é acionado depois que o processo é criado com êxito, e como a criação de LWP faz parte da criação de um processo, lwp-create será acionado para quaisquer LWPs criados durante a criação do processo antes que o teste create seja acionado no novo processo.

exec

Teste que é acionado sempre que um processo carregar uma nova imagem do processo com uma variante da chamada do sistema exec(2): exec(2), execle(2), execlp(2), execv(2), execve(2), execvp(2). O teste exec é acionado antes que a imagem do processo seja carregada. As variáveis de processo como execname e curpsinfo, portanto, contêm o estado do processo antes da imagem ser carregada. Algum tempo depois que o teste exec é acionado, o teste exec-failure ou o teste exec-success será, subseqüentemente, acionado no mesmo segmento. O caminho da nova imagem do processo é apontado por args[0].

exec-failure

Teste que é acionado quando uma variante exec(2) tiver falhado. O teste exec-failure é acionado somente depois que o teste exec tiver sido acionado no mesmo segmento. O valor de errno(3C) é fornecido em args[0] .

exec-success

Teste que é acionado quando uma variante exec(2) tiver sido bem-sucedida. Como o teste exec-failure, o teste exec-success é acionado somente depois que o teste exec é acionado no mesmo segmento. No momento em que o teste exec-success é acionado, variáveis de processo como execname e curpsinfo contêm o estado do processo depois que a nova imagem do processo tiver sido carregada.

exit

Teste que é acionado quando o processo atual está sendo encerrado. A razão do encerramento, que é expressada como um dos códigos SIGCHLD siginfo.h(3HEAD), está contida em args[0].

fault

Teste que é acionado quando uma falha de máquina ocorre em um segmento. O código da falha (conforme definido em proc(4)) está em args[0]. A estrutura siginfo correspondente à falha é apontada por args[1]. Somente as falhas que induzem a um sinal podem acionar o teste fault.

lwp-create

Teste que é acionado quando um LWP é criado, geralmente como resultado de thr_create(3C). A lwpsinfo_t correspondente ao novo segmento é apontada por args[0]. A psinfo_t do processo que contém o segmento é apontada por args[1].

lwp-start

Teste que é acionado no contexto de um LWP recém-criado. O teste lwp-start será acionado antes que quaisquer instruções no nível do usuário sejam executadas. Se o LWP for o primeiro LWP no processo, o teste start será acionado, seguido por lwp-start.

lwp-exit

Teste que é acionado quando um LWP está sendo encerrado, seja devido a um sinal ou a uma chamada explícita para thr_exit(3C).

signal-discard

Teste que é acionado quando um sinal é enviado para um processo de segmento único, e o sinal é desbloqueado e ignorado pelo processo. Sob essas condições, o sinal é descartado ao ser gerado. A lwpsinfo_t e a psinfo_t do processo e do segmento de destino estão, respectivamente, em args[0] e args[1]. O número do sinal está em args[2] .

signal-send

Teste que é acionado quando um sinal é enviado para um segmento ou processo. O teste signal-send é acionado no contexto do processo e do segmento de envio. A lwpsinfo_t e a psinfo_t do processo e do segmento de recebimento estão, respectivamente, em args[0] e args[1]. O número do sinal está em args[2] . signal-send é sempre seguida por signal-handle ou signal-clear no processo e no segmento de recebimento.

signal-handle

Teste que é acionado imediatamente antes de um teste manipular um sinal. O teste signal-handle é acionado no contexto do segmento que irá manipular o sinal. O número do sinal está em args[0] . Um ponteiro para a estrutura siginfo_t que corresponde ao sinal está em args[1]. O valor de args[1] é NULL se não houver nenhuma estrutura siginfo_t ou se o manipulador de sinal não tiver o sinalizador SA_SIGINFO definido. O endereço do manipulador de sinal no processo está em args[2].

signal-clear

Teste que é acionado quando um sinal pendente é cancelado porque o segmento de destino estava aguardando pelo sinal em sigwait(2), sigwaitinfo(3RT) ou sigtimedwait(3RT). Sob essas condições, o sinal pendente é cancelado e o número do sinal é retornado ao chamador. O número do sinal está em args[0] . signal-clear é acionado no contexto do segmento que estava aguardando anteriormente.

start

Teste que é acionado no contexto de um processo recém-criado. O teste start será acionado antes que quaisquer instruções no nível do usuário sejam executadas no processo.

Argumentos

Os tipos de argumentos dos testes proc são listados na Tabela 25–2. Os argumentos são descritos na Tabela 25–1.

Tabela 25–2 Argumentos do teste proc

Teste 

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

Vários testes proc possuem argumentos do tipo lwpsinfo_t, uma estrutura documentada em proc(4). A definição da estrutura lwpsinfo_t conforme disponível para os consumidores do DTrace é a seguinte:

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;

O campo pr_flag é uma máscara de bits com sinalizadores que descrevem o processo. Esses sinalizadores e seus significados são descritos na Tabela 25–3.

Tabela 25–3 Valores de pr_flag

PR_ISSYS

O processo é um processo do sistema. 

PR_VFORKP

O processo é pai de um filho de vfork(2).

PR_FORK

O processo possui o modo herança-em-bifurcação definido. 

PR_RLC

O processo possui o modo execução-em-último-encerramento definido. 

PR_KLC

O processo possui o modo eliminação-em-último-encerramento definido. 

PR_ASYNC

O processo possui o modo interrupção-assíncrona definido. 

PR_MSACCT

O processo possui a contabilidade de micro-estado ativada. 

PR_MSFORK

A contabilidade do micro-estado do processo é herdada na bifurcação. 

PR_BPTADJ

O processo possui o modo de ajuste de ponto de interrupção definido. 

PR_PTRACE

O processo possui o modo de compatibilidade com ptrace(3C) definido.

PR_STOPPED

O segmento é um LWP que está interrompido. 

PR_ISTOP

O segmento é um LWP interrompido em um evento de interesse. 

PR_DSTOP

O segmento é um LWP que possui uma diretiva de interrupção em efeito. 

PR_STEP

O segmento é um LWP que possui uma diretiva de etapa única em efeito. 

PR_ASLEEP

O segmento é um LWP em uma espera que pode ser interrompida em uma chamada do sistema. 

PR_DETACH

O segmento é um LWP desanexado. Consulte pthread_create(3C) e pthread_join(3C).

PR_DAEMON

O segmento é um LWP daemon. Consulte pthread_create(3C).

PR_AGENT

O segmento é o LWP do agente do processo. 

PR_IDLE

O segmento é o segmento inativo de uma CPU. Segmentos inativos somente são executados em uma CPU quando as filas de execução da CPU estão vazias. 

O campo pr_addr é o endereço de uma estrutura de dados no kernel, privada, que representa o segmento. Embora a estrutura de dados seja privada, o campo pr_addr pode ser usado como um símbolo exclusivo de um segmento enquanto o segmento existir.

O campo pr_wchan é definido quando o segmento está em modo de espera em um objeto de sincronização. O significado do campo pr_wchan é privado para a implementação do kernel, mas o campo pode ser usado como um símbolo exclusivo para o objeto de sincronização.

O campo pr_stype é definido quando o segmento está em modo de espera em um objeto de sincronização. Os possíveis valores do campo pr_stype estão na Tabela 25–4.

Tabela 25–4 Valores de pr_stype

SOBJ_MUTEX

Objeto de sincronização do mutex do kernel. Usado para serializar o acesso a regiões de dados compartilhados no kernel. Consulte o Capítulo 18Provedor lockstat e mutex_init(9F) para obter detalhes sobre objetos de sincronização do mutex no kernel.

SOBJ_RWLOCK

Objeto de sincronização de leitores/gravador do kernel. Usado para sincronizar o acesso aos objetos compartilhados no kernel que pode permitir vários leitores simultâneos ou um único gravador. Consulte o Capítulo 18Provedor lockstat e rwlock(9F) para obter detalhes sobre objetos de sincronização de leitores/gravador no kernel.

SOBJ_CV

Objeto de sincronização de variável de condição. Uma variável de condição aguarda indefinidamente até que alguma condição torne-se verdadeira. Variáveis de condição geralmente são usadas para sincronizar por razões diferentes do acesso a uma região de dados compartilhados, e são o mecanismo geralmente usado quando um processo realiza uma espera indefinida direcionada pelo programa. Por exemplo, o bloqueio em poll(2), pause(2), wait(3C) e semelhantes.

SOBJ_SEMA

Objeto de sincronização de semáforo. Um objeto de sincronização de vários objetivos que, assim como os objetos de variável de condição, não controla uma noção de propriedade. Como a propriedade é necessária para implementar a herança de prioridade no kernel do Solaris, a falta de propriedade inerente em objetos de semáforo impede seu uso amplo. Consulte semaphore(9F) para obter detalhes.

SOBJ_USER

Objeto de sincronização no nível do usuário. Todos os bloqueios em objetos de sincronização no nível do usuário são manipulados com objetos de sincronização SOBJ_USER . Os objetos de sincronização no nível do usuário incluem aqueles criados com mutex_init(3C), sema_init(3C), rwlock_init(3C), cond_init(3C) e seus equivalentes POSIX.

SOBJ_USER_PI

Objeto de sincronização no nível do usuário que implementa a herança de prioridade. Alguns objetos de sincronização no nível do usuário que controlam a propriedade adicionalmente permitem a herança de prioridade. Por exemplo, objetos do mutex criados com pthread_mutex_init(3C) podem ser feitos para herdar prioridade usando-se pthread_mutexattr_setprotocol(3C).

SOBJ_SHUTTLE

Objeto de sincronização de deslocamento. Objetos de deslocamento são usados para implementar portas. Consulte door_create(3DOOR) para obter mais informações. 

O campo pr_state é definido como um dos valores na Tabela 25–5. O campo pr_sname é definido como um caractere correspondente mostrado entre parênteses na mesma tabela.

Tabela 25–5 Valores de pr_state

SSLEEP (S)

O segmento está em espera. O teste sched:::sleep será acionado imediatamente antes que o estado de um segmento passe para SSLEEP.

SRUN (R)

O segmento é executável, mas não está sendo executado no momento. O teste sched:::enqueue será acionado imediatamente antes que o estado de um segmento passe para SRUN.

SZOMB (Z)

O segmento é um LWP zumbi. 

SSTOP (T)

O segmento é interrompido, seja devido a uma diretiva proc(4) explícita ou a algum outro mecanismo de interrupção.

SIDL (I)

O segmento é um estado intermediário durante a criação do processo. 

SONPROC (O)

O segmento está sendo executado em uma CPU. O teste sched:::on-cpu será acionado no contexto do segmento SONPROC logo depois que o estado do segmento passar para SONPROC.

psinfo_t

Vários testes proc possuem um argumento do tipo psinfo_t, uma estrutura documentada em proc(4). A definição da estrutura de psinfo_t conforme disponível aos consumidores do DTrace é a seguinte:

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;

O campo pr_dmodel é definido como PR_MODEL_ILP32 , indicando um processo de 32 bits, ou PR_MODEL_LP64, indicando um processo de 64 bits.

Exemplos

exec

Você pode usar o teste exec para determinar facilmente quais programas estão sendo executados, e por quem, conforme mostrado no seguinte exemplo:

#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", @);
}

A execução do script de exemplo por um curto período de tempo em uma máquina de compilação produz um resultado similar ao seguinte exemplo:


# 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 e exit

Se você desejar saber o tempo de execução dos programas da criação ao encerramento, poderá ativar os testes start e exit, conforme mostrado no exemplo a seguir:

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

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

A execução do script de exemplo no servidor de compilação por vários segundos produz um resultado similar ao seguinte exemplo:


# 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 e lwp-exit

Em vez de saber quanto tempo um processo em particular demora para ser executado, talvez você queira saber quanto tempo segmentos individuais demoram para ser executados. O exemplo a seguir mostra como usar os testes lwp-start e lwp-exit com esta finalidade:

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

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

A execução do script de exemplo em um servidor de calendário e NFS produz um resultado similar ao seguinte exemplo:


# 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

Você pode usar o teste signal-send para determinar o processo de envio e recebimento associado a qualquer sinal, conforme mostrado no exemplo a seguir:

#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", @);
}

Executar este script acima resultará numa saída semelhante ao exemplo seguinte:


# 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

Estabilidade

O provedor proc usa o mecanismo de estabilidade do DTrace para descrever suas estabilidades, conforme mostrado na tabela a seguir. Para obter mais informações sobre o mecanismo de estabilidade, consulte o Capítulo 39Estabilidade.

Elemento 

Estabilidade de nome 

Estabilidade de dados 

Classe de dependência 

Provedor 

Desenvolvendo 

Desenvolvendo 

ISA

Módulo 

Privada 

Privada 

Desconhecida 

Função 

Privada 

Privada 

Desconhecida 

Nome 

Desenvolvendo 

Desenvolvendo 

ISA

Argumentos 

Desenvolvendo 

Desenvolvendo 

ISA