Pointers and Address Spaces
A pointer is an address that provides a translation within some virtual address space
to a piece of physical memory. DTrace executes your D programs within
the address space of the operating system kernel itself. Your entire Solaris
system manages many address spaces: one for the operating system kernel, and
one for each user process. Since each address space provides the illusion
that it can access all of the memory on the system, the
same virtual address pointer value can be reused across address spaces but
translate to different physical memory. Therefore, when writing D programs that use
pointers, you must be aware of the address space corresponding to the
pointers you intend to use.
For example, if you use the syscall provider to instrument entry to
a system call that takes a pointer to an integer or array
of integers as an argument (for example, pipe(2)), it would not be
valid to dereference that pointer or array using the * or []
operators because the address in question is an address in the address
space of the user process that performed the system call. Applying the
* or [] operators to this address in D would result in
a kernel address space access, which would result in an invalid address
error or in returning unexpected data to your D program depending upon
whether the address happened to match a valid kernel address.
To access user process memory from a DTrace probe, you must apply
one of the copyin(), copyinstr(), or copyinto() functions described in Chapter 10, Actions and Subroutines to
the user address space pointer. Take care when writing your D programs
to name and comment variables storing user addresses appropriately to avoid confusion.
You can also store user addresses as uintptr_t so you don't accidentally
compile D code that dereferences them. Techniques for using DTrace on user
processes are described in Chapter 33, User Process Tracing.