Guia de rastreamento dinâmico Solaris

Adicionando testes a um aplicativo

Os testes do DTrace em bibliotecas e executáveis são definidos em uma seção ELF no binário do aplicativo correspondente. Esta seção descreve como definir seus testes, adicioná-los ao código-fonte do seu aplicativo, e argumenta o processo de construção do seu aplicativo para incluir as definições de teste do DTrace.

Definindo provedores e testes

Você define os testes do DTrace em um arquivo-fonte .d que é, em seguida, usado durante a compilação e vinculação do seu aplicativo. Primeiro, selecione um nome apropriado no seu provedor de aplicativo do usuário. O nome do provedor que você escolher será anexado ao identificador de cada processo que esteja executando o código do seu aplicativo. Por exemplo, se você escolhesse o nome de provedor myserv para um servidor da Web que estava sendo executado como o ID de processo 1203, o nome do provedor do DTrace correspondente a este processo seria myserv1203. Em seu arquivo-fonte .d, adicione uma definição de provedor semelhante ao exemplo seguinte:

provider myserv {
	...
};			

Em seguida, adicione uma definição para cada teste e os argumentos correspondentes. O exemplo seguinte define os dois testes discutidos em Escolhendo os pontos de teste. O primeiro teste possui dois argumentos, ambos do tipo string, e o segundo teste não possui argumentos. O compilador de D converte dois sublinhados consecutivos (__) em qualquer nome de teste em um hífen (-).

provider myserv {
	probe query__receive(string, string);
	probe query__respond();
};

Você deve adicionar os atributos de estabilidade à definição do seu provedor para que os consumidores de testes entendam a probabilidade de alteração nas futuras versões do seu aplicativo. Consulte o Capítulo 39Estabilidade para obter mais informações sobre os atributos de estabilidade do DTrace. Os atributos de estabilidade são definidos como mostrado no exemplo seguinte:


Exemplo 34–1 myserv.d: testes de aplicativo definidos estaticamente

#pragma D attributes Evolving/Evolving/Common provider myserv provider
#pragma D attributes Private/Private/Unknown provider myserv module
#pragma D attributes Private/Private/Unknown provider myserv function
#pragma D attributes Evolving/Evolving/Common provider myserv name
#pragma D attributes Evolving/Evolving/Common provider myserv args

provider myserv {
	probe query__receive(string, string);
	probe query__respond();
};


Observação –

Os scripts de D que usam argumentos não inteiros dos testes adicionados pelo usuário devem usar as funções copyin() e copyinstr() para recuperar tais argumentos. Consulte o Capítulo 33Rastreio de processo do usuário para obter mais informações.


Adicionando testes ao código do aplicativo

Agora que você definiu seus testes em um arquivo .d, é necessário argumentar seu código-fonte para indicar os locais que devem disparar seus testes. Considere o exemplo seguinte de código-fonte de aplicativo em C:

void
main_look(void)
{
	...
	query = wait_for_new_query();
	process_query(query)
	...
}

Para adicionar um local de teste, acrescente uma referência à macro DTRACE_PROBE() definida em <sys/sdt.h> como mostrado no exemplo seguinte:

#include <sys/sdt.h>
...

void
main_look(void)
{
	...
	query = wait_for_new_query();
	DTRACE_PROBE2(myserv, query__receive, query->clientname, query->msg);
	process_query(query)
	...
}

O sufixo 2 no nome da macro DTRACE_PROBE2 se refere ao número de argumentos que são passados para o teste. Os dois primeiros argumentos para a macro do teste são o nome do provedor e o nome do teste e devem corresponder ao seu provedor e definições de teste de D. Os argumentos da macro restantes são aqueles atribuídos às variáveis arg0..9 do DTrace quando o teste é acionado. O código-fonte do seu aplicativo pode conter várias referências ao mesmo provedor e nome de teste. Se houver várias referências ao mesmo teste em seu código-fonte, qualquer uma dessas referências de macro farão com que o teste seja acionado.

Construindo aplicativos com testes

Você deve aumentar o processo de construção em seu aplicativo para incluir o provedor e as definições de teste do DTrace. Um processo de construção típico pega cada arquivo-fonte e compila-o para criar o arquivo de objeto correspondente. Os arquivos de objeto compilados são, então, vinculados para criar o binário do aplicativo finalizado, conforme mostrado no exemplo seguinte:


cc -c src1.c
cc -c src2.c
...
cc -o myserv src1.o src2.o ...

Para incluir as definições de teste do DTrace em seu aplicativo, adicione as regras Makefile apropriadas ao seu processo de construção para executar o comando dtrace, conforme mostrado no exemplo seguinte:


cc -c src1.c
cc -c src2.c
...
dtrace -G -32 -s myserv.d src1.o src2.o ...
cc -o myserv myserv.o src1.o src2.o ...

O comando dtrace mostrado acima pós-processa os arquivos de objeto gerados pelos comandos do compilador precedente e gera o arquivo de objeto myserv.o a partir de myserv.d e os outros arquivos de objeto. O opção -G do dtrace é usada para vincular o provedor e as definições de teste ao aplicativo do usuário. A opção - 32 é usada para construir binários de 32 bits. A opção - 64 é usada para construir binários de 64 bits.