Solaris Dynamic Tracing Guide

Pointers and Addresses

The Solaris Operating System uses a technique called virtual memory to provide each user process with its own virtual view of the memory resources on your system. A virtual view on memory resources is referred to as an address space, which associates a range of address values (either [0 ... 0xffffffff] for a 32-bit address space or [0 ... 0xffffffffffffffff] for a 64-bit address space) with a set of translations that the operating system and hardware use to convert each virtual address to a corresponding physical memory location. Pointers in D are data objects that store an integer virtual address value and associate it with a D type that describes the format of the data stored at the corresponding memory location.

You can declare a D variable to be of pointer type by first specifying the type of the referenced data and then appending an asterisk (*) to the type name to indicate you want to declare a pointer type. For example, the declaration:

int *p;

declares a D global variable named p that is a pointer to an integer. This declaration means that p itself is an integer of size 32 or 64-bits whose value is the address of another integer located somewhere in memory. Because the compiled form of your D code is executed at probe firing time inside the operating system kernel itself, D pointers are typically pointers associated with the kernel's address space. You can use the isainfo(1) -b command to determine the number of bits used for pointers by the active operating system kernel.

If you want to create a pointer to a data object inside of the kernel, you can compute its address using the & operator. For example, the operating system kernel source code declares an int kmem_flags tunable. You could trace the address of this int by tracing the result of applying the & operator to the name of that object in D:


The * operator can be used to refer to the object addressed by the pointer, and acts as the inverse of the & operator. For example, the following two D code fragments are equivalent in meaning:

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

The left-hand fragment creates a D global variable pointer p. Because the kmem_flags object is of type int, the type of the result of &`kmem_flags is int * (that is, pointer to int). The left-hand fragment traces the value of *p, which follows the pointer back to the data object kmem_flags. This fragment is therefore the same as the right-hand fragment, which simply traces the value of the data object directly using its name.