JavaTM Debug Wire Protocol |
Java TM Debug Wire Protocol (JDWP) は、デバッガと JDWP がデバッグする Java Virtual Machine (VM) 間の通信に使用されるプロトコルです。 以降、JDWP がデバッグする VM をターゲット VM と呼びます。JDWP が存在することにより、同一のデバッガが次の状況で動作するようになります。
将来のバージョンの JDWP では、インプロセスデバッギングが可能になる予定です。
JDWP は、多くのプロトコル仕様とは、詳細フォーマットおよびレイアウト面で異なりますが、トランスポート面では異なりません。JDWP 実装は、単純な API を使用して、異なるトランスポート機構を受け付けるように設計することが可能です。特定のトランスポートが、上記の 3 つのデバッガ/ターゲット VM の各組み合わせを必ずしもサポートする必要はありません。
JDWP の設計は、各実装に対応するものとして十分単純化されていますが、将来の拡張に対応する柔軟性もあります。
JDWP は、JDI API を使って効率的に使用できることを主眼に設計されています。 その機能の多くはこの目的に沿って編成されます。
JDWP は、デバッガおよびターゲット VM を範囲として実装されます。一般に、デバッガ側は Java で記述され、ターゲット側はネイティブコードで記述されます。ターゲット側をネイティブコードで記述するのは、Java 言語実装で避けることのできないデッドロックおよび侵入を避けるためです。
現在のところ、JDWP はトランスポートランデブー用の機構またはディレクトリサービスを一切指定しません。これは将来変更される可能性がありますが、その点は別のドキュメントで扱われることになるでしょう。
JDWP はパケットベースであり、安定していません。 基本的なパケットタイプには、 コマンドパケットと応答パケットの 2 種類があります。
コマンドパケットは、デバッガまたはターゲット VM のいずれかにより送信されます。コマンドパケットは、ターゲット VM からの情報を要求するため、またはプログラムの実行を制御するためにデバッガにより使用されます。デバッガにターゲット VM 内のイベント (ブレークポイントや例外など) を通知するために、ターゲット VM がコマンドパケットを送信します。
応答パケットは、コマンドパケットへ応答する場合にのみ送信され、コマンドの成功または失敗に関する情報を常に提供します。応答パケットは、コマンド内で要求されたデータ (フィールドまたは変数の値など) を運ぶこともあります。現在のところ、ターゲット VM から送信されるイベントは、デバッガからの応答パケットを必要としません。
JDWP は非同期です。 このため、最初の応答パケットを受信する前に、複数のコマンドパケットが送信される場合があります。
コマンドおよび応答パケットヘッダは、同じサイズになります。 これは、トランスポートの実装および抽象化を容易にするためです。各パケットのレイアウトは、次のようになります。
JDWP 経由で送信されるすべてのフィールドおよびデータは、ビッグエンディアン形式である必要があります。ビッグエンディアンの定義については、Java Virtual Machine 仕様を参照してください。最初の 3 つのフィールドは、両方のパケットタイプで同一です。
単純で単調なカウンタは、大半の実装に適合するはずです。そのようなカウンタは、2^32 の一意な未処理パケットが存在可能で、もっとも単純な実装の代替手段となります。
0x80
応答ビットが設定されると、そのパケットが応答であることを示します。
コマンドセット空間は、次のように大きく分けられます。
0 - 63
64 - 127
128 - 256
一般に、コマンドまたは応答パケットのデータフィールドは、コマンドまたは応答データを定義する複数フィールドのグループを抽象化したものです。データフィールドの各サブフィールドは、ビッグエンディアン (Java) 形式で符号化されます。各コマンドとその応答用のデータフィールド作成方法の詳細は、このセクションで説明します。
異なる JDWP コマンドおよび応答の多くに共通な、一般データ型の小規模なセットが存在します。これらについては、以下で説明します。
名前 | サイズ | 解説 |
---|---|---|
byte
| 1 バイト | バイト値 |
boolean
| 1 バイト | ブール値。 false の場合は 0、true の場合はゼロ以外の値で符号化されます。 |
int
| 4 バイト | 4 バイトの整数値。整数は、符号なしと明示されている場合を除き、符号付きです。 |
long
| 8 バイト | 8 バイトの整数値。値は、符号なしと明示されている場合を除き、符号付きです。 |
objectID
| ターゲット VM 固有。 8 バイトまで (以下を参照) | ターゲット VM 内のオブジェクトを一意に識別します。特定のオブジェクトは、JDWP コマンドおよび応答内の 1 つの objectID により、その存続期間内は (または、objectID が明示的に廃棄されるまで) 厳密に識別されます。ObjectID は、それが明示的に廃棄されない限り、参照されたオブジェクトがガベージコレクトされたかどうかにかかわらず、異なるオブジェクトの識別に再利用されることはありません。objectID が 0 の場合、null オブジェクトを意味します。
object ID の存在により、オブジェクトのガベージコレクションが妨げられることはありません。ガベージコレクトされたオブジェクトへ、そのオブジェクト ID を使ってアクセスしようとすると、INVALID_OBJECT エラーコードが生成されます。ガベージコレクションは、DisableCollection コマンドを使って無効にできますが、通常その必要はありません。 |
tagged-objectID
| objectID のサイズ + 1 バイト | 最初のバイトは、オブジェクト型の識別用の符号バイトです。このバイトに設定可能な値については、JDWP.Tag を参照してください。 使用できるのは、プリミティブタグではなく、オブジェクトタグだけです。その直後に、objectID 本体が続きます。 |
threadID
| objectID と同じ | スレッドとして認識されるターゲット VM 内のオブジェクトを一意に識別します。 |
threadGroupID
| objectID と同じ | スレッドグループとして認識されるターゲット VM 内のオブジェクトを一意に識別します。 |
stringID
| objectID と同じ | 文字列オブジェクトとして認識されるターゲット VM 内のオブジェクトを一意に識別します。注:これは実際には文字列ではなく、値です。 |
classLoaderID
| objectID と同じ | クラスローダオブジェクトとして認識されるターゲット VM 内のオブジェクトを一意に識別します。 |
classObjectID
| objectID と同じ | クラスオブジェクトとして認識されるターゲット VM 内のオブジェクトを一意に識別します。 |
referenceTypeID
| objectID と同じ | ターゲット VM 内の参照型を一意に識別します。特定のクラスで、classObjectID と referenceTypeID が同一であると想定することはできません。特定の参照型は、JDWP コマンドおよび応答内の 1 つの ID により、その存続期間内は厳密に識別されます。referenceTypeID は、参照されたクラスが読み込み解除されたかどうかにかかわらず、異なる参照型を識別するために再利用されることはありません。
|
classID
| referenceTypeID と同じ | クラス型として認識されるターゲット VM 内の参照型を一意に識別します。 |
interfaceID
| referenceTypeID と同じ | インタフェース型として認識されるターゲット VM 内の参照型を一意に識別します。 |
arrayID
| referenceTypeID と同じ | 配列型として認識されるターゲット VM 内の参照型を一意に識別します。 |
methodID
| ターゲット VM 固有。 8 バイトまで (以下を参照) | ターゲット VM 内のあるクラスのメソッドを一意に識別します。methodID は、クラス/インタフェース内のメソッド、またはそのサブクラス/サブインタフェース/実装者のいずれかを一意に識別する必要があります。methodID は、必ずしも一意である必要はありません。 これは、常に referenceTypeID とペアで 1 つのメソッドを一意に識別します。referenceTypeID は、メソッドの宣言型またはサブタイプを識別できます。 |
fieldID
| ターゲット VM 固有。 8 バイトまで (以下を参照) | ターゲット VM 内のあるクラスのフィールドを一意に識別します。methodID は、クラス/インタフェース内のメソッド、またはそのサブクラス/サブインタフェース/実装者のいずれかを一意に識別する必要があります。fieldID は、必ずしも一意である必要はありません。 これは、常に referenceTypeID とペアで 1 つのフィールドを一意に識別します。referenceTypeID は、フィールドの宣言型またはサブタイプを識別できます。 |
frameID
| ターゲット VM 固有。 8 バイトまで (以下を参照) | ターゲット VM 内のフレームを一意に識別します。frameID は、VM 全体 (指定されたフレーム内だけではなく) のフレームを一意に識別する必要があります。frameID は、スレッドの中断中だけ有効である必要があります。 |
location
| ターゲット VM 固有 | 実行可能ファイルの位置。位置は、1 バイトのタイプタグ + classID + methodID + 符号なしの 8 バイトインデックス (メソッド内の位置を識別する) により識別されます。インデックス値には、次の制限があります。
タイプタグは、位置の classID がクラスまたはインタフェースを識別するかどうかを識別する必要があります。ほとんどすべての位置はクラス内に存在しますが、インタフェースの静的初期化子内に実行可能コードを保持することも可能です。 |
string
| 可変 | UTF-8 で符号化された文字列。 ゼロで終了することはなく、その前に 4 バイトの整数が付きます。 |
値
| 可変 | ターゲット VM から取得した値。最初のバイトは、型の識別用の符号バイトです。このバイトに指定可能な値については、JDWP.Tag を参照してください。その直後に、値が続きます。この値は、objectID (ID サイズの取得を参照) またはプリミティブ値 (1 〜 8 バイト) になります。各値型の詳細については、次の表を参照してください。 |
untagged-value
| 可変 | 上述のように、符号バイトなしの value 。この書式は、符号情報をコンテキストから判別可能な場合に使用します。
|
arrayregion
| 可変 | 配列操作で使用される値の簡潔な表現。最初のバイトは、型の識別用の符号バイトです。このバイトに指定可能な値については、JDWP.Tag を参照してください。 次は、シーケンス内の値の数を示す 4 バイトの整数です。 その直後に、値自体が続きます。 プリミティブ値は untagged-values のシーケンスとして符号化されます。オブジェクト値は values のシーケンスとして符号化されます。
|
オブジェクト ID、参照型 ID、フィールド ID、メソッド ID、およびフレーム ID は、ターゲット VM 実装が異なると、サイズも異なります。一般に、そのサイズは、JNI および JVMDI 呼び出し内の項目で使用されるネイティブ識別子のサイズに対応しています。各型の最大サイズは、8 バイトです。VirtualMachine コマンドセットの IDSizes コマンドは、これらの各型のサイズを決定するのにデバッガにより使用されます。
Copyright © 1999 Sun Microsystems, Inc. All Rights Reserved.
コメントの送付先:java-debugger@java.sun.com |