Guia de rastreamento dinâmico Solaris

Políticas do buffer principal

O DTrace permite o rastreio em contextos altamente restritos no kernel. Em particular, o DTrace permite o rastreio em contextos nos quais a alocação de memória pelo software do kernel possa não ser confiável. A conseqüência dessa flexibilidade de contexto é que sempre existe a possibilidade de que o DTrace irá tentar rastrear os dados quando não houver espaço disponível. O DTrace deve ter uma política para lidar com tais situações quando elas ocorrerem, mas você pode querer ajustar a política com base nas necessidades de um determinado experimento. Algumas vezes a política apropriada pode ser de descartar os novos dados. Outras vezes, talvez seja desejável reutilizar o espaço que contém os dados registrados mais antigos para rastrear novos dados. Mais freqüentemente, a política desejada é de minimizar a probabilidade de ficar sem espaço disponível em primeiro lugar. Para acomodar todas essas demandas, o DTrace oferece suporte a várias políticas de buffer diferentes. Esse suporte é implementado com a opção bufpolicy, e pode ser definido em uma base por consumidor. Consulte o Capítulo 16Opções e ajustáveis para obter detalhes sobre as opções de configuração.

Política switch

Por padrão, o buffer principal possui uma política switch. Nessa política, os buffers por CPU são alocados em pares: um buffer é ativo e ou outro, inativo. Quando um consumidor do DTrace tenta ler um buffer, o kernel primeiro alterna os buffers inativos e ativos. A alternância de buffer é feita de tal maneira que não haja uma janela na qual os dados do rastreio possam se perder. Depois que os buffers forem alternados, o buffer recém-inativo é copiado para o consumidor do DTrace. Essa política garante que o consumidor sempre veja um buffer auto-consistente: um buffer nunca é simultaneamente rastreado e copiado. Essa técnica também impede que seja introduzida uma janela na qual o rastreio seja pausado ou, de alguma forma, impedido. A taxa na qual o buffer é alternado e lido é controlada pelo consumidor com a opção switchrate. Assim como com qualquer opção de taxa, switchrate pode ser especificada com qualquer sufixo de tempo, mas o padrão é taxa por segundo. Para obter mais detalhes sobre switchrate e outras opções, consulte o Capítulo 16Opções e ajustáveis.


Observação –

Para processar o buffer principal no nível do usuário mais rápido que o padrão que é de uma vez por segundo, ajuste o valor de switchrate. O sistema processa as ações que produzem atividade no nível do usuário (como printa () e system()) quando o registro correspondente no buffer principal é processado. O valor de switchrate determina a velocidade na qual o sistema processa tais ações.


Na política switch, se um determinado teste ativado rastrear mais dados do que o espaço disponível no buffer principal ativo, os dados serão cancelados e uma contagem de cancelamento por CPU é incrementada. No caso de um ou mais cancelamentos, o dtrace(1M) exibe uma mensagem similar ao seguinte exemplo:


dtrace: 11 drops on CPU 0

Se um determinado registro for maior que o tamanho total do buffer, o registro será cancelado independentemente da política do buffer. Você pode reduzir ou eliminar cancelamentos, seja aumentando o tamanho do buffer principal com a opção bufsize ou aumentando a taxa de alternância com a opção switchrate .

Na política switch, o espaço temporário para copyin(), copyinstr() e alloca() é alocado fora do buffer ativo.

Política fill

Para alguns problemas, você pode querer usar um único buffer em kernel. Embora essa abordagem possa ser implementada com a política switch e construções apropriadas de D incrementando-se uma variável em D e criando-se um predicado para uma ação exit() apropriadamente, tal implementação não elimina a possibilidade de cancelamentos. Para solicitar um único buffer grande em kernel e prosseguir com o rastreio até que um ou mais dos buffers por CPU tenha sido preenchido, use a política de buffer fill. Nessa política, o rastreio continua até que um teste ativado tente rastrear mais dados que possam caber no espaço restante do buffer principal. Quando não houver espaço suficiente restante, o buffer é marcado como preenchido e o consumidor é notificado que pelo menos um dos buffers por CPU foi preenchido. Quando o dtrace(1M) detecta um único buffer preenchido, o rastreio é interrompido, todos os buffers são processados e dtrace é encerrado. Dados adicionais não serão rastreados para um buffer preenchido mesmo que esses dados caibam nele.

Para usar a política fill, defina a opção bufpolicy como fill. Por exemplo, o seguinte comando rastreia cada entrada de chamada do sistema em um buffer por CPU de 2K com a política de buffer definida como fill:


# dtrace -n syscall:::entry -b 2k -x bufpolicy=fill

Política fill e testes END

Os testes END normalmente não são acionados até que o rastreio tenha sido explicitamente interrompido pelo consumidor do DTrace. É garantido que os testes END sejam acionados apenas em uma CPU, mas a CPU na qual o teste é acionado não é definida. Com buffers fill, o rastreio é explicitamente interrompido quando pelo menos um dos buffers principais por CPU tiver sido marcado como preenchido. Se a política fill estiver selecionada, o teste END pode ser acionado em uma CPU que possua um buffer preenchido. Para acomodar o rastreio END em buffers fill, o DTrace calcula a quantidade de espaço potencialmente consumido pelos testes END e subtrai esse espaço do tamanho do buffer principal. Se o tamanho líquido for negativo, o DTrace se recusará a iniciar e o dtrace(1M) retornará uma mensagem de erro correspondente:


dtrace: END enablings exceed size of principal buffer

O mecanismo de reserva garante que um buffer completo sempre possui espaço suficiente para quaisquer testes END.

Política ring

A política de buffer ring do DTrace auxilia no rastreio de eventos que levam a falha. Se a reprodução da falha demorar horas ou dias, talvez você queira manter somente os dados mais recentes. Depois que um buffer principal for preenchido, o rastreio retorna para a primeira entrada, sobrescrevendo dados de rastreio antigos. Estabeleça o buffer de anel, configurando a opção bufpolicy para a seqüência ring:


# dtrace -s foo.d -x bufpolicy=ring

Quando usado para criar um buffer de anel, o dtrace(1M) não exibirá qualquer resultado até que o processo esteja terminado. Nesse momento, o buffer de anel estará consumido e processado. O dtrace processa cada buffer de anel em ordem de CPU. Em um buffer de CPU, os registros do rastreio serão exibidos na ordem do mais antigo para o mais novo. Assim como na política de buffer switch, não existe ordem entre os registros de CPUs diferentes. Se for necessária uma ordem, você deve rastrear a variável timestamp como parte da solicitação de rastreio.

O exemplo a seguir demonstra o uso de uma diretiva #pragma option para ativar o buffer em anel:

#pragma D option bufpolicy=ring
#pragma D option bufsize=16k

syscall:::entry
/execname == $1/
{
	trace(timestamp);
}

syscall::rexit:entry
{
	exit(0);
}