Manuel de suivi dynamique Solaris

Pointeurs et adresses

Le système d'exploitation Solaris utilise une technique appelée mémoire virtuelle pour fournir à chaque processus utilisateur un affichage virtuel propre des ressources mémoire du système. Un affichage virtuel des ressources mémoire est appelé espace d'adresse, qui associe une plage de valeurs d'adresses ([0 ... 0xffffffff] pour un espace d'adresse 32 bits ou [0 ... 0xffffffffffffffff] pour un espace d'adresse 64 bits) avec un ensemble de translations utilisé par le système d'exploitation et le matériel pour convertir chaque adresse virtuelle en un emplacement de mémoire physique correspondant. Les pointeurs dans D sont des objets de données qui stockent une valeur d'adresse virtuelle entière et l'associe à un type D qui décrit le format des données stockées à l'emplacement de mémoire correspondant.

Vous pouvez déclarer une variable D de sorte qu'elle soit un type de pointeur en spécifiant tout d'abord le type des données référencées, puis en ajoutant un astérisque ( *) au nom du type pour indiquer que vous souhaitez déclarer un pointeur. Par exemple, la déclaration :

int *p;

déclare une variable globale D nommée p qui est un pointeur sur un entier. Cette déclaration signifie que p est un entier de 32 ou 64 bits dont la valeur est l'adresse d'un autre entier en mémoire. La forme compilée de votre code D étant exécutée au déclenchement de sonde dans le noyau du système d'exploitation, les pointeurs D sont généralement associés à l'espace d'adresse du noyau. Vous pouvez utiliser la commande isainfo(1) -b pour déterminer le nombre de bits utilisés pour les pointeurs par le noyau du système d'exploitation actif.

Pour créer un pointeur sur un objet de données dans le noyau, vous pouvez calculer son adresse à l'aide de l'opérateur &. Par exemple, le code source de noyau du système d'exploitation déclare un paramètre réglable int kmem_flags. Vous pourriez suivre l'adresse de int en suivant le résultat de l'application de l'opérateur & au nom de cet objet dans D :

trace(&`kmem_flags);

L'opérateur * peut être utilisé pour faire référence à l'objet pointé et agit de manière inverse à l'opérateur &. Par exemple, les deux fragments de code D ont une signification équivalente :

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

Le fragment de gauche crée un pointeur p de variable globale D. L'objet kmem_flags étant du type int, le type du résultat de &`kmem_flags est int * (à savoir le pointeur sur int). Le fragment de gauche suit la valeur de *p, qui suit le pointeur sur l'objet de données kmem_flags. Ce fragment est donc identique à celui de droite, qui suit simplement la valeur de l'objet de données via son nom.