Guia de rastreamento dinâmico Solaris

Ponteiros e endereços

O sistema operacional Solaris usa uma técnica chamada memória virtual para fornecer a cada usuário os processos com sua própria visão virtual dos recursos de memória do sistema. Uma visão virtual dos recursos de memória é chamada de espaço de endereço, que associa um intervalo de valores de endereço ([0 ... 0xffffffff] para um espaço de endereço de 32 bits ou [0 ... 0xffffffffffffffff] para um espaço de endereço de 64 bits) a um conjunto de translações que o sistema operacional e o hardware usam para converter cada endereço virtual em um local de memória física correspondente. Os ponteiros em D são objetos de dados que armazenam um valor de endereço virtual de inteiro e associa-o a um tipo de D que descreve o formato dos dados armazenados no local correspondente da memória.

Você pode declarar uma variável de D como o tipo de ponteiro, especificando primeiro o tipo dos dados referenciados e, em seguida, acrescentando um asterisco ( *) ao nome do tipo para indicar que deseja declarar um tipo de ponteiro. Por exemplo, a declaração:

int *p;

declara uma variável de D global chamada p que é um ponteiro para um inteiro. Esta declaração significa que a própria p é um inteiro de 32 ou 64 bits, cujo valor é o endereço de outro inteiro localizado em algum lugar da memória. Como o formato compilado do seu código de D é executado na hora em que o teste é acionado dentro do próprio kernel do sistema operacional, os ponteiros de D são geralmente associados ao espaço de endereço do kernel. Você pode usar o comando isainfo(1) -b para determinar o número de bits usado para ponteiros pelo kernel ativo do sistema operacional.

Se você quiser criar um ponteiro para um objeto de dados dentro do kernel, calcule seu endereço usando o operador &. Por exemplo, o código-fonte do kernel do sistema operacional declara um int kmem_flags ajustável. Você poderia rastrear o endereço deste int rastreando o resultado da aplicação do operador & ao nome desse objeto em D:

trace(&`kmem_flags);

O operador * pode ser usado para fazer referência ao objeto endereçado pelo ponteiro, e age inversamente ao operador &. Por exemplo, os dois fragmentos de código de D seguintes têm significados equivalentes:

p = &`kmem_flags;				trace(`kmem_flags);
trace(*p);

O fragmento esquerdo cria um ponteiro de variável de D global p. Como o objeto kmem_flags é do tipo int, o tipo do resultado de &`kmem_flags é int * (ou seja, o ponteiro para int). O fragmento esquerdo rastreia o valor de *p, que segue o ponteiro de volta para o objeto de dados kmem_flags. Portanto, esse fragmento é o mesmo que o fragmento direito, que simplesmente rastreia o valor do objeto de dados diretamente através do seu nome.