Guia de rastreamento dinâmico Solaris

Capítulo 15 Script

Você pode usar o utilitário dtrace(1M) para criar arquivos do intérprete a partir de programas em D semelhantes para criar shell de scripts que você pode instalar como ferramentas interativas reutilizáveis do DTrace. O compilador de D e o comando dtrace oferecem um conjunto de variáveis de macro expandidas pelo compilador de D que facilitam a criação de scripts. Este capítulo fornece uma referência do recurso de variável de macro e dicas para a criação de scripts persistentes.

Arquivos de intérprete

Semelhante ao shell e aos utilitários, tais como awk(1) e perl(1), o dtrace(1M) pode ser usado para criar arquivos de intérprete executáveis. Um arquivo de intérprete começa com uma linha do formato:

#! nome do caminho arg

onde nome do caminho é o caminho do intérprete e arg é um único argumento opcional. Quando um arquivo de intérprete é executado, o sistema chama o intérprete especificado. Se arg foi especificado no arquivo do intérprete, ele é passado como um argumento para o intérprete. O caminho para o próprio arquivo do intérprete e quaisquer argumentos adicionais especificados quando ele foi executado são, em seguida, adicionados à lista de argumentos do intérprete. Portanto, você sempre precisará criar arquivos de intérprete do DTrace com pelo menos estes argumentos:

#!/usr/sbin/dtrace -s

Quando o seu arquivo de intérprete é executado, o argumento para a opção - s será, portanto, o nome do caminho do próprio arquivo do intérprete. dtrace irá, em seguida, ler, compilar e executar este arquivo, como se você tivesse digitado o seguinte comando no shell:


# dtrace -s interpreter-file

O exemplo seguinte mostra como criar e executar um arquivo de intérprete do dtrace . Digite o seguinte código-fonte de D e salve-o em um arquivo chamado interp.d:

#!/usr/sbin/dtrace -s
BEGIN
{
	trace("hello");
	exit(0);
}

Marque o arquivo interp.d como executável e execute-o da seguinte forma:


# chmod a+rx interp.d
# ./interp.d
dtrace: script './interp.d' matched 1 probe
CPU     ID                    FUNCTION:NAME
  1      1                           :BEGIN   hello
#

Lembre-se que a diretiva #! deve compreender os dois primeiros caracteres do seu arquivo sem espaço em branco precedente ou intermediário. O compilador de D sabe como ignorar automaticamente esta linha quando processa o arquivo de intérprete.

O dtrace usa getopt(3C) para processar opções da linha de comando, para que você possa combinar várias opções em seu único argumento de intérprete. Por exemplo, para adicionar a opção -q ao exemplo anterior, você poderia alterar a diretiva do intérprete para:

#!/usr/sbin/dtrace -qs

Se você especificar letras de várias opções, a opção -s deve sempre terminar a lista de opções booleanas, para que o próximo argumento (o nome do arquivo do intérprete) seja processado como o argumento correspondente à opção -s.

Se você precisar especificar mais de uma opção que requeira um argumento em seu arquivo de intérprete, suas opções e argumentos não caberão em um único argumento de intérprete. Em vez disso, use a sintaxe de diretiva da opção #pragma de D para definir suas opções. Todas as opções da linha de comando do dtrace possuem #pragma equivalentes que você pode usar, conforme mostrado no Capítulo 16Opções e ajustáveis.

Variáveis de macro

O compilador de D define um conjunto de variáveis de macro incorporadas que você pode usar ao escrever programas em D ou arquivos de intérprete. As variáveis de macro são identificadores prefixados com um sinal de dólar ($) e são expandidos apenas pelo compilador de D ao processar o seu arquivo de entrada. O compilador de D fornece as seguintes variáveis de macro:

Tabela 15–1 Variáveis de macro de D

Nome 

Descrição 

Referência 

$[0-9]+

argumentos de macro 

Consulte Argumentos de macro

$egid

ID de grupo efetivo 

getegid(2)

$euid

ID de usuário efetivo 

geteuid(2)

$gid

ID de grupo real 

getgid(2)

$pid

ID do processo 

getpid(2)

$pgid

ID de grupo de processo 

getpgid(2)

$ppid

ID de processo-pai 

getppid(2)

$projid

ID do projeto 

getprojid(2)

$sid

ID de sessão 

getsid(2)

$target

ID do processo de destino 

Consulte ID do processo de destino

$taskid

ID de tarefa 

gettaskid(2)

$uid

ID de usuário real 

getuid(2)

Exceto para os argumentos de macro $[0-9]+ e a variável de macro $target, todas as variáveis de macro se expandem para inteiros correspondentes aos atributos do sistema, tais como ID do processo e ID do usuário. As variáveis se expandem para o valor de atributo associado ao próprio processo do dtrace atual, ou a qualquer processo que esteja sendo executado no compilador de D.

Usar variáveis de macro em arquivos de intérprete permite que você crie programas em D duradouros que não precisam ser editados toda vez que deseja usá-los. Por exemplo, para contar todas as chamadas do sistema exceto aquelas executadas pelo comando dtrace, use a seguinte cláusula do programa em D contendo $pid:

syscall:::entry
/pid != $pid/
{
	@calls = count();
}

Esta cláusula sempre produz o resultado desejado, embora cada chamada do comando dtrace tenha um ID de processo diferente.

As variáveis de macro podem ser usadas em qualquer lugar que um inteiro, identificador ou seqüência possam ser usados em um programa em D. As variáveis de macro são expandidas apenas uma vez (ou seja, não recursivamente) quando a saída é analisada. Cada variável de macro é expandida para formar um símbolo de entrada separado, e não pode ser concatenada com outro texto para produzir um símbolo único. Por exemplo, se $pid se expandisse para o valor 456, o código de D:

123$pid

se expandiria para os dois símbolos adjacentes 123 e 456, resultando em um erro de sintaxe, em vez de um único símbolo de inteiro 123456.

As variáveis de macro são expandidas e concatenadas com texto adjacente dentro de descrições de teste de D no início das suas cláusulas de programa. Por exemplo, a cláusula seguinte usa o provedor pid do DTrace para instrumentar o comando dtrace:

pid$pid:libc.so:printf:entry
{
	...
}

As variáveis de macro são expandidas apenas uma vez em cada campo de descrição de teste; elas talvez não contenham delimitadores de descrição de teste (:).

Argumentos de macro

O compilador de D também fornece um conjunto de variáveis de macro correspondentes a quaisquer operandos de argumento adicionais especificados como parte da chamada do comando dtrace. Estes argumentos de macro são acessados através de nomes incorporados $0 do nome do arquivo do programa em D ou do comando dtrace , $1 do primeiro operando adicional, $2 do segundo operando, e assim por diante. Se você usar a opção -s do dtrace , $0 se expandirá para o valor do nome do arquivo de entrada usado com esta opção. Para programas em D especificados na linha de comando, $0 se expande para o valor de argv[0] usado para executar o próprio dtrace.

Os argumentos de macro podem se expandir para inteiros, identificadores ou seqüências, dependendo do formato do texto correspondente. Como acontece com todas as variáveis de macro, os argumentos de macro podem ser usados em qualquer lugar em que um inteiro, um identificador e os símbolos de seqüência possam ser usados em um programa em D. Todos os exemplos seguintes poderiam formar expressões de D válidas, presumindo-se que os valores de argumento de macro estejam apropriados:

execname == $1    /* with a string macro argument */
x += $1           /* with an integer macro argument */
trace(x->$1)      /* with an identifier macro argument */

Os argumentos de macro podem ser usados para criar arquivos de intérprete do dtrace que agem como comandos reais do Solaris e usam informações especificadas por um usuário ou por outra ferramenta para modificar seu comportamento. Por exemplo, o arquivo de intérprete de D rasteia as chamadas do sistema write(2) executadas por um ID de processo específico:

#!/usr/sbin/dtrace -s

syscall::write:entry
/pid == $1/
{
}

Se você tornar este arquivo de intérprete executável, poderá especificar o valor de $1 usando argumentos de linha de comando adicionais em seu arquivo de intérprete:


# chmod a+rx ./tracewrite
# ./tracewrite 12345

A chamada de comando resultante conta cada chamada do sistema write(2) executada pelo ID de processo 12345.

Se o seu programa em D fizer referência a um argumento de macro que não seja fornecido na linha de comando, será impressa uma mensagem de erro apropriada e o seu programa não será compilado:


# ./tracewrite
dtrace: failed to compile script ./tracewrite: line 4:
  macro argument $1 is not defined

Os programas em D poderão fazer referência a argumentos de macro não especificados, se a opção defaultargs estiver definida. Se defaultargs estiver definida, os argumentos não especificados terão o valor 0. Consulte o Capítulo 16Opções e ajustáveis para obter mais informações sobre as opções do compilador de D. O compilador de D também produzirá uma mensagem de erro, se forem especificados argumentos adicionais na linha de comando que não tenham sido referenciados por seu programa em D.

Os valores de argumento de macro devem correspondem ao formato de um inteiro, identificador ou seqüência. Se o argumento não corresponder a nenhum desses formatos, o compilador de D informará uma mensagem de erro apropriada. Ao especificar argumentos de macro de seqüência para um arquivo de intérprete do DTrace, coloque o argumento entre um par de aspas simples extra a fim de evitar a interpretação das aspas duplas e do conteúdo da seqüência pelo seu shell:


# ./foo '"a string argument"'

Se você quiser que os seus argumentos de macro de D sejam interpretados como símbolos de seqüência mesmo que eles correspondam a um inteiro ou identificador, coloque um prefixo na variável de macro ou nome do argumento com dois sinais de dólar à esquerda (por exemplo, $$1) para forçar o compilador de D a interpretar o valor do argumento como se ele fosse uma seqüência entre aspas duplas. Todas as seqüências de escape de seqüência de D (consulte a Tabela 2–5) são expandidas dentro de quaisquer argumentos de macro de seqüência, independentemente de serem referenciadas através do formato $arg ou $$arg da macro. Se a opção defaultargs estiver definida, os argumentos não especificados que são referenciados com o formato $$arg possuem o valor da seqüência vazia ("").

ID do processo de destino

Use a variável de macro $target para criar scripts que possam ser aplicados a um processo de usuário específico de seu interesse que seja selecionado na linha de comando do dtrace com a opção -p ou criado com a opção -c. Os programas em D especificados na linha de comando ou com a opção -s são compilados depois que os processos são criados ou capturados, e a variável $target se expande para o ID de processo de inteiro do primeiro processo desse tipo. Por exemplo, o script de D poderia ser usado para determinar a distribuição de chamadas do sistema executadas por processo de assunto específico:

syscall:::entry
/pid == $target/
{
	@[probefunc] = count();
}

Para determinar o número de chamadas do sistema executadas pelo comando date(1) salve o script no arquivo syscall.d e execute o seguinte comando:


# dtrace -s syscall.d -c date
dtrace: script 'syscall.d' matched 227 probes
Fri Jul 30 13:46:06 PDT 2004
dtrace: pid 109058 has exited

  gtime                                                             1
  getpid                                                            1
  getrlimit                                                         1
  rexit                                                             1
  ioctl                                                             1
  resolvepath                                                       1
  read                                                              1
  stat                                                              1
  write                                                             1
  munmap                                                            1
  close                                                             2
  fstat64                                                           2
  setcontext                                                        2
  mmap                                                              2
  open                                                              2
  brk                                                               4