JavaTM Virtual Machine Debug Interface リファレンス |
はじめに
JVMDI の関数の使用法
エラー
イベント
VM および JVMDI クライアントの起動
注: J2SE 5.0 では、JVMDI は推奨されていません。その代わりに、JVMTI を使用する必要があります。
JavaTM Virtual Machine Debug Interface (JVMDI) は、デバッガやその他のプログラミングツールにより使用されるプログラミングインタフェースです。このインタフェースは、JavaTM 仮想マシンで動作するアプリケーションの状態検査と実行制御の両方の機能を提供します。
JVMDI は、双方向のインタフェースです。JVMDI クライアントは、知りたい状態の発生状況について、イベントを介して通知を受け取ることができます。JVMDI は、イベントに応答して、またはイベントからは独立して、さまざまな関数を使ってアプリケーションへの照会および制御を実行できます。
JVMDI クライアントは、デバッグされているアプリケーションと同じ仮想マシン上で動作し、ネイティブインタフェースを使って JVMDI にアクセスします。ネイティブのインプロセスインタフェースにより、デバッグツール側への侵入は最小限に抑えながら、最大限の制御が可能になります。通常、JVMDI クライアントは比較的コンパクトです。JVMDI クライアントは、ターゲットアプリケーションの通常の実行を妨げることなく、デバッガの機能の大部分を実装する別のプロセスによって制御できます。
JVMDI は、Java Platform Debugger Architecture の一番下の層です。この役割は JVMTI によって処理されるようになりました。このアーキテクチャには、より高いレベルの、アウトプロセスのデバッガインタフェースが含まれています。多くのデバッガツールには、JVMDI よりも高いレベルのインタフェースの方が適しています。Java Platform Debugger Architecture の詳細については、このリリースの Java Platform Debugger Architecture のドキュメントおよび Java Platform Debugger Architecture の Web サイトを参照してください。
関数および定数を定義する場合は、
#include <jvmdi.h>をソースコードに追加してください。
Java Native Interface (JNI) の関数と同様に、JVMDI の関数には、関数テーブルを使ってアクセスします。JVMDI の関数テーブルは、JNI の GetEnv
関数を使って取得できます。たとえば、次のコードは、バージョン 1 の JVMDI 用の関数テーブルを取得します。
JVMDI_Interface_1 *jvmdi; ... (*jvm)->GetEnv(jvm, &jvmdi, JVMDI_VERSION_1);
JVMDI の関数は、復帰状態を表す jvmdiError
値を常に返します。関数によっては、呼び出し側の関数で指定されたポインタにより、これ以外の値を返すことも可能です。JVMDI の関数の中にはメモリを割り当てるものがありますが、この場合はプログラム内でそのメモリを明示的に解放しなければなりません。これについては、個々の関数の説明に明記されています。空のリスト、配列、シーケンスなどは、割り当てられた長さがゼロの配列 (null ではない) として返されます。
JVMDI の関数は、JNI 参照を使ってオブジェクトを識別します。JVMDI の関数に渡される参照は、グローバルでもローカルでもかまいませんが、強い参照でなければなりません。JVMDI の関数によって返される参照はすべて、強いグローバル参照です。
JVMDI 関数がエラーに遭遇した場合は (戻り値が JVMDI_ERROR_NONE 以外)、引数ポインタにより参照されるメモリ値は未定義です。しかし、メモリおよびグローバル参照は何も割り当てられません。
JVMDI では、JNI で定義されているデータ型を、次のように拡張しています。jthread
および jthreadGroup
は jobject
のサブタイプであり、対応するオブジェクトを表します。jframeID
は、中断されたスレッドまたは現在のスレッドの単一のスタックフレームを表すポインタ型です (スレッドが再開されると無効になる)。jlocation
は、64 ビットの符号なしの値で、メソッド内で単調に増加する実行可能位置を表します。jvmdiError
は jint
であり、その用途はすでに説明したとおりです。
JVMDI の関数は、次のようなカテゴリに分類されます。
JVMDI の多くの関数では、メモリの割り当てを必要とします。デフォルトでは、メモリは malloc()
などのプラットフォーム固有のメモリ割り当て関数で割り当てられます。JVMDI に基づいて構築するシステムでは、独自のメモリ割り当て機構を提供できます。独自のメモリ割り当て機構を使用すれば、たとえば、メモリが少なくなってもデバッガが処理を続行できるように事前にメモリを割り当てておくといったことが可能になります。また、デフォルトのメモリ割り当て関数を、デバッガ固有の関数に置き換えることで、内部でメモリ管理関数を実行中にアプリケーションのスレッドが中断している間、デバッガのスレッドが malloc
に入ることができないシステム上で、デッドロック発生の可能性を減らすことができます。
jvmdiError SetAllocationHooks(JVMDI_AllocHook ahook, JVMDI_DeallocHook dhook)
メモリ割り当て関数とメモリ解放関数を設定します。フック関数は以下のように定義されます。
typedef jvmdiError (*JVMDI_AllocHook)(jlong size, jbyte** memPtr) typedef jvmdiError (*JVMDI_DeallocHook)(jbyte* buffer)
JVMDI は、メモリを割り当てるときは ahook
を呼び出し、メモリを解放するときは dhook
を呼び出します。この指定を行うと、JVMDI のデフォルトのメモリアロケータは無効になります。デフォルトのアロケータに戻すには、ahook
および dhook
を null
に設定して SetAllocationHooks
を呼び出します。
ahook
関数では、割り当てるバイト数を size
で受け取り、そのメモリを memPtr
で返すようにします。戻り値としては、null ポインタが引き渡された場合は JVMDI_ERROR_NULL_POINTER を、メモリ割り当て要求を受け付けることができない場合は JVMDI_ERROR_OUT_OF_MEMORY を、それ以外の場合は JVMDI_ERROR_NONE を返すようにします。
dhook
関数では、解放するメモリを buffer
で受け取るようにします。戻り値としては、null ポインタが引き渡された場合は JVMDI_ERROR_NULL_POINTER を、それ以外の場合は JVMDI_ERROR_NONE を返すようにします。
パラメータ:
- ahook
- メモリの割り当てに使用する関数、または null (デフォルトのアロケータに戻す場合)
- dhook
- メモリの解放に使用する関数、または null (デフォルトのアロケータに戻す場合)
SetAllocationHooks
は、常に JVMDI_ERROR_NONE
を返します。
jvmdiError Allocate(jlong size, jbyte** memPtr)
JVMDI のアロケータを使用して、メモリの領域を割り当てます。割り当てられたメモリは、Deallocate
によって解放してください。
パラメータ:
- size
- 割り当てるバイト数
- memPtr
- 戻ったとき、
SetAllocationHooks
で指定されたアロケータによって割り当てられたメモリの先頭を指すポインタ
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
JVMDI のアロケータを使用して、jvmdiError Deallocate(jbyte* mem)
mem
を解放します。この関数は、JVMDI の関数によって割り当てられて返されたメモリ、または Allocate
を使用して割り当てられたメモリを解放するために使用します。
パラメータ:
- mem
- 割り当てられたメモリの先頭を指すポインタ
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
jvmdiError GetThreadStatus(jthread thread, jint *threadStatusPtr, jint *suspendStatusPtr)
スレッドのステータス情報を取得します。
パラメータ:
この関数は、汎用エラー、または次のエラーのどれかを返します。
- thread
- 照会するスレッド
- threadStatusPtr
- 戻ったとき、スレッドの現在のステータスをポイントする。スレッドを中断した場合、中断前のスレッドのステータスが返されます。スレッドのステータスは次の値のうちのどれかで表されます。
JVMDI_THREAD_STATUS_UNKNOWN
- スレッドのステータスは不明
JVMDI_THREAD_STATUS_ZOMBIE
- スレッドは実行を完了
JVMDI_THREAD_STATUS_RUNNING
- スレッドは実行可能
JVMDI_THREAD_STATUS_SLEEPING
- スレッドはスリープ中(
Thread.sleep()
が呼び出された)JVMDI_THREAD_STATUS_MONITOR
- スレッドは同期ブロックに入るために待機中
JVMDI_THREAD_STATUS_WAIT
- スレッドは待機中(
Object.wait()
が呼び出された)- suspendStatusPtr
- 戻ったとき、中断についての情報をポイントする。中断ステータスは、ビットフラグを含まないか、または 1 つ以上のビットフラグを組み合わせたもの
JVMDI_SUSPEND_STATUS_SUSPENDED
- スレッドは中断されている(
java.lang.Thread.suspend()
、SuspendThread
、またはSuspendThreadList
が呼び出された)。JVMDI_SUSPEND_STATUS_BREAK
- スレッドはブレークポイントに達して中断された。このビットは、スレッドが現在のスレッドであるか、またはスレッドが中断されている場合にだけ有効である
JVMDI_ERROR_INVALID_THREAD
thread
が無効JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
jvmdiError GetAllThreads(jint *threadsCountPtr, jthread **threadsPtr)
仮想マシンに認識されている実行中のすべてのスレッドを取得します。VM に接続されていないネイティブスレッドは、返されるリストに含まれません。
パラメータ:
この関数は、汎用エラー、または次のエラーのどれかを返します。
- threadsCountPtr
- 戻ったとき、スローされる例外の数をポイントする
- threadsPtr
- 戻ったとき、参照 (実行中のスレッドごとに 1 つずつ) の配列をポイントする。配列内のスレッドは、JNI のグローバル参照で、JNI 関数
DeleteGlobalRef
を使って明示的に解放する必要がある。返されたスレッドの配列は、Deallocate
を使って解放する必要がある
JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
jvmdiError SuspendThread(jthread thread)
指定されたスレッドを中断します。呼び出し側スレッドが指定されている場合、この関数は、ほかのスレッドが ResumeThread
または ResumeThreadList
を呼び出すまで戻りません。
パラメータ:
- thread
- 中断するスレッド
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_INVALID_THREAD
thread
が無効JVMDI_ERROR_THREAD_SUSPENDED
- スレッドはすでに中断されている
reqList 配列で指定された reqCount スレッドを中断します。呼び出し側スレッドが reqList 配列で指定されている場合、この関数は、ほかのスレッドがjvmdiError SuspendThreadList(jint reqCount, jthread *reqList, jvmdiError *results)
ResumeThread
または ResumeThreadList
を呼び出すまで戻りません。
パラメータ:
- reqCount
- 中断するスレッドの数
- reqList
- 中断するスレッドのリスト
- results
- スレッドごとの中断結果のリスト
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_ILLEGAL_ARGUMENT
- reqCount はゼロ (0) 未満
関数の戻り値にスレッドごとのエラー状態は含まれません。スレッドごとのエラー状態は結果配列を介して返されます。
指定したスレッドの結果配列要素には、汎用エラー、または次のエラーのどれかが含まれます。
JVMDI_ERROR_INVALID_THREAD
thread
が無効JVMDI_ERROR_THREAD_SUSPENDED
- スレッドはすでに中断されている
JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
jvmdiError ResumeThread(jthread thread)
中断されているスレッドの実行を再開します。java.lang.Thread.suspend()
、SuspendThread
、または SuspendThreadList
によって中断されたスレッドの実行を再開します。
パラメータ:
- thread
- 再開するスレッド
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_INVALID_THREAD
thread
が無効JVMDI_ERROR_THREAD_NOT_SUSPENDED
- スレッドは中断されていない
JVMDI_ERROR_INVALID_TYPESTATE
- スレッドの状態が変更されたため、不整合が生じている
jvmdiError ResumeThreadList(jint reqCount, jthread *reqList, jvmdiError *results)
reqList 配列で指定された reqCount スレッドを再開します。java.lang.Thread.suspend()
、SuspendThread
、または SuspendThreadList
によって中断されたスレッドの実行を再開します。
パラメータ:
- reqCount
- 再開するスレッドの数
- reqList
- 再開するスレッドのリスト
- results
- スレッドごとの再開結果のリスト
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_ILLEGAL_ARGUMENT
- reqCount はゼロ (0) 未満
指定したスレッドの結果配列要素には、汎用エラー、または次のエラーのどれかが含まれます。
JVMDI_ERROR_INVALID_THREAD
thread
が無効JVMDI_ERROR_THREAD_NOT_SUSPENDED
- スレッドは中断されていない
JVMDI_ERROR_INVALID_TYPESTATE
- スレッドの状態が変更されたため、不整合が生じている
JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
jvmdiError StopThread(jthread thread, jobject exception)
指定された非同期の例外を指定されたスレッドに送ります (java.lang.Thread.stop
と同様)。通常、この関数は、指定されたスレッドを、例外 ThreadDeath のインスタンスを使って終了させるために使います。
パラメータ:
- thread
- 停止するスレッド
- exception
- 非同期の例外オブジェクト
この関数は、次のエラーコードのどれかを返します。
JVMDI_ERROR_INVALID_THREAD
jvmdiError InterruptThread(jthread thread)
指定されたスレッドに割り込みます (java.lang.Thread.interrupt
と同様)。
パラメータ:
- thread
- 割り込むスレッド
この関数は、次のエラーコードのどれかを返します。
JVMDI_ERROR_INVALID_THREAD
typedef struct { char *name; /* Name in UTF-8 */ jint priority; jboolean is_daemon; jthreadGroup thread_group; jobject context_class_loader; } JVMDI_thread_info; jvmdiError GetThreadInfo(jthread thread, JVMDI_thread_info *infoPtr)
スレッド情報を取得します。JVMDI_thread_info 構造体のフィールドに、指定されたスレッドの詳細が入ります。
パラメータ:
- thread
- 照会するスレッド
- infoPtr
- 戻ったとき、指定されたスレッドについての情報が入っている。返されるオブジェクト (スレッドグループおよびコンテキストクラスローダ) はグローバル参照で、JNI 関数
DeleteGlobalRef
を使って明示的に解放する必要がある。返されるスレッド名の文字列は、Deallocate
を使って解放する必要があるコンテキストクラスローダを認識しない JDK 1.1 の実装の場合、
context_class_loader
フィールドは null
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_INVALID_THREAD
thread
が無効JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
typedef struct { jint owned_monitor_count; jobject *owned_monitors; } JVMDI_owned_monitor_info; jvmdiError GetOwnedMonitorInfo(jthread thread, JVMDI_owned_monitor_info *infoPtr)
指定されたスレッドが所有するモニターについての情報を取得します。JVMDI_owned_monitor_info 構造体のフィールドに、所有するモニターの詳細が入ります。この関数を現在のスレッド以外のスレッドに対して呼び出す場合は、指定するスレッドを中断する必要があります。
この機能はオプションで、すべての仮想マシンに実装しなければならないわけではありません。特定の仮想マシンでサポートされている機能について判別するには、GetCapabilities
を使います。
パラメータ:
- thread
- 照会するスレッド
- infoPtr
- 戻ったとき、所有するモニターの情報が入っている。返されるオブジェクト (所有するモニターの配列) はグローバル参照で、JNI 関数
DeleteGlobalRef
を使って明示的に解放する必要がある。配列の入っているowned_monitors
バッファは、Deallocate
を使って解放する必要がある
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_INVALID_THREAD
thread
が無効JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
JVMDI_ERROR_THREAD_NOT_SUSPENDED
- 呼び出しの前に、
thread
が中断されている必要があるJVMDI_ERROR_NOT_IMPLEMENTED
- このオプション機能は、この VM に存在しない
jvmdiError GetCurrentContendedMonitor(jthread thread, jobject *monitorPtr)
指定されたスレッドが、java.lang.Object.wait
を使ってオブジェクトのモニターに入るか、モニターを獲得し直すのを待機している場合に、そのオブジェクトを取得します。この関数を現在のスレッド以外のスレッドに対して呼び出す場合は、指定するスレッドを中断する必要があります。
この機能はオプションで、すべての仮想マシンに実装しなければならないわけではありません。特定の仮想マシンでサポートされている機能について判別するには、GetCapabilities
を使います。
パラメータ:
- thread
- 照会するスレッド
- monitorPtr
- 戻ったとき、現在競合しているモニターが入っている。そのようなモニターがない場合は null が入っている。競合するモニターオブジェクトはグローバル参照で、JNI 関数
DeleteGlobalRef
を使って明示的に解放する必要がある
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_INVALID_THREAD
thread
が無効JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
JVMDI_ERROR_THREAD_NOT_SUSPENDED
- 呼び出しの前に、
thread
が中断されている必要があるJVMDI_ERROR_NOT_IMPLEMENTED
- このオプション機能は、この VM に存在しない
typedef void (*JVMDI_StartFunction)(void *); jvmdiError RunDebugThread(jthread thread, JVMDI_StartFunction proc, void *arg, int priority);
指定されたネイティブ関数を使って、デバッガスレッドの実行を開始します。この開始関数には、1 つの引数 arg
と、指定された優先順位が与えられます。この関数を利用すると、java.lang.Thread の特別なサブクラスや java.lang.Runnable の実装者をロードする必要なしに、別のプロセスとの通信を処理したりイベントを処理したりするデバッガスレッドを作成できます。こうして作成されたスレッドは、完全にネイティブとして機能できます。ただし、作成するスレッドには、java.lang.Thread の新しく作成されたインスタンス (引数 thread
によって参照される) が必要で、そのインスタンスにスレッドを関連付けます。スレッドオブジェクトは JNI 呼び出しによって作成できますが、デバッグ中のアプリケーションとの相互作用を避けるため、そのような Java コードへの呼び出しはデバッガの初期化中に行うことをお勧めします。
新しいスレッドは、デーモンスレッドとして起動されます。
proc
の実行時に、新しいスレッドは VM に接続されます。
パラメータ:
- thread
- 実行するスレッド
- proc
- 開始関数
- arg
- 開始関数への引数
- priority
- 開始されるスレッドの優先順位。java.lang.Thread.setPriority で許可されている、次の任意のスレッド優先順位を使用できる
JVMDI_THREAD_MIN_PRIORITY
JVMDI_THREAD_NORM_PRIORITY
JVMDI_THREAD_MAX_PRIORITY
この関数は、次のエラーコードのどれかを返します。
JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
JVMDI_ERROR_INVALID_THREAD
thread
が無効JVMDI_ERROR_INVALID_PRIORITY
jvmdiError GetTopThreadGroups(jint *groupCountPtr, jthreadGroup **groupsPtr)
VM 内のトップレベルの (親がない) スレッドグループをすべて返します。
パラメータ:
- groupCountPtr
- 戻ったとき、トップレベルのスレッドグループの数をポイントする
- groupsPtr
- 戻ったとき、トップレベルののスレッドグループの配列を指すポインタを参照する返されるグループ配列には、グローバル参照が入っており、JNI 関数
DeleteGlobalRef
を使って明示的に解放する必要がある。グループ配列の配列バッファは、Deallocate
を使って解放する必要がある
この関数は、次のエラーコードのどれかを返します。
JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
typedef struct { jthreadGroup parent; char *name; /* Name in UTF-8 */ jint max_priority; jboolean is_daemon; } JVMDI_thread_group_info; jvmdiError GetThreadGroupInfo(jthreadGroup group, JVMDI_thread_group_info *infoPtr)
スレッドグループの情報を取得します。JVMDI_thread_group_info 構造体のフィールドに、指定されたスレッドグループの詳細が入ります。
パラメータ:
- group
- 照会するスレッドグループ
- infoPtr
- 戻ったとき、指定されたスレッドグループについての情報が入っている。返されるスレッドグループの親はグローバル参照で、JNI 関数
DeleteGlobalRef
を使って明示的に解放する必要がある。返されるスレッドグループ名の文字列は、Deallocate
を使って解放する必要がある
この関数は、次のエラーコードのどれかを返します。
JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
JVMDI_ERROR_INVALID_THREAD_GROUP
指定されたスレッドグループ内で作成されたライブスレッドおよびアクティブなスレッドグループを取得します。スレッドが開始しており、まだ停止していない場合、そのスレッドはライブスレッドです。アクティブなスレッドグループについては、「java.lang.ThreadGroup」を参照してください。jvmdiError GetThreadGroupChildren(jthreadGroup group, jint *threadCountPtr, jthread **threadsPtr, jint *groupCountPtr, jthreadGroup **groupsPtr)
パラメータ:
- group
- 照会するグループ
- threadCountPtr
- 戻ったとき、所有されているライブスレッドの数をポイントする
- threadsPtr
- 戻ったとき、所有されているライブスレッド配列へのポインタを参照する。返されるスレッド配列には、グローバル参照が入っており、JNI 関数
DeleteGlobalRef
を使って明示的に解放する必要がある。スレッド配列のバッファは、Deallocate
を使って解放する必要がある- groupCountPtr
- 戻ったとき、アクティブな子スレッドグループの数をポイントする
- groupsPtr
- 戻ったとき、アクティブな子スレッドグループの配列へのポインタを参照する。返されるグループ配列には、グローバル参照が入っており、JNI 関数
DeleteGlobalRef
を使って明示的に解放する必要がある。グループ配列の配列バッファは、Deallocate
を使って解放する必要がある
この関数は、次のエラーコードのどれかを返します。
JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
JVMDI_ERROR_INVALID_THREAD_GROUP
jvmdiError GetFrameCount(jthread thread, jint *countPtr)
指定されたスレッドの呼び出しスタックに現在入っているフレームの数を取得します。
この関数を現在のスレッド以外のスレッドに対して呼び出す場合は、指定するスレッドを中断する必要がある
パラメータ:
この関数は、汎用エラー、または次のエラーのどれかを返します。
- thread
- 照会するスレッド
- countPtr
- 戻ったとき、呼び出しスタック内のフレームの数をポイントする
JVMDI_ERROR_INVALID_THREAD
thread
が無効JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
JVMDI_ERROR_THREAD_NOT_SUSPENDED
- スレッドは中断されていない
jvmdiError GetCurrentFrame(jthread thread, jframeID *framePtr)
thread
の現在のスタックフレームの jframeID
値を取得し、framePtr
を使って返します。
この関数を現在のスレッド以外のスレッドに対して呼び出す場合は、指定するスレッドを中断する必要があります。返されるフレーム ID 値は、thread
が実行を再開するまでの間のみ有効です。スレッドは、Java プログラミング言語または JNI メソッド内に存在する必要があります。
パラメータ:
この関数は、汎用エラー、または次のエラーのどれかを返します。
- thread
- 照会するスレッド
- framePtr
- 戻ったとき、このスレッドの現在のスタックフレームのフレーム ID をポイントする
JVMDI_ERROR_INVALID_THREAD
thread
が無効JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
JVMDI_ERROR_THREAD_NOT_SUSPENDED
- スレッドは中断されていない
JVMDI_ERROR_NO_MORE_FRAMES
- 呼び出しスタックに Java または JNI フレームがなくなった
jvmdiError PopFrame(jthread thread)
thread
スタックの最上位のスタックをポップします。フレームをポップすると、最上位のスタックフレームの呼び出し側のフレームに移動します。スレッドが再開されると、スレッドの状態は、メソッドが呼び出される直前の状態にリセットされます。オペランドスタックは回復します (objectref (適切な場合) および引数が再度追加されます)。ただし、呼び出し先のメソッドで発生した引数の変更内容は保持されます。実行を続行すると、最初の実行指示が呼び出しとなります。
PopFrame
の呼び出しとスレッドの再開の間、スタックの状態は未定義です。最初のフレームよりも前にフレームをポップするには、次の 3 つの手順を繰り返す必要があります。
PopFrame
を呼び出す
ポップされたフレームに対するロックは、ポップ時に解放されます。これは、ポップされた同期化メソッドや、その中の同期化ブロックにも当てはまります。
最終的に、ブロックは実行されません。
グローバル状態への変更には対応しません。
この関数を現在のスレッド以外のスレッドに対して呼び出す場合は、指定するスレッドを中断する必要があります。スレッドは、Java プログラミング言語または JNI メソッド内に存在する必要があります。
このスレッドのすべてのフレーム ID は無効です。
この関数は、JVMDI イベントを生成しません。
ネイティブフレームはポップされないことがあります。また、呼び出し側がネイティブコードの場合は Java フレームもポップされないことがあります。
この機能はオプションで、すべての仮想マシンに実装しなければならないわけではありません。特定の仮想マシンでこの機能がサポートされているかどうかを判別するには、GetCapabilities
の can_pop_frame
を調べてください。
パラメータ:
この関数は、汎用エラー、または次のエラーのどれかを返します。
- thread
- ポップするトップフレームのスレッド
JVMDI_ERROR_INVALID_THREAD
thread
が無効JVMDI_ERROR_OPAQUE_FRAME
frame
はネイティブフレームではないJVMDI_ERROR_NULL_POINTER
- 無効なポインタ
JVMDI_ERROR_THREAD_NOT_SUSPENDED
- スレッドが中断されていない、または現在のスレッド
JVMDI_ERROR_NO_MORE_FRAMES
- 呼び出しスタックに Java プログラミング言語のフレームがなくなった。
JVMDI_ERROR_NOT_IMPLEMENTED
- この機能が実装されていない (can_pop_frame 機能が false)
jvmdiError GetCallerFrame(jframeID called, jframeID *framePtr)
frame
について、それを呼び出したフレームを、framePtr
を使って返します。called
(呼び出し先) と呼び出し側の両方のフレームが、Java プログラム言語または JNI メソッド内に存在する必要があります。
パラメータ:
- called
- 呼び出されるフレーム
- framePtr
- 戻ったとき、呼び出し側フレームのフレーム ID をポイントする
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
JVMDI_ERROR_INVALID_FRAMEID
jframeID
が無効JVMDI_ERROR_NO_MORE_FRAMES
- 呼び出し側フレームが Java プログラミング言語または JNI メソッド内にない
jvmdiError GetFrameLocation(jframeID frame, jclass *classPtr, jmethodID *methodPtr, jlocation *locationPtr)
Java プログラミング言語のフレームについて、現在実行中の命令の位置を返します。
パラメータ:
- frame
- 照会するフレーム
- classPtr
- 戻ったとき、現在の位置のクラスをポイントする。返されるクラスは、JNI グローバル参照で、JNI 関数
DeleteGlobalRef
を使って明示的に解放する必要がある- methodPtr
- 戻ったとき、現在の位置のメソッドをポイントする
- locationPtr
- 戻ったとき、現在実行中の命令のインデックスをポイントする
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
JVMDI_ERROR_INVALID_FRAMEID
frame
は有効なフレーム ID ではない
jvmdiError NotifyFramePop(jframeID frame);
frame
がスタックからポップされたとき、JVMDI_EVENT_FRAME_POP
イベントを生成します。「イベント」を参照してください。
パラメータ:
- frame
- フレームのポップイベントが生成されるフレーム
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
JVMDI_ERROR_INVALID_FRAMEID
frame
は有効なフレーム ID ではない
jvmdiError GetLocalObject(jframeID frame, jint slot, jobject *valuePtr)
jvmdiError GetLocalInt(jframeID frame, jint slot, jint *valuePtr)
jvmdiError GetLocalLong(jframeID frame, jint slot, jlong *valuePtr)
jvmdiError GetLocalFloat(jframeID frame, jint slot, jfloat *valuePtr)
jvmdiError GetLocalDouble(jframeID frame, jint slot, jdouble *valuePtr)
これらの関数は、局所変数の値を取得するために使います。GetLocalInt
は、int、char、byte、および boolean 型の値の取得に使うことができます。変数は、変数の値を含んでいるフレームと、変数のスロット番号によって識別されます。変数からスロット番号へのマッピングは、関数 GetLocalVariableTable
を使って取得できます。
パラメータ:
- frame
- 変数の値を含むフレーム
- slot
- 変数のスロット番号
- valuePtr
- 戻ったとき、変数の値をポイントする。GetLocalObject に関しては、返される値はグローバル参照で、JNI 関数
DeleteGlobalRef()
を使って明示的に解放する必要がある
この関数は、次のエラーコードのどれかを返します。
JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
JVMDI_ERROR_INVALID_FRAMEID
frame
が無効JVMDI_ERROR_INVALID_SLOT
slot
が無効JVMDI_ERROR_TYPE_MISMATCH
- 使用した関数と変数の型が合わない
JVMDI_ERROR_OPAQUE_FRAME
jvmdiError SetLocalObject(jframeID frame, jint slot, jobject value)
jvmdiError SetLocalInt(jframeID frame, jint slot, jint value)
jvmdiError SetLocalLong(jframeID frame, jint slot, jlong value)
jvmdiError SetLocalFloat(jframeID frame, jint slot, jfloat value)
jvmdiError SetLocalDouble(jframeID frame, jint slot, jdouble value)
これらの関数は、局所変数の値を設定するために使います。SetLocalInt
は、int、char、byte、および boolean 型の値の設定に使うことができます。変数は、変数の値を含んでいるフレームと、変数のスロット番号によって識別されます。変数からスロット番号へのマッピングは、関数 GetLocalVariableTable
を使って取得できます。
パラメータ:
- frame
- 変数の値を含むフレーム
- slot
- 変数のスロット番号
- 値
- 変数の新しい値
この関数は、次のエラーコードのどれかを返します。
JVMDI_ERROR_OPAQUE_FRAME
- 無効なポインタ
JVMDI_ERROR_INVALID_FRAMEID
frame
が無効JVMDI_ERROR_INVALID_SLOT
slot
が無効JVMDI_ERROR_TYPE_MISMATCH
- 使用した関数と変数の型が合わない
jvmdiError SetBreakpoint(jclass clazz, jmethodID method, jlocation location)
clazz
、method
、および location
で指定された命令にブレークポイントを設定します。1 つの命令に対して設定できるブレークポイントは 1 つだけです。
指定した命令が実行される直前に、JVMDI_EVENT_BREAKPOINT
イベントが生成されます。「イベント」を参照してください。
パラメータ:
- clazz
- ブレークポイントを設定するクラス
- method
- ブレークポイントを設定するメソッド
- location
- ブレークポイントを設定する命令のインデックス
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_INVALID_METHODID
- 無効な
method
JVMDI_ERROR_INVALID_CLASS
clazz
が無効JVMDI_ERROR_INVALID_LOCATION
- 無効な位置
JVMDI_ERROR_DUPLICATE
- 指定されたバイトコードにはブレークポイントがすでに設定されている
jvmdiError ClearBreakpoint(jclass clazz, jmethodID method, jlocation location)
clazz
、method
、および location
で指定されたバイトコードに設定されているブレークポイントを解除します。
パラメータ:
- clazz
- ブレークポイントを解除するクラス
- method
- ブレークポイントを解除するメソッド
- location
- ブレークポイントを解除する命令のインデックス
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_INVALID_METHODID
- 無効な
method
JVMDI_ERROR_INVALID_CLASS
clazz
が無効JVMDI_ERROR_INVALID_LOCATION
- 無効な位置
JVMDI_ERROR_NOT_FOUND
- 指定されたバイトコードにはブレークポイントが設定されていない
この仮想マシンに設定されているブレークポイントをすべて解除します。jvmdiError ClearAllBreakpoints()
jvmdiError SetFieldAccessWatch(jclass clazz, jfieldID field)
clazz
および field
で指定されたフィールドがアクセスされようとした時点で、JVMDI_EVENT_FIELD_ACCESS イベントを生成します。イベントは、ClearFieldAccessWatch を使って取り消されるまで、フィールドがアクセスされるたびに生成されます。Java プログラミング言語コードまたは JNI からのフィールドアクセスが監視され、ほかの手段で変更されるフィールドは監視されません。JVMDI のユーザは、自分自身のフィールドアクセスによって監視イベントがトリガされることに注意してください。1 つのフィールドに対し、フィールドアクセスの監視を 1 つだけ設定できます。フィールドの変更はアクセスとはみなされません。変更を監視するには、SetFieldModificationWatch を使います。
この機能はオプションで、すべての仮想マシンに実装しなければならないわけではありません。特定の仮想マシンでサポートされている機能について判別するには、GetCapabilities
を使います。
パラメータ:
- clazz
- 監視するフィールドを含むクラス
- field
- 監視するフィールド
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_INVALID_FIELDID
field
に指定された jfieldID が有効なフィールド ID でないJVMDI_ERROR_INVALID_CLASS
clazz
に指定された jclass が有効なクラスでないJVMDI_ERROR_DUPLICATE
- 指定されたフィールドはすでにアクセスが監視されている
JVMDI_ERROR_NOT_IMPLEMENTED
- このオプション機能は、この VM に存在しない
jvmdiError ClearFieldAccessWatch(jclass clazz, jfieldID field)
SetFieldAccessWatch を使って設定した、clazz
および field
で指定されるフィールドに対するフィールドアクセスの監視を取り消します。
パラメータ:
- clazz
- 監視するフィールドを含むクラス
- field
- 監視するフィールド
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_INVALID_FIELDID
field
に指定された jfieldID が有効なフィールド ID でないJVMDI_ERROR_INVALID_CLASS
clazz
に指定された jclass が有効なクラスでないJVMDI_ERROR_NOT_FOUND
- 指定されたフィールドはアクセスが監視されていない
jvmdiError SetFieldModificationWatch(jclass clazz, jfieldID field)
clazz
および field
で指定されたフィールドが変更されようとした時点で、JVMDI_EVENT_FIELD_MODIFICATION イベントを生成します。イベントは、ClearFieldModificationWatch を使って取り消されるまで、フィールドが変更されるたびに生成されます。Java プログラミング言語コードまたは JNI からのフィールド変更が監視され、ほかの手段で変更されるフィールドは監視されません。JVMDI のユーザは、自分自身で実行するフィールド変更によって監視イベントがトリガされることに注意してください。1 つのフィールドに対し、フィールド変更の監視を 1 つだけ設定できます。
この機能はオプションで、すべての仮想マシンに実装しなければならないわけではありません。特定の仮想マシンでサポートされている機能について判別するには、GetCapabilities
を使います。
パラメータ:
- clazz
- 監視するフィールドを含むクラス
- field
- 監視するフィールド
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_INVALID_FIELDID
field
に指定された jfieldID が有効なフィールド ID でないJVMDI_ERROR_INVALID_CLASS
clazz
に指定された jclass が有効なクラスでないJVMDI_ERROR_DUPLICATE
- 指定されたフィールドはすでに変更が監視されている
JVMDI_ERROR_NOT_IMPLEMENTED
- このオプション機能は、この VM に存在しない
jvmdiError ClearFieldModificationWatch(jclass clazz, jfieldID field)
clazz
および field
で指定されるフィールドに対して、SetFieldModificationWatch を使って以前に設定したフィールド変更の監視を取り消します。
パラメータ:
- clazz
- 監視するフィールドを含むクラス
- field
- 監視するフィールド
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_INVALID_FIELDID
field
に指定された jfieldID が有効なフィールド ID でないJVMDI_ERROR_INVALID_CLASS
clazz
に指定された jclass が有効なクラスでないJVMDI_ERROR_NOT_FOUND
- 指定されたフィールドは変更が監視されていない
jvmdiError GetClassSignature(jclass clazz, char **sigPtr)
clazz
で指定されたクラスのクラスのシグニチャーを、sigPtr
を使って返します。戻り値は UTF-8 文字列です。
プリミティブクラス (たとえば、java.lang.Integer.TYPE) について返されるシグニチャーは、対応するプリミティブ型のシグニチャー (たとえば、「I」) です。
パラメータ:
- clazz
- 照会するクラス
- sigPtr
- 戻ったとき、クラスのシグニチャー (UTF-8) へのポインタを参照する。返されたシグニチャーの文字列は、
Deallocate
を使って解放する必要がある
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
JVMDI_ERROR_INVALID_CLASS
clazz
が無効
クラスのステータスを取得します。次のビットのうち、0 個以上のビットがセットされます。jvmdiError GetClassStatus(jclass clazz, jint *statusPtr)
JVMDI_CLASS_STATUS_VERIFIED
- クラスのバイトコードが検証された
JVMDI_CLASS_STATUS_PREPARED
- クラスの準備が完了した
JVMDI_CLASS_STATUS_INITIALIZED
- クラスの初期化が完了した。静的な初期化子が実行された
JVMDI_CLASS_STATUS_ERROR
- 初期化中のエラーによりクラスが使用できない
プリミティブクラス (たとえば、java.lang.Integer.TYPE) および配列のステータス値は、未定義です。
パラメータ:
- clazz
- 照会するクラス
- statusPtr
- 戻ったとき、このクラスの現在の状態として上記の 1 つ以上のフラグをポイントする
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
JVMDI_ERROR_INVALID_CLASS
clazz
が無効
jvmdiError GetSourceFileName(jclass clazz, char **sourceNamePtr)
clazz
で指定されたクラスについて、sourceNamePtr
を介してソースファイル名を返します。返される UTF-8 文字列は、ファイル名だけで、ディレクトリ名は含まれません。
プリミティブクラス (たとえば、java.lang.Integer.TYPE) および配列の場合、この関数は JVMDI_ERROR_ABSENT_INFORMATION を返します。
パラメータ:
- clazz
- 照会するクラス
- sourceNamePtr
- 戻ったとき、クラスのソースファイル名 (UTF-8) へのポインタを参照する。返されるファイル名の文字列は、
Deallocate
を使って解放する必要がある
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
JVMDI_ERROR_INVALID_CLASS
clazz
が無効JVMDI_ERROR_ABSENT_INFORMATION
- クラス情報に、ソースパスが含まれていない。これには、クラスが配列クラスまたはプリミティブクラスである場合が含まれる
jvmdiError GetClassModifiers(jclass clazz, jint *modifiersPtr)
clazz
で指定されたクラスのアクセスフラグを、modifiersPtr
を介して返します。アクセスフラグの定義と、クラス修飾子についての情報は、「Java 仮想マシン仕様」を参照してください。
クラスが配列クラスの場合、その public、private および protected 修飾子は、そのコンポーネント型の修飾子と同じです。プリミティブ型の配列の場合、このコンポーネント型は、プリミティブクラスの 1 つ (たとえば、java.lang.Integer.TYPE) で表現されます。
クラスがプリミティブクラスの場合、その public 修飾子は常に true になります。また、その protected 修飾子および private 修飾子は常に false になります。
クラスが配列クラスまたはプリミティブクラスの場合、その final 修飾子は常に true になり、interface 修飾子は常に false になります。その他の修飾子の値は、この仕様では判定されません。
パラメータ:
- clazz
- 照会するクラス
- modifiersPtr
- 戻ったとき、このクラスの現在のアクセスフラグをポイントする
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
JVMDI_ERROR_INVALID_CLASS
clazz
が無効
jvmdiError GetClassMethods(jclass clazz, jint *methodCountPtr, jmethodID **methodsPtr)
clazz
で指定されたクラスに含まれるメソッドの数を methodCountPtr
を介して返し、メソッド ID のリストを methodsPtr
を介して返します。メソッドのリストには、本来のメソッドだけでなく、コンストラクタおよび static 初期化子も含まれます。直接宣言されたメソッドだけが返されます (継承したメソッドは返されない)。メソッドは、クラスファイル内に出現する順序で返されます。配列クラスおよびプリミティブクラス (たとえば、java.lang.Integer.TYPE) の場合、空のメソッドリストが返されます。
パラメータ:
- clazz
- 照会するクラス
- methodCountPtr
- 戻ったとき、このクラスで宣言されているメソッドの数をポイントする
- methodsPtr
- 戻ったとき、メソッド ID の配列をポイントする。JVMDI アロケータが、配列にメモリを割り当てる。配列は、
Deallocate()
を使って解放する必要がある
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
JVMDI_ERROR_INVALID_CLASS
clazz
が無効JVMDI_ERROR_CLASS_NOT_PREPARED
jvmdiError GetClassFields(jclass clazz, jint *fieldCountPtr, jfieldID **fieldsPtr)
clazz
で指定されたクラスに含まれるフィールドの数を fieldCountPtr
を介して返し、フィールド ID のリストを fieldsPtr
を介して返します。直接宣言されたフィールドだけが返されます (継承したフィールドは返されない)。フィールドは、クラスファイル内に出現する順序で返されます。配列クラスおよびプリミティブクラス (たとえば、java.lang.Integer.TYPE) の場合、空のフィールドリストが返されます。JNI を使って、配列の長さを判別してください。
パラメータ:
- clazz
- 照会するクラス
- fieldCountPtr
- 戻ったとき、このクラスで宣言されているフィールドの数をポイントする
- fieldsPtr
- 戻ったとき、フィールド ID の配列をポイントする。JVMDI アロケータが、配列にメモリを割り当てる。
Deallocate()
を使ってメモリを解放する必要がある
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
JVMDI_ERROR_INVALID_CLASS
clazz
が無効JVMDI_ERROR_CLASS_NOT_PREPARED
このクラスの直接のスーパーインタフェースを返します。クラスに対しては、この関数は、jvmdiError GetImplementedInterfaces(jclass clazz, jint *interfaceCountPtr, jclass **interfacesPtr);
implements
節で宣言されているインタフェースを返します。インタフェースに対しては、この関数は、extends
節で宣言されているインタフェースを返します。配列クラスおよびプリミティブクラス (たとえば、java.lang.Integer.TYPE) の場合、空のインタフェースリストが返されます。
パラメータ:
- clazz
- 照会するクラス
- interfaceCountPtr
- 戻ったとき、インタフェースの数をポイントする
- interfacesPtr
- 戻ったとき、インタフェースの配列をポイントする。配列内のインタフェースは、JNI グローバル参照で、JNI 関数
DeleteGlobalRef
を使って明示的に解放する必要がある。返されるインタフェースの配列は、Deallocate
を使って解放する必要がある
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
JVMDI_ERROR_INVALID_CLASS
clazz
が無効JVMDI_ERROR_CLASS_NOT_PREPARED
クラスオブジェクト参照がインタフェースを表しているかどうかを判定します。クラスが実際にインタフェースである場合、jvmdiError IsInterface(jclass clazz, jboolean *isInterfacePtr)
jboolean
は JNI_TRUE
を返し、インタフェースではない場合には JNI_FALSE
を返します。
パラメータ:
- clazz
- 照会するクラス
- isInterfacePtr
- 戻ったとき、この関数の boolean 型の結果をポイントする
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
JVMDI_ERROR_INVALID_CLASS
clazz
が無効
クラスオブジェクト参照が配列を表しているかどうかを判定します。jvmdiError IsArrayClass(jclass clazz, jboolean *isArrayClassPtr)
jboolean
は、クラスが配列である場合は JNI_TRUE
になり、そのでない場合は JNI_FALSE
になります。
パラメータ:
- clazz
- 照会するクラス
- isArrayClassPtr
- 戻ったとき、この関数の boolean 型の結果をポイントする
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
JVMDI_ERROR_INVALID_CLASS
clazz
が無効
jvmdiError GetClassLoader(jclass clazz, jobject *classloaderPtr)
clazz
で指定されたクラスのクラスローダへの参照を、classloaderPtr
を介して返します。指定したクラスがクラスローダにより作成されたものでない場合には、classloaderPtr
は null
をポイントします。
パラメータ:
- clazz
- 照会するクラス
- classloaderPtr
- 戻ったとき、このクラスまたはインタフェースをロードしたクラスローダをポイントする。クラスローダを持たない場合は、null をポイントする。返されるクラスローダは、JNI グローバル参照で、JNI 関数
DeleteGlobalRef
を使って明示的に解放する必要がある
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
JVMDI_ERROR_INVALID_CLASS
clazz
が無効
jvmdiError GetSourceDebugExtension(jclass clazz, char **sourceDebugExtensionPtr)
clazz
で指示されたクラスについて、sourceDebugExtensionPtr
を介してデバッグ拡張機能を返します。返される UTF-8 文字列には、clazz
ファイルに存在するデバッグ拡張情報がそのまま含まれます。
パラメータ:
- clazz
- 照会するクラス
- sourceDebugExtensionPtr
- 戻ったとき、クラスのデバッグ拡張機能名 (UTF-8) へのポインタを参照する。返されたシグニチャーの文字列は、
Deallocate
を使って解放する必要がある。
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_NULL_POINTER
JVMDI_ERROR_INVALID_CLASS
clazz
が無効
JVMDI_ERROR_ABSENT_INFORMATION
jvmdiError GetObjectHashCode(jobject object, jint *hashCodePtr)
object
で指定されたオブジェクトについて、オブジェクト参照のハッシュテーブルの維持に使用できるハッシュコードを、hashCodePtr
を介して返します。この関数は、特定のオブジェクトの持続期間中ずっと、そのオブジェクトのハッシュコード値が同じであることを保証します。
パラメータ:
- object
- 照会するオブジェクト
- hashCodePtr
- 戻ったとき、オブジェクトのハッシュコードをポイントする
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
JVMDI_ERROR_INVALID_OBJECT
object
が無効
typedef struct { jthread owner; jint entry_count; jint waiter_count; jthread *waiters; } JVMDI_monitor_info; jvmdiError GetMonitorInfo(jobject object, JVMDI_monitor_info *infoPtr)
オブジェクトのモニターに関する情報を取得します。JVMDI_owned_monitor_info 構造体のフィールドに、モニターの詳細が入ります。モニターの状態に影響を与える可能性のある各スレッドは、中断されているか、または現在のスレッドである必要があります。
この機能はオプションで、すべての仮想マシンに実装しなければならないわけではありません。特定の仮想マシンでサポートされている機能について判別するには、GetCapabilities
を使います。
パラメータ:
- object
- 照会するオブジェクト
- infoPtr
- 戻ったとき、指定されたオブジェクトのモニター情報が入っている。返されるオブジェクト (所有者、待機者の配列) はグローバル参照で、JNI 関数
DeleteGlobalRef
を使って明示的に解放する必要がある。返される待機者の配列のバッファは、Deallocate
を使って解放する必要がある
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_INVALID_OBJECT
thread
が無効JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
JVMDI_ERROR_THREAD_NOT_SUSPENDED
- 呼び出し前にスレッドが中断されている必要がある
JVMDI_ERROR_NOT_IMPLEMENTED
- このオプション機能は、この VM に存在しない
jvmdiError GetFieldName(jclass clazz, jfieldID field, char **namePtr, char **signaturePtr)
clazz
と field
で指定されたフィールドについて、名前を namePtr
で返し、シグニチャーを signaturePtr
で返します。
パラメータ:
- clazz
- 照会するクラス
- field
- 照会するフィールド
- namePtr
- 戻ったとき UTF-8 形式のフィールド名へのポインタを参照する。この文字列は、
Deallocate
を使って解放する必要がある- signaturePtr
- 戻ったとき、UTF-8 形式のフィールドシグニチャーへのポインタを参照する。この文字列は、
Deallocate
を使って解放する必要がある
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
JVMDI_ERROR_INVALID_FIELDID
field
が無効JVMDI_ERROR_INVALID_CLASS
clazz
が無効
jvmdiError GetFieldDeclaringClass(jclass clazz, jfieldID field, jclass *declaringClassPtr)
clazz
と field
で指定されたフィールドについて、そのフィールドを定義しているクラスを declaringClassPtr
を介して返します。宣言しているクラスは、clazz
、スーパークラス、または実装されたインタフェースのどれかです。
パラメータ:
- clazz
- 照会するクラス
- field
- 照会するフィールド
- declaringClassPtr
- 戻ったとき、宣言しているクラスをポイントする。返されるクラスは、JNI グローバル参照で、JNI 関数
DeleteGlobalRef
を使って明示的に解放する必要がある
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
JVMDI_ERROR_INVALID_FIELDID
field
が無効JVMDI_ERROR_INVALID_CLASS
clazz
が無効
jvmdiError GetFieldModifiers(jclass clazz, jfieldID field, jint *modifiersPtr)
clazz
と field
で指定されたフィールドのアクセスフラグを、modifiersPtr
を介して返します。アクセスフラグの定義と、フィールド修飾子についての情報は、「Java 仮想マシン仕様」を参照してください。
パラメータ:
- clazz
- 照会するクラス
- field
- 照会するフィールド
- modifiersPtr
- 戻ったとき、アクセスフラグをポイントする
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
JVMDI_ERROR_INVALID_FIELDID
- 無効な
method
JVMDI_ERROR_INVALID_CLASS
clazz
が無効
jvmdiError IsFieldSynthetic(jclass clazz, jfieldID field, jboolean *isSyntheticPtr)
clazz
および field
で指定されたフィールドについて、それが合成フィールドであるかどうかを示す値を、isSyntheticPtr
を介して返します。合成フィールドはコンパイラによって生成されますが、元のソースコード内には存在しません。
この機能はオプションで、すべての仮想マシンに実装しなければならないわけではありません。特定の仮想マシンでサポートされている機能について判別するには、GetCapabilities
を使います。
パラメータ:
- clazz
- 照会するクラス
- field
- 照会するフィールド
- isSyntheticPtr
- 戻ったとき、この関数の boolean 型の結果をポイントする
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
JVMDI_ERROR_INVALID_FIELDID
field
が無効JVMDI_ERROR_INVALID_CLASS
clazz
が無効JVMDI_ERROR_NOT_IMPLEMENTED
- このオプション機能は、この VM に存在しない
jvmdiError GetMethodName(jclass clazz, jmethodID method, char **namePtr, char **signaturePtr)
clazz
と method
で指定されたメソッドについて、名前を namePtr
で返し、シグニチャーを signaturePtr
で返します。このシグニチャーは、JNI シグニチャーで、Java 仮想マシン仕様ではメソッド記述子とも呼ばれています。これは、Java 言語仕様で定義されているメソッドシグニチャーとは違うので、注意してください。
パラメータ:
- clazz
- 照会するクラス
- method
- 照会するメソッド
- namePtr
- 戻ったとき、UTF-8 形式のメソッド名へのポインタを参照する。この文字列は、
Deallocate
を使って解放する必要がある- signaturePtr
- 戻ったとき、UTF-8 形式のメソッドシグニチャーへのポインタを参照する。この文字列は、
Deallocate
を使って解放する必要がある
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
JVMDI_ERROR_INVALID_METHODID
- 無効な
method
JVMDI_ERROR_INVALID_CLASS
clazz
が無効
jvmdiError GetMethodDeclaringClass(jclass clazz, jmethodID method, jclass *declaringClassPtr)
clazz
と method
で指定されたメソッドについて、そのメソッドを定義しているクラスを、declaringClassPtr
を介して返します。
パラメータ:
- clazz
- 照会するクラス
- method
- 照会するメソッド
- declaringClassPtr
- 戻ったとき、宣言しているクラスをポイントする。返されるクラスは、JNI グローバル参照で、JNI 関数
DeleteGlobalRef
を使って明示的に解放する必要がある
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
JVMDI_ERROR_INVALID_METHODID
- 無効な
method
JVMDI_ERROR_INVALID_CLASS
clazz
が無効
jvmdiError GetMethodModifiers(jclass clazz, jmethodID method, jint *modifiersPtr)
clazz
と method
で指定されたメソッドのアクセスフラグを、modifiersPtr
を介して返します。アクセスフラグの定義と、メソッド修飾子についての情報は、「Java 仮想マシン仕様」を参照してください。
パラメータ:
- clazz
- 照会するクラス
- method
- 照会するメソッド
- modifiersPtr
- 戻ったとき、アクセスフラグをポイントする
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
JVMDI_ERROR_INVALID_METHODID
- 無効な
method
JVMDI_ERROR_INVALID_CLASS
clazz
が無効
jvmdiError GetMaxStack(jclass clazz, jmethodID method, jint *maxPtr)
clazz
と method
で指定されたメソッドについて、そのメソッドの実行中にスタック上に置ける最大ワード数を、maxPtr
を介して返します。
パラメータ:
- clazz
- 照会するクラス
- method
- 照会するメソッド
- maxPtr
- 戻ったとき、スタックの最大ワード数をポイントする
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
JVMDI_ERROR_INVALID_METHODID
- 無効な
method
JVMDI_ERROR_INVALID_CLASS
clazz
が無効
jvmdiError GetMaxLocals(jclass clazz, jmethodID method, jint *maxPtr);
clazz
と method
で指定されたメソッドについて、そのメソッド全体で使用される局所変数のスロット数を、maxPtr
を介して返します。なお、2 ワードの引数は、スロットを 2 つ使用します。
パラメータ:
- clazz
- 照会するクラス
- method
- 照会するメソッド
- maxPtr
- 戻ったとき、局所変数のスロットの最大数をポイントする
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
JVMDI_ERROR_INVALID_METHODID
- 無効な
method
JVMDI_ERROR_INVALID_CLASS
clazz
が無効
jvmdiError GetArgumentsSize(jclass clazz, jmethodID method, jint *sizePtr)
clazz
と method
で指定されたメソッドについて、そのメソッドの引数によって使用される局所変数のスロット数を、maxPtr
を介して返します。なお、2 ワードの引数は、スロットを 2 つ使用します。
パラメータ:
- clazz
- 照会するクラス
- method
- 照会するメソッド
- sizePtr
- 戻ったとき、引数のスロットの数をポイントする
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
JVMDI_ERROR_INVALID_METHODID
- 無効な
method
JVMDI_ERROR_INVALID_CLASS
clazz
が無効
jvmdiError GetLineNumberTable(jclass clazz, jmethodID method, jint *entryCountPtr, JVMDI_line_number_entry **tablePtr)
clazz
と method
で指定されたメソッドについて、ソース行番号のエントリから成るテーブルを返します。テーブルのサイズは entryCountPtr
により返され、テーブル自体は tablePtr
により返されます。テーブルのエントリは、次の構造体のインスタンスです。
パラメータ:typedef struct { jlocation start_location; jint line_number; } JVMDI_line_number_entry;
- clazz
- 照会するクラス
- method
- 照会するメソッド
- entryCountPtr
- 戻ったとき、テーブル内のエントリの数をポイントする
- tablePtr
- 戻ったとき、行番号テーブルのポインタをポイントする。JVMDI アロケータが、テーブルに領域を割り当てる。このテーブルは、
Deallocate()
を使って解放する必要がある
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_NONE
- エラーなし
JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
JVMDI_ERROR_INVALID_METHODID
- 無効な
method
JVMDI_ERROR_INVALID_CLASS
clazz
が無効JVMDI_ERROR_ABSENT_INFORMATION
- クラスの情報に行番号が含まれていない
jvmdiError GetMethodLocation(jclass clazz, jmethodID method, jlocation *startLocationPtr, jlocation *endLocationPtr)
clazz
と method
で指定されたメソッドについて、その開始アドレスと終了アドレスを startLocationPtr
と endLocationPtr
により返します。バイトコードの通常のインデックス法では、これらの値は常に、ゼロと、バイトコード数から 1 を引いた数になります。
パラメータ:
- clazz
- 照会するクラス
- method
- 照会するメソッド
- startLocationPtr
- 戻ったとき、最初の位置をポイントする。位置情報が得られない場合は -1 をポイントする
- endLocationPtr
- 戻ったとき、最後の位置をポイントする。位置情報が得られない場合は -1 をポイントする
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
JVMDI_ERROR_INVALID_METHODID
- 無効な
method
JVMDI_ERROR_INVALID_CLASS
clazz
が無効JVMDI_ERROR_ABSENT_INFORMATION
- クラス情報にメソッドのサイズが含まれていない
jvmdiError GetLocalVariableTable(jclass clazz, jmethodID method, jint *entryCountPtr, JVMDI_local_variable_entry **tablePtr)
clazz
と method
で指定されたメソッドについて、局所変数のテーブルを返します。テーブルのサイズは entryCountPtr
により返され、テーブル自体は tablePtr
により返されます。テーブルのエントリは、次の構造体になっています。
typedef struct { jlocation start_location; /* variable valid start_location */ jint length; /* up to start_location+length */ char *name; /* name in UTF-8 */ char *signature; /* type signature in UTF-8 */ jint slot; /* variable slot, see JVMDI_GetLocal*() */ } JVMDI_local_variable_entry;
パラメータ:
- clazz
- 照会するクラス
- method
- 照会するメソッド
- entryCountPtr
- 戻ったとき、テーブル内のエントリの数をポイントする
- tablePtr
- 戻ったとき、局所変数テーブルのポインタをポイントする。JVMDI アロケータが、テーブルに領域を割り当てる。また、テーブル内のそれぞれの名前およびシグニチャー文字列も、JVMDI アロケータによって割り当てられる。これらのバッファは、
Deallocate
を使って解放する必要がある
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
JVMDI_ERROR_INVALID_METHODID
- 無効な
method
JVMDI_ERROR_INVALID_CLASS
clazz
が無効JVMDI_ERROR_ABSENT_INFORMATION
- クラス情報に局所変数の情報が含まれていない
jvmdiError GetExceptionHandlerTable(jclass clazz, jmethodID method, jint *entryCountPtr, JVMDI_exception_handler_entry **tablePtr)
clazz
と method
で指定されたメソッドについて、例外ハンドラのテーブルを返します。テーブルのサイズは entryCountPtr
により返され、テーブル自体は tablePtr
により返されます。テーブルのエントリは、次の構造体になっています。
typedef struct { jlocation start_location; jlocation end_location; jlocation handler_location; jclass exception; /* if null, all exceptions */ } JVMDI_exception_handler_entry;
この関数を呼び出すと、スローされる例外クラスのうち、まだロードされていないクラスのロードが行われることがあります。スレッドの中断中に呼び出してはなりません。
パラメータ:
- clazz
- 照会するクラス
- method
- 照会するメソッド
- entryCountPtr
- 戻ったとき、テーブル内のエントリの数をポイントする
- tablePtr
- 戻ったとき、例外ハンドラテーブルのポインタをポイントする。JVMDI アロケータが、テーブルに領域を割り当てる。このテーブルは、
Deallocate()
を使って解放する必要があるJVMDI_exception_handler_entry の exception フィールドに返されるクラスは、グローバル参照で、JNI 関数Deallocate
を使って明示的に解放する必要がある
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
JVMDI_ERROR_INVALID_METHODID
- 無効な
method
JVMDI_ERROR_INVALID_CLASS
clazz
が無効
jvmdiError GetThrownExceptions(jclass clazz, jmethodID method, jint *exceptionCountPtr, jclass **exceptionsPtr)
clazz
と method
で指定されたメソッドについて、そのメソッドがスローする可能性がある例外クラスの配列を返します。例外の数は、exceptionCountPtr
を介して返されます。例外の配列は、exceptionsPtr
を介して返されます。
この関数を呼び出すと、スローされる例外クラスのうち、まだロードされていないクラスのロードが行われることがあります。スレッドの中断中に呼び出してはなりません。
パラメータ:
- clazz
- 照会するクラス
- method
- 照会するメソッド
- exceptionCountPtr
- 戻ったとき、スローされる例外の数をポイントする
- exceptionsPtr
- 戻ったとき、スローされる例外への参照 (例外ごとに 1 つずつ) の配列をポイントする。配列内の例外クラスは、JNI グローバル参照で、JNI 関数
DeleteGlobalRef
を使って明示的に解放する必要がある。返される例外の配列は、Deallocate
を使って解放する必要がある
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
JVMDI_ERROR_INVALID_METHODID
- 無効な method
JVMDI_ERROR_INVALID_CLASS
- 無効な class
jvmdiError GetBytecodes(jclass clazz, jmethodID method, jint *bytecodeCountPtr, jbyte **bytecodesPtr)
clazz
と method
で指定されたメソッドについて、そのメソッドを実装するバイトコードを返します。バイトコードの数は、bytecodeCountPtr
を介して返されます。バイトコード自体は、bytecodesPtr
を介して返されます。
この機能はオプションで、すべての仮想マシンに実装しなければならないわけではありません。特定の仮想マシンでサポートされている機能について判別するには、GetCapabilities
を使います。
パラメータ:
- clazz
- 照会するクラス
- method
- 照会するメソッド
- bytecodeCountPtr
- 戻ったとき、バイトコードの配列の長さをポイントする
- bytecodesPtr
- 戻ったとき、バイトコード配列へのポインタをポイントする。JVMDI のメモリアロケータが、バイトコードの配列にメモリを割り当てる。このテーブルは、
Deallocate()
を使って解放する必要がある
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
JVMDI_ERROR_INVALID_CLASS
clazz
が無効JVMDI_ERROR_INVALID_METHODID
- 無効な
method
JVMDI_ERROR_NOT_IMPLEMENTED
- このオプション機能は、この VM に存在しない
jvmdiError IsMethodNative(jclass clazz, jmethodID method, jboolean *isNativePtr)
clazz
と method
で指定されたメソッドがネイティブメソッドかどうかを表す値を、isNativePtr
を介して返します。
パラメータ:
- clazz
- 照会するクラス
- method
- 照会するメソッド
- isNativePtr
- 戻ったとき、この関数の boolean 型の結果をポイントする
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
JVMDI_ERROR_INVALID_METHODID
- 無効な
method
JVMDI_ERROR_INVALID_CLASS
clazz
が無効
jvmdiError IsMethodSynthetic(jclass clazz, jmethodID method, jboolean *isSyntheticPtr)
clazz
と method
で指定されたメソッドについて、それが合成メソッドであるかどうかを示す値を、isSyntheticPtr
を介して返します。合成メソッドは、コンパイラによって生成されますが、元のソースコード内には存在しません。
この機能はオプションで、すべての仮想マシンに実装しなければならないわけではありません。特定の仮想マシンでサポートされている機能について判別するには、GetCapabilities
を使います。
パラメータ:
- clazz
- 照会するクラス
- method
- 照会するメソッド
- isSyntheticPtr
- 戻ったとき、この関数の boolean 型の結果をポイントする
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
JVMDI_ERROR_INVALID_METHODID
- 無効な
method
JVMDI_ERROR_INVALID_CLASS
clazz
が無効JVMDI_ERROR_NOT_IMPLEMENTED
- このオプション機能は、この VM に存在しない
raw モニターを作成します。jvmdiError CreateRawMonitor(char *name, JVMDI_RawMonitor *monitorPtr)
パラメータ:
- name
- モニターを識別する UTF-8 形式の名前
- monitorPtr
- 戻ったとき、作成されたモニターをポイントする
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
raw モニターを破棄します。jvmdiError DestroyRawMonitor(JVMDI_RawMonitor monitor)
パラメータ:
- monitor
- モニター
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_INVALID_MONITOR
- 無効なモニター
raw モニターの排他的所有権を取得します。jvmdiError RawMonitorEnter(JVMDI_RawMonitor monitor)
パラメータ:
- monitor
- モニター
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_INVALID_MONITOR
- 無効なモニター
raw モニターの排他的所有権を解放します。jvmdiError RawMonitorExit(JVMDI_RawMonitor monitor)
パラメータ:
- monitor
- モニター
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_INVALID_MONITOR
- 無効なモニター
JVMDI_ERROR_NOT_MONITOR_OWNER
raw モニターの通知を待ちます。jvmdiError RawMonitorWait(JVMDI_RawMonitor monitor, jlong millis)
パラメータ:
- monitor
- モニター
- millis
- タイムアウト (ミリ秒単位)
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_INVALID_MONITOR
- 無効なモニター
JVMDI_ERROR_NOT_MONITOR_OWNER
JVMDI_ERROR_INTERRUPT
raw モニターを待機中の 1 つのスレッドに通知します。jvmdiError RawMonitorNotify(JVMDI_RawMonitor monitor)
パラメータ:
- monitor
- モニター
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_INVALID_MONITOR
- 無効なモニター
JVMDI_ERROR_NOT_MONITOR_OWNER
raw モニターを待機中のすべてのスレッドに通知します。jvmdiError RawMonitorNotifyAll(JVMDI_RawMonitor monitor)
パラメータ:
- monitor
- モニター
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_INVALID_MONITOR
- 無効なモニター
JVMDI_ERROR_NOT_MONITOR_OWNER
すべてのイベントごとに呼び出される関数を設定します。イベントの詳細は、このドキュメントで後述します。typedef void (*JVMDI_EventHook)(JNIEnv *env , JVMDI_Event *event); jvmdiError SetEventHook(JVMDI_EventHook hook)
パラメータ:
- hook
- 新しいイベントフック、または null (既存のフックを削除する場合)
この関数は、エラーの場合は汎用エラーを返します。
イベントの生成を制御します。jvmdiError SetEventNotificationMode(jint mode, jint eventType, jthread thread, ...)
mode
が JVMDI_ENABLE の場合は、イベント eventType
が有効にされます。mode
が JVMDI_DISABLE の場合は、イベントが無効にされます。thread
が null の場合は、このイベントはグローバルに有効または無効にされます。そうでない場合は、特定のスレッドについて有効または無効にされます。特定のスレッドについてイベントが生成されるのは、イベントがスレッドレベルまたはグローバルレベルのどちらかで有効にされている場合です。
イベントの有効化は、グローバルとスレッド単位でそれぞれ独立しています。たとえば、MethodEntry が最初にグローバルでも各スレッドでも無効になっている場合、MethodEntry をグローバルで有効にしても、スレッド単位では無効のままです。実行中のスレッドが潜在的なイベント条件に遭遇した場合、そのイベントがグローバルまたは実行中のスレッドで有効にされていると、そのイベントが送られます。イベントのグローバルな有効化は、呼び出しの後に作成されるスレッドにも適用されます。
個々のイベントについての情報は、後述する説明を参照してください。
次のイベントは、この関数を使ってスレッドレベルでは制御 (有効化または無効化) できません。
次のイベントは、この関数を使ってグローバルレベルでは制御 (有効化または無効化) できません。
最初は、スレッドレベルで有効にされているイベントはありません。次のイベント以外のイベントが、グローバルレベルで有効にされています。
パラメータ:
- mode
- JVMDI_ENABLE または JVMDI_DISABLE
- eventType
- 制御するイベント
- thread
- 制御するスレッド、または null (すべてのスレッドの場合)
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_INVALID_THREAD
thread
が無効、または実行されていない場合JVMDI_ERROR_INVALID_EVENT_TYPE
eventType
が無効な値の場合JVMDI_ERROR_ILLEGAL_ARGUMENT
thread
引数が、次のいずれかのイベントと一緒に指定されている場合
- JVMDI_EVENT_VM_INIT
- JVMDI_EVENT_VM_DEATH
- JVMDI_EVENT_THREAD_START
- JVMDI_EVENT_CLASS_UNLOAD
jvmdiError GetLoadedClasses(jint *classCountPtr, jclass **classesPtr)
仮想マシンにロードされている全クラスの配列を返します。配列内のクラスの数は classCountPtr
によって返され、配列自体は classesPtr
によって返されます。配列は、Deallocate()
を使って解放する必要があります。
返されるリストには、すべての型の配列クラス (プリミティブ型の配列を含む) が含まれます。プリミティブクラス (たとえば、java.lang.Integer.TYPE) は、このリストには含まれません。
パラメータ:
- classCountPtr
- 戻ったとき、クラスの数をポイントする
- classesPtr
- 戻ったとき、各クラスへの参照 (クラスごとに 1 つずつ) の配列をポイントする。配列内のクラスは、JNI グローバル参照で、JNI 関数
DeleteGlobalRef
を使って明示的に解放する必要がある。返されるクラス配列は、Deallocate
を使って解放する必要がある
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
jvmdiError GetClassLoaderClasses(jobject initiatingLoader, jint *classCountPtr, jclass **classesPtr)
このクラスローダが起動ローダとして記録されている、すべてのクラスの配列を返します。返される配列内の各クラスは、このクラスローダによって直接定義されて作成されたものか、または別のクラスローダに委譲して作成されたものです。
JDK 1.1 の実装では、起動クラスローダと定義クラスローダの区別が認識されないため、この関数は、仮想マシンにロードされたすべてのクラスを返します。配列内のクラスの数は classCountPtr
によって返され、配列自体は classesPtr
によって返されます。配列は、Deallocate()
を使って解放する必要があります。
initiatingLoader
引数は、null であってはなりません。システムクラスローダにより起動されたクラスのセットは、そのローダにより定義されたクラスのセットと同一です。このセットを判別するには、GetLoadedClasses を呼び出して、クラスローダが null のクラスを選び出します。
パラメータ:
- initiatingLoader
- 起動クラスローダ
- classCountPtr
- 戻ったとき、クラスの数をポイントする
- classesPtr
- 戻ったとき、各クラスへの参照 (クラスごとに 1 つずつ) の配列をポイントする。配列内のクラスは、JNI グローバル参照で、JNI 関数
DeleteGlobalRef
を使って明示的に解放する必要がある。返されるクラス配列は、Deallocate
を使って解放する必要がある
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
typedef struct { jclass clazz; /* Class to be redefined */ jint class_byte_count; /* number of bytes defining class (below) */ jbyte *class_bytes; /* bytes defining class */ /* (in Class File Format of JVM spec) */ } JVMDI_class_definition; jvmdiError RedefineClasses(jint classCount, JVMDI_class_definition *classDefs)
指定されたクラスはすべて、提供される定義に従って再定義されます。再定義されたメソッドにアクティブなスタックフレームがあると、そのアクティブフレームは元のメソッドのバイトコードの実行を続行します。再定義したメソッドは、新しい呼び出しで使用されます。jmethodID
を返す JVMDI の関数またはイベントは、再定義したメソッド (下記参照) と同等でないかぎり、元のメソッドを参照するときに OBSOLETE_METHOD_ID
を返します。たとえば、元のメソッドがまだ実行しているスタックフレームを検査するときなどです。元のメソッド ID は再定義されたメソッドを参照します。JVMDI クライアントで OBSOLETE_METHOD_ID
を扱う際には注意が必要です。スタックフレームをリセットする場合は、OBSOLETE_METHOD_ID
とともに PopFrame
を使用し、フレームをポップしてください。
元のメソッドと再定義したメソッドが同等とみなされるのは、次のような場合です。
この関数により、一般的な JVM セマンティクスのもとで行われる以外の初期化は起こりません。つまり、クラスを再定義しても、そのクラスの初期化は実行されません。既存のスタティック変数は、呼び出し前の状態のままです。ただし、まったく初期化されていない (新しい) スタティック変数には、既定値が割り当てられます。
再定義したクラスにインスタンスがある場合、そのインスタンスのフィールドは呼び出し完了時に再定義したクラスで定義されます。既存のフィールドは以前の値を保持します。新しいフィールドは既定値となります。インスタンスイニシャライザやコンストラクタは実行しません。
スレッドを中断する必要はありません。
クラス内のブレークポイントは解除されます。
属性はすべて更新されます。
この関数は、JVMDI イベントを生成しません。
この機能はオプションで、すべての仮想マシンに実装しなければならないわけではありません。特定の仮想マシンでこの機能がサポートされているかどうかを判定するには、GetCapabilities
の can_redefine_classed
、can_add_method
および can_unrestrictedly_redefine_classes
を調べてください。
パラメータ:
この関数は、汎用エラー、または次のエラーのどれかを返します。
- classCount
classDefs
で指定されたクラスの数- classDefs
- 新しいクラス定義の配列数
JVMDI_ERROR_NULL_POINTER
- 無効なポインタ。classDefs または class_bytes の 1 つが null
JVMDI_ERROR_INVALID_CLASS
- ClassDefs の要素が有効なクラスではない
JVMDI_ERROR_UNSUPPORTED_VERSION
- 新しいクラスファイルのバージョンがこの VM でサポートされていない
JVMDI_ERROR_INVALID_CLASS_FORMAT
- 新しいクラスファイルの形式が正しくない (VM がClassFormatError を返す)
JVMDI_ERROR_CIRCULAR_CLASS_DEFINITION
- 新しいクラスファイルの定義が循環定義になる (VM は ClassCircularityError を返す)
JVMDI_ERROR_FAILS_VERIFICATION
- クラスバイトが検証に失敗する
JVMDI_ERROR_NAMES_DONT_MATCH
- 新しいクラスファイル内で定義されたクラス名が、旧クラスオブジェクト内の名前と異なる
JVMDI_ERROR_NOT_IMPLEMENTED
- この機能は実装されていない (can_redefine_classes 機能が false)
JVMDI_ERROR_ADD_METHOD_NOT_IMPLEMENTED
- 新しいクラスファイルでメソッドの追加が必要になる (can_add_method 機能が false)
JVMDI_ERROR_SCHEMA_CHANGE_NOT_IMPLEMENTED
- 新しいクラスのバージョンによりフィールドが変更される (can_unrestrictedly_redefine_classes が false)
JVMDI_ERROR_HIERARCHY_CHANGE_NOT_IMPLEMENTED
- 新しいクラスのバージョンの直接スーパークラスが異なる、または直接実装されているインタフェースが異なる (can_unrestrictedly_redefine_classes が false)
JVMDI_ERROR_DELETE_METHOD_NOT_IMPLEMENTED
- 新しいクラスのバージョンでは旧クラスのバージョンで宣言したメソッドを宣言しない(can_unrestrictedly_redefine_classes が false)
JVMDI_ERROR_CLASS_MODIFIERS_CHANGE_NOT_IMPLEMENTED
- クラスの新しいバージョンのクラス修飾子 (public、abstract、final など) が旧バージョンと異なる (can_unrestrictedly_redefine_classes が false)
JVMDI_ERROR_METHOD_MODIFIERS_CHANGE_NOT_IMPLEMENTED
- クラスの新しいバージョンのメソッド修飾子 (public、abstract、final など) が旧バージョンと異なる (can_unrestrictedly_redefine_classes が false)
JVMDI のバージョンを、jvmdiError GetVersionNumber(jint *versionPtr)
versionPtr
を介して返します。戻り値はバージョン識別子です。下位の 16 ビットは、マイナーバージョン番号を表します。次の 12 ビットは、メジャーバージョン番号を表します。上位の 4 ビットは、未定義です。
パラメータ:
- versionPtr
- 戻ったとき、JVMDI のバージョンをポイントする
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
typedef struct { unsigned int can_watch_field_modification : 1; unsigned int can_watch_field_access : 1; unsigned int can_get_bytecodes : 1; unsigned int can_get_synthetic_attribute : 1; unsigned int can_get_owned_monitor_info : 1; unsigned int can_get_current_contended_monitor : 1; unsigned int can_get_monitor_info : 1; unsigned int reserved1 : 1; unsigned int reserved2 : 1; unsigned int reserved3 : 1; unsigned int can_pop_frame : 1; unsigned int reserved4 : 1; unsigned int can_redefine_classes : 1; unsigned int can_add_method : 1; unsigned int can_unrestrictedly_redefine_classes : 1; unsigned int reserved5 : 1; } JVMDI_capabilities; jvmdiError GetCapabilities(JVMDI_capabilities *capabilitiesPtr)
capabilitiesPtr
を介して、この実装でサポートされているオプションの JVMDI 機能を返します。capabilities 構造体には、フラグ名に示されている機能がサポートされているかどうかを示す、いくつかの boolean 型のフラグが含まれています。
パラメータ:
- capabilitiesPtr
- 戻ったとき、JVMDI の機能をポイントする
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_NULL_POINTER
- 無効なポインタ
JVMDI 関数はすべて、jvmdiError
エラーコードを返します。
JVMDI_ERROR_NONE
JVMDI_ERROR_OUT_OF_MEMORY
JVMDI_ERROR_ACCESS_DENIED
JVMDI_ERROR_UNATTACHED_THREAD
JVMDI_ERROR_VM_DEAD
JVMDI_ERROR_INTERNAL
JVMDI_ERROR_INVALID_THREAD
JVMDI_ERROR_INVALID_FIELDID
JVMDI_ERROR_INVALID_METHODID
JVMDI_ERROR_INVALID_LOCATION
JVMDI_ERROR_INVALID_FRAMEID
jframeID
JVMDI_ERROR_NO_MORE_FRAMES
JVMDI_ERROR_OPAQUE_FRAME
JVMDI_ERROR_NOT_CURRENT_FRAME
JVMDI_ERROR_TYPE_MISMATCH
JVMDI_ERROR_INVALID_SLOT
JVMDI_ERROR_DUPLICATE
JVMDI_ERROR_THREAD_NOT_SUSPENDED
JVMDI_ERROR_THREAD_SUSPENDED
JVMDI_ERROR_INVALID_OBJECT
JVMDI_ERROR_INVALID_CLASS
JVMDI_ERROR_CLASS_NOT_PREPARED
JVMDI_ERROR_NULL_POINTER
JVMDI_ERROR_ABSENT_INFORMATION
JVMDI_ERROR_INVALID_EVENT_TYPE
JVMDI_ERROR_NOT_IMPLEMENTED
JVMDI_ERROR_INVALID_THREAD_GROUP
JVMDI_ERROR_INVALID_PRIORITY
JVMDI_ERROR_NOT_FOUND
JVMDI_ERROR_INVALID_MONITOR
JVMDI_ERROR_ILLEGAL_ARGUMENT
JVMDI_ERROR_NOT_MONITOR_OWNER
JVMDI_ERROR_ABSENT_INFORMATION
JVMDI_ERROR_INTERRUPT
JVMDI_ERROR_INVALID_TYPESTATE
JVMDI_ERROR_UNSUPPORTED_VERSION
JVMDI_ERROR_INVALID_CLASS_FORMAT
JVMDI_ERROR_CIRCULAR_CLASS_DEFINITION
JVMDI_ERROR_ADD_METHOD_NOT_IMPLEMENTED
JVMDI_ERROR_SCHEMA_CHANGE_NOT_IMPLEMENTED
JVMDI_ERROR_FAILS_VERIFICATION
JVMDI_ERROR_HIERARCHY_CHANGE_NOT_IMPLEMENTED
JVMDI_ERROR_DELETE_METHOD_NOT_IMPLEMENTED
JVMDI_ERROR_NAMES_DONT_MATCH
JVMDI_ERROR_CLASS_MODIFIERS_CHANGE_NOT_IMPLEMENTED
JVMDI_ERROR_METHOD_MODIFIERS_CHANGE_NOT_IMPLEMENTED
イベントを処理するには、SetEventHook
を使ってフック関数を指定します。各イベントに対して、イベント型とその他の情報 (一部のイベントの場合) を記述した JVMDI_Event
引数を指定して、そのフック関数が呼び出されます。フック関数は、通常、アプリケーションスレッド内から呼び出されます。JVMDI 実装は、どんな形でもイベントをキューに入れません。これは、イベントのフック関数を注意深く記述する必要があることを意味しています。このあと、一般的なガイドラインを説明します。さらに詳しい提案については、個々のイベントの説明を参照してください。
JVMDI イベントの中には、JNI 参照を使ってオブジェクトを識別するものがあります。そのような参照はすべて、JVMDI_Event
引数を介してイベントフック関数に渡されます。JVMDI イベント内のすべての参照は、JNI ローカル参照で、イベントフック関数から復帰すると無効になります。 JVMDI_Event
データ構造体は、ローカルに割り当てられ、イベントフック関数から復帰すると解放されます。
イベントは、関数 SetEventNotificationMode を使って有効および無効にできます。アプリケーションの起動時に有効にされているイベントと、そうでないイベントがあります。この関数の詳細は、ドキュメントを参照してください。
イベントを生成するスレッドの実行状態は変化しません。スレッドを中断させる必要のあるイベントの場合は、イベントフック関数の中で SuspendThread を使って明示的にスレッドを中断させなければなりません。
JVMDI_Event
には、イベントの種類と、さらに多くの情報を含むイベント固有の構造体の共用体が含まれます。
typedef struct { jint kind; /* the discriminant */ union { /* kind = JVMDI_EVENT_SINGLE_STEP */ JVMDI_single_step_event_data single_step; /* kind = JVMDI_EVENT_BREAKPOINT */ JVMDI_breakpoint_event_data breakpoint; /* kind = JVMDI_EVENT_FRAME_POP */ /* kind = JVMDI_EVENT_METHOD_ENTRY */ /* kind = JVMDI_EVENT_METHOD_EXIT */ JVMDI_frame_event_data frame; /* kind = JVMDI_EVENT_FIELD_ACCESS */ JVMDI_field_access_event_data field_access; /* kind = JVMDI_EVENT_FIELD_MODIFICATION */ JVMDI_field_modification_event_data field_modification; /* kind = JVMDI_EVENT_EXCEPTION */ JVMDI_exception_event_data exception; /* kind = JVMDI_EVENT_EXCEPTION_CATCH */ JVMDI_exception_catch_event_data exception_catch; /* kind = JVMDI_EVENT_USER_DEFINED */ JVMDI_user_event_data user; /* kind = JVMDI_EVENT_THREAD_END or */ /* JVMDI_EVENT_THREAD_START */ JVMDI_thread_change_event_data thread_change; /* kind = JVMDI_EVENT_CLASS_LOAD, */ /* JVMDI_EVENT_CLASS_UNLOAD, or */ /* JVMDI_EVENT_CLASS_PREPARE */ JVMDI_class_event_data class_event; /* kind = JVMDI_EVENT_VM_DEATH, JVMDI_EVENT_VM_INIT */ /* no additional fields */ } u; } JVMDI_Event;
個々のイベントの詳細について、このあと説明します。
typedef struct { jthread thread; jclass clazz; jmethodID method; jlocation location; } JVMDI_single_step_event_data;
ステップ実行イベントを利用すると、JVMDI クライアントは、VM で可能な最小の単位でスレッドの実行を追跡できます。ステップ実行イベントは、スレッドが新しい位置に達するたびに生成されます。通常、ステップ実行イベントは、仮想マシンの仕様に定義されている VM の命令の 1 つが完了したことを表します。しかし、実装によっては、位置の定義方法が異なる場合があります。いずれにしても、イベント構造体の clazz
、method
、および location
フィールドによって現在の位置を一意に識別できるため、この情報があればソースファイルと行番号へのマッピングが可能です。
ネイティブメソッド内からは、ステップ実行イベントは生成されません。
ステップ実行イベントは、デフォルトでは無効になっています。SetEventNotificationMode
を呼び出すことにより、スレッドに対して有効にできます。
typedef struct { jthread thread; jclass clazz; jmethodID method; jlocation location; } JVMDI_breakpoint_event_data;
ブレークポイントイベントは、SetBreakpoint を使ってブレークポイントとして指定された位置にスレッドが達した時点で生成されます。イベント構造体の clazz
、method
、および location
フィールドによって現在の位置を一意に識別できるため、この情報があればソースファイルと行番号へのマッピングが可能です。
ブレークポイントのレポートは、通常は SetEventNotificationMode
の呼び出しによって有効または無効にできます。デフォルトでは、有効になっています。無効になっている場合、設定されているブレークポイントは無視されます。
/* kind = JVMDI_EVENT_FIELD_ACCESS */ typedef struct { jthread thread; jclass clazz; jmethodID method; jlocation location; jclass field_clazz; jobject object; jfieldID field; } JVMDI_field_access_event_data; /* kind = JVMDI_EVENT_FIELD_MODIFICATION */ typedef struct { jthread thread; jclass clazz; jmethodID method; jlocation location; jclass field_clazz; jobject object; jfieldID field; char signature_type; jvalue new_value; } JVMDI_field_modification_event_data;
フィールドイベントは、SetFieldAccessWatch
または SetFieldModificationWatch
を使ってウォッチポイントとして指定されたフィールドを、スレッドがアクセスまたは変更した時点で生成されます。イベント構造体の clazz
、method
、および location
フィールドは現在の位置を一意に識別するため、この情報があればソースファイルと行番号へのマッピングが可能です。field_clazz
および field
フィールドは、アクセスまたは変更されるフィールドを一意に識別します。object
は、フィールドがインスタンスフィールドである場合に、そのフィールドを含んでいるオブジェクトを識別します。そうでない場合は、null です。
フィールドウォッチポイントのレポートは、通常、SetEventNotificationMode
の呼び出しによって有効または無効にできます。デフォルトでは、有効になっています。無効になっている場合、設定されているウォッチポイントは無視されます。
typedef struct { jthread thread; jclass clazz; jmethodID method; jframeID frame; } JVMDI_frame_event_data;
メソッドエントリイベントは、Java プログラミング言語メソッドまたはネイティブメソッドに入る時点で生成されます。メソッド終了イベントは、Java プログラミング言語メソッドまたはネイティブメソッドから出る時点で生成されます。フレームポップイベントは、NotifyFramePop
の呼び出しで指定された単一のフレーム内の単一のメソッドから出る時点で生成されます呼び出し側に例外をスローしてメソッドが終了する場合は、メソッド終了イベントもフレームポップイベントも生成されません。JVMDI クライアントは、そのような事態の発生を、例外キャッチイベントを監視することによって確認できます。
clazz
および method
フィールドは、入るメソッドまたは出るメソッドを一意に識別します。frame
フィールドは、メソッドのスタックフレームへのアクセスを提供します。メソッドに入る時点で、GetFrameLocation
によりレポートされる位置は、メソッド内の初期実行可能ファイルの位置を識別します。メソッドを出る時点、またはフレームポップの時点で、GetFrameLocation
によりレポートされる位置は、復帰しようとしているメソッド内の復帰直前の実行可能位置を識別します。
メソッドエントリおよびメソッド終了イベントは、デフォルトでは無効になっており、SetEventNotificationMode
を呼び出すことによって有効にできます。フレームポップイベントは、デフォルトでは有効になっており、同様の呼び出しで無効にできます。
typedef struct { jthread thread; jclass clazz; jmethodID method; jlocation location; jobject exception; jclass catch_clazz; jmethodID catch_method; jlocation catch_location; } JVMDI_exception_event_data;
例外イベントは、Java プログラミング言語メソッド内で例外が最初に検出された時点で生成されます。例外は、Java プログラミング言語メソッドによってスローされる場合と、ネイティブメソッドによってスローされる場合があります。ネイティブメソッドによってスローされる場合は、その例外が Java プログラミング言語メソッドによって最初に認識されるまで、このイベントは生成されません。例外がネイティブメソッド内で生成されて解除された場合 (つまり、Java プログラミング言語コードからは認識されない場合) は、例外イベントは生成されません。
イベント構造体の clazz
、method
、および location
フィールドにより、例外が検出された現在位置を一意に識別できるため、この情報があればソースファイルと行番号へのマッピングが可能です。exception
フィールドは、スローされた例外オブジェクトを認識します。catch_clazz
、catch_method
、および catch_location
は、スローされた例外を処理する catch 節の位置を識別します (そのような節が存在する場合)。そのような catch 節がない場合、それらの各フィールドは 0 に設定されます。スレッドがこの catch 節に到達するという保証はありません。呼び出しスタック上で例外スローの位置と catch 節の間にネイティブメソッドがある場合、それらのネイティブメソッドのどれかによって例外がリセットされる可能性があるからです。JVMDI クライアントは、そのような事態の発生を、例外キャッチイベントを監視することによって確認できます。
例外イベントはデフォルトでは有効になっており、SetEventNotificationMode
を呼び出すことによって無効にできます。
typedef struct { jthread thread; jclass clazz; jmethodID method; jlocation location; jobject exception; } JVMDI_exception_catch_event_data;
例外キャッチイベントは、スローされた例外がキャッチされた時点で生成されます。例外が Java プログラミング言語メソッド内でキャッチされた場合は、catch 節に到達した時点でこのイベントが生成されます。例外がネイティブメソッド内でキャッチされた場合は、Java プログラミング言語メソッドに制御が戻った直後にこのイベントが生成されます。例外キャッチイベントは、Java プログラミング言語メソッド内でスローが検出された例外に対して生成されます。
イベント構造体の clazz
、method
、および location
フィールドによって現在の位置を一意に識別できるため、この情報があればソースファイルと行番号へのマッピングが可能です。Java プログラミング言語メソッド内でキャッチされた例外の場合は、exception
オブジェクトが例外オブジェクトを識別します。ネイティブメソッド内でキャッチされた例外は、例外のキャッチがレポートされた時点で入手可能とは限らないので、exception
フィールドは null に設定されます。
例外キャッチイベントは、デフォルトでは無効になっており、SetEventNotificationMode
を呼び出すことによって有効にできます。
typedef struct { jobject object; jint key; } JVMDI_user_event_data;
ユーザイベントのデータ構造体にあるユーザ定義イベントおよびフィールドの意味は、JVMDI の個々の実装によって定義されます。
typedef struct { jthread thread; } JVMDI_thread_change_event_data;
スレッド開始イベントは、新しいスレッドによって、スレッドの初期メソッドが実行される前に、生成されます。スレッド終了イベントは、停止しようとしているスレッドによって、スレッドの初期メソッドの実行完了後に、生成されます。スレッド開始イベントが生成される前、およびスレッド終了イベントが生成されたあとに、GetAllThreads
によって返される配列に、そのスレッドが含まれている可能性があります。また、スレッド開始イベントの前に、そのスレッドについて他のイベントが生成される可能性があります。しかし、スレッド終了イベントの後に、そのスレッドについて他のイベントが生成されることはありません。
スレッドイベントは、デフォルトでは有効になっており、SetEventNotificationMode
を呼び出すことによって無効にできます。
typedef struct { jthread thread; jclass clazz; } JVMDI_class_event_data;
クラスイベントは、特定のクラスのステータスが変化したことを示します。
クラスロードイベントは、クラスが最初にロードされた時点で生成されます。特定のスレッドによりクラスロードイベントが生成される順序は、そのスレッド内でクラスがロードされる順序と一致することが保証されています。非プリミティブ型の配列には、クラスロードイベントがあります。プリミティブ型の配列には、クラスロードイベントがありません (VM の初期化の時点でロードされたと見なされる)。プリミティブクラス (たとえば、java.lang.Integer.TYPE) には、クラスロードイベントがありません。
クラス準備イベントは、クラスの準備が完了した時点で生成されます。この時点では、クラスのフィールド、メソッド、および実装されたインタフェースが利用可能ですが、クラスのコードはまだ何も実行されていません。配列クラスは、フィールドやメソッドを持つことがないため、配列クラスについてクラス準備イベントが生成されることはありません。プリミティブクラス (たとえば、java.lang.Integer.TYPE) についても、クラス準備イベントは生成されません。
クラスアンロードイベントは、クラスがアンロードされる直前に生成されます。クラスアンロードイベントはガベージコレクション中に発生するため、特に慎重に処理しなければなりません。ガベージコレクタが多くのロックを保持し、ほかのスレッドをすべて中断しているので、イベントハンドラはロックを獲得する機能を使えないかもしれません。クラスアンロードのイベントハンドラでは、あとで処理するべき情報をキューに入れるなどして、処理をできるだけ行わないようにする必要があります。
クラスイベントは、デフォルトでは有効になっており、SetEventNotificationMode
を呼び出すことによって無効にできます。
VM 初期化イベントは、VM の初期化の完了を示します。このイベントが生成されたあとは、JVMDI クライアントは任意の JNI または JVMDI 関数を自由に呼び出すことができます。VM 初期化イベントは、その前に他のイベントが生成されたり、他のイベントと同時に生成されたりすることがあります。そのうち、VM 初期化イベントの前の生成されるイベントについては、VM の初期化がまだ完了していないので、特に注意して処理する必要があります。メインアプリケーションスレッドのスレッド開始イベントは、VM 初期化イベントのハンドラが復帰するまでは発生しないことが保証されています。
現在位置がメソッドのエントリポイントである場合は、同一スレッド内の現在位置で発生した他のすべてのイベントより前に、JVMDI_EVENT_METHOD_ENTRY
イベントがレポートされます。
現在位置で例外のキャッチが検出された場合 (catch 節の先頭の場合か、未処理の例外を解除したネイティブメソッドが復帰した位置の場合) は、同一スレッド内の現在位置で発生した他のすべてのイベントより前に、JVMDI_EVENT_EXCEPTION_CATCH
イベントがレポートされます。
JVMDI_EVENT_SINGLE_STEP
イベントまたは JVMDI_EVENT_BREAKPOINT
イベントが現在位置でトリガされる場合、そのイベントは、現在位置のコードが実行される直前に発生するものと定義されています。これらのイベントは、同一スレッド内の現在位置にあるコードの実行によりトリガされるどのイベント (特に、JVMDI_EVENT_EXCEPTION
、JVMDI_EVENT_FIELD_ACCESS
、および JVMDI_EVENT_FIELD_MODIFICATION
) よりも前にレポートされます。ステップイベントとブレークポイントイベントの両方が同一のスレッドおよび場所でトリガされた場合は、ステップイベントがブレークポイントイベントより前にレポートされます。
現在位置がメソッドの終了ポイント (つまり、呼び出し側に復帰する前の最後の位置) である場合、 JVMDI_EVENT_METHOD_EXIT
イベントおよび JVMDI_EVENT_FRAME_POP
イベント (要求されている場合) は、同一スレッド内の現在位置で発生する他のすべてのイベントのあとにレポートされます。これら 2 つのイベントについては、レポートされる順序は特に指定されていません。
同じ位置で発生するイベントは、同じスレッド内の同じ位置での JVMDI クライアントによる処理中にトリガされることがあります。その種のイベント (タイプ y) が、タイプ x のイベントの処理中にトリガされたとします。前述の説明にある順序によると x は y より前にレポートされるという場合は、同じ位置で発生したイベント y が、現在のスレッドおよび位置についてレポートされます。逆に、x が y より前にレポートされないという場合は、イベント y は、現在のスレッドおよび位置についてレポートされません。たとえば、JVMDI_EVENT_SINGLE_STEP
の処理中に現在位置にブレークポイントが設定された場合は、スレッドが現在位置を離れる前に、そのブレークポイントがレポートされます。
以下のイベントは、他のイベントと同じ位置で発生したと見なされることがありません。
JVMDI_EVENT_USER_DEFINED
JVMDI_EVENT_VM_INIT
JVMDI_EVENT_VM_DEATH
JVMDI_EVENT_THREAD_START
JVMDI_EVENT_THREAD_END
JVMDI_EVENT_CLASS_LOAD
JVMDI_EVENT_CLASS_UNLOAD
JVMDI_EVENT_CLASS_PREPARE
VM の起動時に JVMDI クライアントを初期ロードする方法は、VM によって異なります。以下の説明は、Windows 版および Solaris 版 Sun J2SE 1.2 の旧来の VM に適用されます。
JVMDI クライアントを適切にロードして実行するには、VM の起動時に次のコマンド行引数が必要です。
この関数は、起動時に VM によって呼び出される。たとえば、オプションJNIEXPORT jint JNICALL JVM_OnLoad(JavaVM *vm, char *options, void *reserved)
-Xrunfoo:opt1,opt2
が指定された場合、VM は、Windows では共用ライブラリ foo.dll を、Solaris では共用ライブラリ libfoo.so をロードしようとする。次に、VM は、JVM_OnLoad
を探し、「opt1,opt2」を第 2 引数に指定して呼び出そうとする。この呼び出しの時点で VM はまだ初期化されていないので、JVM_OnLoad 内で安全に実行できる処理はごく限られている。VM が安全に実行できるのは、オプションの処理や、SetEventHook を使ってイベントフックを設定する処理である。VM 初期化イベントについてイベントフックが呼び出されたあと、JVMDI クライアントは、自身の初期化を完了することができる
Copyright © 1996-2004 Sun Microsystems, Inc.All Rights Reserved.
コメントの送付先: java-debugger@sun.com. |
|