Guia de rastreamento dinâmico Solaris

Segurança de ponteiro

Se você for um programador em C ou C++, talvez esteja um pouco assustado depois de ler a seção anterior porque sabe que o uso incorreto de ponteiros ponde fazer com que os seus programas travem. O DTrace é um ambiente seguro e robusto para executar seus programas em D, onde esses erros não podem fazer com que o seu programa trave. Você pode até escrever um programa em D com erros, mas acessos inválidos ao ponteiro de D não farão com que o DTrace ou o kernel do sistema operacional falhe ou trave. Em vez disso, o software do DTrace detectará quaisquer acessos inválidos ao ponteiro, desativará sua instrumentação e informará o problema para que você faça a depuração.

Se você programou na linguagem de programação Java, provavelmente sabe que a linguagem Java não aceita ponteiros exatamente pelos mesmos motivos de segurança. Os ponteiros são necessários em D porque eles são uma parte intrínseca da implementação do sistema operacional em C, mas o DTrace implementa os mesmos tipos de mecanismo de segurança encontrados na linguagem de programação Java que evitam que programas com erro causem danos neles mesmos ou em outros programas. O relatório de erros do DTrace é semelhante ao ambiente de tempo de execução da linguagem de programação Java, que detecta um erro de programação e informa uma exceção para você.

Para ver o relatório e a manipulação de erros do DTrace, escreva deliberadamente um programa D ruim usando ponteiros. Em um editor, digite o seguinte programa em D e salve-o em um arquivo chamado badptr.d:


Exemplo 5–1 badptr.d: demonstração de manipulação de erros do DTrace

BEGIN
{
	x = (int *)NULL;
	y = *x;
	trace(y);
}

O programa badptr.d cria um ponteiro de D chamado x que é um ponteiro para int. O programa atribui a esse ponteiro o valor de ponteiro inválido especial NULL, que é um alias interno para o endereço 0. Por convenção, o endereço 0 é sempre definido como inválido, para que NULL possa ser usado como um valor de sentinela em programas em C e em D. O programa usa uma expressão de conversão para converter NULL a fim de que seja usado como um ponteiro para um inteiro. O programa cancela a referência ao ponteiro usando a expressão *x, atribui o resultado a outra variável y e tenta rastrear y. Quando o programa em D é executado, o DTrace detecta um acesso inválido ao ponteiro quando a declaração y = *x é executada e informa o erro:


# dtrace -s badptr.d
dtrace: script '/dev/stdin' matched 1 probe
CPU     ID                    FUNCTION:NAME
dtrace: error on enabled probe ID 1 (ID 1: dtrace:::BEGIN): invalid address
(0x0) in action #2 at DIF offset 4
dtrace: 1 error on CPU 0
^C
#

O outro problema que pode surgir dos programas que usam ponteiros inválidos é um erro de alinhamento. Por convenção arquitetural, os objetos de dados fundamentais, tais como inteiros, são alinhados na memória de acordo com o su tamanho. Por exemplo, inteiros de 2 bytes são alinhados em endereços que são múltiplos de 2, inteiros de 4 bytes em múltiplos de 4, e assim por diante. Se você cancelar a referência de um ponteiro a um inteiro de 4 bytes e o endereço do ponteiro for um valor inválido que não seja múltiplo de 4, o acesso falhará devido a um erro de alinhamento. Os erros de alinhamento em D quase sempre indicam que o ponteiro possui um valor inválido ou corrompido devido a um erro em seu programa em D. Você pode criar um erro de alinhamento de exemplo, alterando o código-fonte de badptr.d para usar o endereço (int *)2 em vez de NULL. Como int é de 4 bytes e 2 não é um múltiplo de 4, a expressão *x resulta em um erro de alinhamento do DTrace.

Para obter detalhes sobre o mecanismo de erro do DTrace, consulte Teste ERROR.