JPDA 内では、デバッガアプリケーションは Java Debug Interface (JDI) インタフェースとコネクタ抽象を使用してターゲット VM への接続を確立します。デバッガアプリケーションによって使用されるコネクタは、トランスポートをカプセル化します。ターゲット VM では、デバッガとの通信に JavaTM Debug Wire Protocol をサポートするエージェントが使用されます。このエージェント (ターゲット VM に組み込むか、実行時ライブラリからロード可能) は、デバッガと通信するためにトランスポートをカプセル化します。
Sun では、TCP/IP に基づくソケットトランスポートと共用メモリートランスポートの 2 つのトランスポート実装を、リファレンス実装とともに出荷しています。仕様では、特定のトランスポートの実装を必要としません。この実装とともに提供されるトランスポートのほかにも、アーキテクチャーに含まれるサービスプロバイダインタフェースを使用して、別のトランスポートを開発および配備できます。
コマンドと応答パケットは、JDWP トランスポートインタフェースを使用して、JDWP 仕様に従ってストリームに書き込まれます。JDWP を介して多数の小さなパケットを送信できるため、TCP_NO_DELAY ソケットオプションにより、小さなパケットが送信される前にソケット実装によってバッファーされる場合に発生する可能性のある遅延を回避することによって、一部のソケット実装でパフォーマンスを向上させることができます。可能な場合は未送信のデータが送信されるように、ソケットは適切に閉じられます。
ソケットトランスポートは、dt_socket という一意の文字列で識別されます。この名前は、ターゲット VM を呼び出すときに、ソケットトランスポートを選択するために使用できます。デバッガアプリケーションでは、対応するコネクタによってソケットトランスポートがカプセル化されます。
クライアントがサーバーに接続しているコンテキストでは、ソケットトランスポートアドレスの形式は、「<name>:<port>」になります。<name> はホスト名です。また、<port> は接続または待機しているソケットポート番号です。サーバーがクライアントの接続を待機しているコンテキストでは、アドレスはポート番号だけで構成されます (ホスト名は明示されません)。
共用メモリートランスポートは、dt_shmem という一意の文字列で識別されます。この名前は、ターゲット VM を呼び出すときに、ソケットトランスポートを選択するために使用できます。デバッガアプリケーションでは、対応するコネクタによって共用メモリートランスポートがカプセル化されます。
共用メモリーのトランスポートアドレスは、Microsoft Windows のファイルマッピングオブジェクトの名前として使用できます。この名前の文字列には、バックスラッシュを除く任意の文字を含めることができます。
実装されるコネクタをユーザーが選択および構成できるように、JDI クライアントアプリケーションを作成することもできますが、特定のコネクタに関する情報をデバッガに組み込んでおくと、ユーザーが使いやすい構成になります。JPDA で提供されている JDB の実装例では、この方法が採用されています。
JDI リファレンス実装では、使用可能なトランスポートの種類および接続モード (起動、待機、および接続) に対応するいくつかのコネクタが提供されています。それらのコネクタについて、このあとのセクションで説明します。これらのコネクタのリストは、JDI メソッド VirtualMachineManager.allConnectors() によって返されます。また、各接続コネクタ、待機コネクタ、および起動コネクタは、対応する VirtualMachineManager メソッド attachingConnectors()、listeningConnectors()、および launchingConnectors() によって返されるリストに含まれます。
このコネクタは、「com.sun.jdi.CommandLineLaunch」という名前で一意に識別されます。
name | 必須 | デフォルト値 | description |
---|---|---|---|
home | いいえ | 現在の java.home プロパティー値 | ターゲット VM の呼び出しに使用される Java 2 Runtime Environment の場所。 |
options | いいえ | "" | VM を呼び出すために使用する標準のデバッグオプションを含むオプション。 |
main | はい | "" | デバッグするアプリケーションのメインクラスおよびコマンド行の引数。 |
suspend | いいえ | true | メインクラスがロードされる直前にターゲット VM が中断される場合は true、そうでない場合は false。 |
quote | はい | "\"" | コマンド行上で、空白で区切られたテキストを結合するときに使用する文字。 |
vmexec | はい | java | VM 起動用ウィンドウの実行可能ファイル。デバッグ時には、javaw または java_g に変更できる (それらの起動用ウィンドウが使用可能な場合)。 |
このコネクタは、「com.sun.jdi.RawCommandLineLaunch」という名前で一意に識別されます。
name | 必須 | デフォルト値 | description |
---|---|---|---|
command | はい | "" | デバッグするアプリケーションからターゲット VM を呼び出すときに使用するコマンド行全体。 |
address | はい | "" | 新しく起動されたターゲット VM の接続を待機するトランスポートアドレス。この値は、通常は raw コマンドの引数として使用される。ただし、接続先のトランスポートアドレスを、ターゲット VM で独自に識別できる場合は必須ではない。 |
quote | はい | "\"" | コマンド行上で、空白で区切られたテキストを結合するときに使用する文字。 |
このコネクタは、「com.sun.jdi.SocketAttach」という名前で一意に識別されます。
name | 必須 | デフォルト値 | description |
---|---|---|---|
hostname | いいえ | ローカルホスト名 | 接続先のホストマシン名。 |
port | はい | "" | 接続先の host マシン上のポート番号。 |
timeout | いいえ | "" | ターゲット VM への接続時に使用するタイムアウト (ミリ秒単位)。 |
このコネクタは、「com.sun.jdi.SharedMemoryAttach」という名前で一意に識別されます。
name | 必須 | デフォルト値 | description |
---|---|---|---|
name | はい | "" | ターゲット VM が待機中の共用メモリーのトランスポートアドレス。 |
timeout | いいえ | "" | ターゲット VM に接続するときに使用するタイムアウト (ミリ秒単位) |
このコネクタでは、複数のターゲット VM からの接続を受け入れることができます。
このコネクタは、「com.sun.jdi.SocketListen」という名前で一意に識別されます。
name | 必須 | デフォルト値 | description |
---|---|---|---|
port | いいえ | 一時的なポート番号 (TCP/IP スタックによって割り当てられるポート) | 接続を待機するポート番号。 |
localAddress | いいえ | ホストに割り当てられるすべてのアドレス | ホストに割り当てられる IP アドレス |
timeout | いいえ | "" | ターゲット VM の接続を待機する間に使用するタイムアウト (ミリ秒単位) |
このコネクタでは、複数のターゲット VM からの接続を受け入れることができます。
このコネクタは、「com.sun.jdi.SharedMemoryListen」という名前で一意に識別されます。
name | 必須 | デフォルト値 | description |
---|---|---|---|
name | はい | "" | ターゲット VM の接続を待機する共用メモリーのトランスポートアドレス。 |
timeout | いいえ | "" | ターゲット VM の接続を待機する間に使用するタイムアウト (ミリ秒単位) |
name | 必須 | デフォルト値 | description |
---|---|---|---|
pid | はい | "" | デバッグされるプロセスのプロセス ID。 |
timeout | いいえ | "" | ターゲット VM への接続時に使用するタイムアウト (ミリ秒単位)。 |
name | 必須 | デフォルト値 | description |
---|---|---|---|
core |
いいえ | core | デバッグするコアファイルのパス名 |
javaExecutable |
はい |
"" |
コアファイルを生成した Java 実行可能ファイルのパス名。 |
name | 必須 | デフォルト値 | description |
---|---|---|---|
pid | はい | "" | デバッグされるプロセスのプロセス ID。 |
${JAVA_HOME}/bin/rmiregistry -J-Xbootclasspath/p:${JAVA_HOME}/lib/sa-jdi.jar
${JAVA_HOME}/bin/java \ -classpath ${JAVA_HOME}/lib/sa-jdi.jar \ sun.jvm.hotspot.jdi.SADebugServer \ <pid> \ [uniqueID]
または
${JAVA_HOME}/bin/java \ -classpath ${JAVA_HOME}/lib/sa-jdi.jar \ sun.jvm.hotspot.jdi.SADebugServer \ <pathname to the java executable that produced the core file>\ <pathname of the corefile to debug> \ [uniqueID]
上記の 2 つの手順の代わりに、jsadebugd コマンドを使用して、リモートマシンで RMI レジストリとデバッグサーバーを起動する方法もあります。
「uniqueID」はオプションの文字列です。同じマシンで複数のデバッグサーバーを同時に実行する場合は、各サーバーに異なる「uniqueID」文字列を指定する必要があります。
上の例の JAVA_HOME には、デバッグ対象で使用されるバージョンと同じビットサイズ (つまり 32 ビットまたは 64 ビット) および同じバージョン (5.0、5.1 など) の Java インストールのパス名が含まれていなければなりません。ただし、デバッガのビットサイズとバージョンは同じである必要はありません。
デバッグされるプロセスが、デバッグモードで (つまり、-agentlib:jdwp または -Xrunjdwp を使用して) 開始されている必要はありません。 プロセスがハングアップしても問題ありません。プロセスは、デバッグサーバーの接続時に中断されます。プロセスに接続されているデバッグサーバーを (^C またはほかの方法で) 終了すると、デバッグ対象プロセスは再開されます。コアファイルに複数のデバッグサーバーを接続することはできますが、プロセスに接続できるデバッグサーバーは 1 つだけです。
このコネクタでは、同じデバッグサーバーに複数のデバッグセッションを接続できます。
このコネクタは、「sun.jvm.hotspot.jdi.SADebugServerAttachingConnector」という名前で一意に識別されます。
name | 必須 | デフォルト値 | description |
---|---|---|---|
debugServerName | はい | "" | デバッグサーバーが実行されているマシンの IP アドレスまたは名前。このマシンに複数のデバッグサーバーが含まれている場合、この名前は、 uniqueID@IPAddress または uniqueID@hostname という形式である必要があります。ここで、「uniqueID」は対応するデバッグサーバーを起動するために使用される文字列です。 |
Sun の VM 実装には、デバッグ用の JDWP エージェントをロードするコマンド行オプションが必要です。5.0 以降では、JDWP エージェントをロードしたり、そのオプションを指定したりするために -agentlib:jdwp オプションが使用されます。5.0 より前のリリースでは、-Xdebug および -Xrunjdwp オプションが使用されます (5.0 の実装では、-Xdebug および -Xrunjdwp オプションもサポートされますが、5.0 の JDWP エージェントは、VM に対して以前の JVMDI インタフェースではなく JVM TI インタフェースを使用するため、新しい -agentlib:jdwp オプションの使用をお勧めします)。
デバッガアプリケーションで JDI の Sun コマンド行起動コネクタを使用する場合、5.0 より前のターゲット VM への接続にこのコネクタが使用される可能性があるため、-Xdebug および -Xrunjdwp オプションがコネクタで使用されます。
ターゲット VM が 5.0 以降の場合、-agentlib:jdwp オプションは次のように指定します。
5.0 より前のリリースの場合、-Xdebug および -Xrunjdwp オプションが使用されます。
-agentlib:jdwp=<name1>[=<value1>],<name2>[=<value2>]...
または
-Xrunjdwp:<name1>[=<value1>],<name2>[=<value2>]...
name | 必須 | デフォルト値 | description |
---|---|---|---|
help | いいえ | なし | 簡単なヘルプメッセージを出力して VM を終了する。 |
transport | はい | なし | デバッガアプリケーションに接続するときに使用するトランスポートの名前。 |
サーバー | いいえ | "n" | 「y」の場合は、デバッガアプリケーションへの接続を待機する。そうでない場合は、指定されたアドレスのデバッガアプリケーションに接続する。
「y」が指定されているときにアドレスが指定されていない場合は、デバッガアプリケーションを待機するトランスポートアドレスを選択し、標準出力ストリームにそのアドレスを出力する。 |
address | server=n の場合は、はい。それ以外の場合は、いいえ |
"" | 接続用のトランスポートアドレス。server=n の場合は、このアドレスのデバッガアプリケーションに対して接続する。server=y の場合は、このアドレスで接続を待機する。 |
timeout | いいえ | "" | server=y の場合は、デバッガからの接続を待機するときに使用するタイムアウト (ミリ秒単位) を指定する。server=n の場合は、デバッガへの接続時に使用するタイムアウト (ミリ秒単位) を指定する。一部のトランスポート実装では、タイムアウトオプションが無視される場合がある。 |
launch | いいえ | なし | JDWP の初期化が完了したときに、この文字列に指定されたプロセスを起動する。このオプションは、「Just-In-Time デバッグ」を行うときに、onthrow または onuncaught、あるいはその両方のオプションと組み合わせて使用する。「Just-In-Time デバッグ」では、この VM で特定のイベントが発生したときにデバッガプロセスが起動する。
起動されるプロセスは、自身のウィンドウでは起動されない。ほとんどの場合、起動されるプロセスは小さなアプリケーションで、起動後にデバッガアプリケーションが自身のウィンドウで起動される。 この引数に指定した文字列には、空白で区切られた次の文字列が追加される。これらの文字列は、起動されたデバッガがこの VM との接続を確立するために使われる。こうして生成された文字列が実行される。
|
onthrow | いいえ | なし | 特定のクラスの例外がこの VM にスローされるまで、JDWP ライブラリの初期化を遅延する。例外クラス名は、パッケージで修飾されていなければならない。JDWP が初期化されたときに接続が確立されるため、この例外がスローされるまで接続は確立されない。 |
onuncaught | いいえ | "n" | 「y」の場合は、uncaught 例外がこの VM にスローされるまで、JDWP ライブラリの初期化を遅延する。JDWP が初期化されたときに接続が確立されるため、この例外がスローされるまで接続は確立されない。uncaught 例外の定義については、JDI 仕様の com.sun.jdi.ExceptionEvent を参照。 |
suspend | いいえ | "y" | 「y」の場合、VMStartEvent は中断ポリシーが SUSPEND_ALL になる。「n」の場合、VMStartEvent の中断ポリシーは SUSPEND_NONE になる。 |
JDI の起動コネクタは、Plug-in アプレットのデバッグには使用できません。
JDB では、-attach オプションを指定すると、リファレンス実装の接続コネクタ (Microsoft Windows 上では共用メモリー、Solaris および Linux プラットフォーム上ではソケット) にアクセスできます。-listen オプションを指定すると、リファレンス実装の待機コネクタ (Microsoft Windows 上では共用メモリー、Solaris および Linux プラットフォーム上ではソケット) にアクセスできます。コマンド行にクラス名と引数を直接指定すると、Sun コマンド行起動コネクタにアクセスできます。
たとえば、
jdb -attach myhost:8000
上のように入力すると、ソケット接続コネクタを使用して簡単にターゲット VM に接続できます (Solaris オペレーティング環境の場合)。
jdb Hello 1 2 3
上のように入力すると、Sun コマンド行起動コネクタを使用して簡単にターゲット VM を起動できます。
ただし、JDB には -connect オプションも用意されています。これにより、コネクタ名と、名前と値の引数ペアの任意のセットを指定することによって任意のコネクタを処理できます。たとえば、上記の 2 つのコマンド行は、次のコマンド行と同じことです。
jdb -connect com.sun.jdi.SocketAttach:hostname=myhost,port=8000
jdb -connect "com.sun.jdi.CommandLineLaunch:main=Hello 1 2 3"
これらのコマンド行は、最初の例よりも複雑ですが、-connect オプションを指定すれば任意のコネクタを使用できます。これらの操作から、JDI デバッガでは、任意のコネクタを使用できることがわかります。また、よく使われるコネクタを使用するための簡単なインタフェースも提供されています。
JPDA に含まれているサービスプロバイダインタフェースを使うと、コネクタやトランスポートの実装を開発および配置できます。これらのサービスプロバイダインタフェースにより、デバッガやほかのツールベンダーで新しいコネクタ実装を開発し、Sun が提供するソケットおよび共用メモリートランスポートを超える別のトランスポートメカニズムを提供できます。JDI のサービスプロバイダインタフェースは、com.sun.jdi.connect.spi パッケージで指定されます。
JDI のサービスプロバイダインタフェースに加え、Sun の実装には、Java TMDebug Wire Protocol Transport Interface と呼ばれるトランスポートライブラリインタフェースも含まれています。トランスポートライブラリは、ターゲット VM の JDWP エージェントによってロードされ、デバッガとの接続の確立、およびデバッガと VM 間の JDWP パケットのトランスポートに使用されます。
サービスプロバイダインタフェースに関する詳細は、「JavaTM Platform Debugger Architecture - サービスプロバイダインタフェース」のドキュメントを参照してください。