このドキュメントで説明するソフトウェアは、Extended SupportまたはSustaining Supportのいずれかにあります。 詳細は、https://www.oracle.com/us/support/library/enterprise-linux-support-policies-069172.pdfを参照してください。
Oracleでは、このドキュメントに記載されているソフトウェアをできるだけ早くアップグレードすることをお薦めします。
DTraceは、オペレーティング・システム・カーネルのアドレス空間内でDプログラムを実行します。 Oracle Linuxシステム全体では、オペレーティング・システム・カーネルのために1つと、ユーザー・プロセスごとに1つのアドレス空間を管理します。 各アドレス空間では、システム上のすべてのメモリーにアクセスできるとみなされるため、同じ仮想アドレスを異なるアドレス空間で使用できますが、それは物理メモリー内の異なる場所に変換されません。 Dプログラムでポインタを使用する場合、それぞれのポインタに対応しているアドレス空間を把握しておく必要があります。
たとえば、syscall
プロバイダを使用して、整数または整数の配列へのポインタを引数として使用するpipe()
などのシステム・コールに対するエントリを配置する場合、*または[]演算子を使用してそのポインタまたは配列を間接参照することは、有効ではありません。 アドレスは、カーネルのアドレス空間ではなく、システム・コールを実行したユーザー・プロセスのアドレス空間に存在します。 Dでアドレスを間接参照すると、カーネルのアドレス空間へのアクセスが発生し、無効なアドレス・エラーが出力されるか、Dプログラムに対して予期しないデータが返されます。
DTraceプローブからユーザー・プロセス・メモリーにアクセスするには、copyin()
、copyinstr()
またはcopyinto()
関数のいずれかをユーザー空間のアドレスと組み合せて使用します。
次のDプログラムは、プロセスによってwrite()
システム・コールに渡されたファイル記述子、文字列および文字列長の引数を出力する2つの相互に等価な方法を示しています。
syscall::write:entry { printf("fd=%d buf=%s count=%d", arg0, stringof(copyin(arg1, arg2)), arg2); } syscall::write:entry { printf("fd=%d buf=%s count=%d", arg0, copyinstr(arg1, arg2), arg2); }
arg0
、arg1
およびarg2
変数には、システム・コールに対するfd
、buf
およびcount
引数の値が含まれます。 arg1
の値は、カーネルのアドレス空間ではなく、プロセスのアドレス空間に存在するアドレスであることに注意してください。
この例では、DTraceが取得したユーザー・データを文字列に変換できるように、stringof()
関数とcopyin()
を組み合せて使用する必要があります。 copyinstr()
関数は、常に文字列を返します。
混乱を避けるため、ユーザー・アドレスを格納する変数には適切に名前を付け、コメントしておく必要があります。 また、uintptr_t
型の変数としてユーザー・アドレスを格納し、それらを間接参照するDコードを誤ってコンパイルしないようにしてください。