![]() |
JavaTM Virtual Machine Debug Interface リファレンス |
はじめに
JVMDI の関数の利用
エラー
イベント
VM および JVMDI クライアントの起動
JVMDI は、双方向のインタフェースです。JVMDI クライアントは、知りたい状態の発生状況について、イベントを介して通知を受け取ることができます。JVMDI は、イベントに応答して、またはイベントから独立して、さまざまな関数を使ってアプリケーションへのクエリーおよび制御を行うことができます。
JVMDI クライアントは、デバッグされているアプリケーションと同じ Virtual Machine 上で実行され、ネイティブインタフェースを使って JVMDI にアクセスします。ネイティブのインプロセスインタフェースでは、デバッグ用ツール側への最小限の介入で、最大限の制御が可能です。通常、JVMDI クライアントは比較的コンパクトです。これらは、ターゲットアプリケーションの通常の実行を妨げることなく、デバッガの機能の大部分を実装する別のプロセスによって制御することが可能です。
JVMDI は、Java Platform Debugger Architecture 内の 1 つのレイヤを構成します。このアーキテクチャには、より高レベルのアウトプロセスデバッガインタフェースが含まれています。多くのデバッガツールには、JVMDI よりもこれらのより高レベルのインタフェースの方が適しています。Java Platform Debugger Architecture の詳細については、Java Developer Connection を参照してください。
関数および定数を定義する場合は、
#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
が呼び出された)。このビットが設定されると、statusPtr を介して返される状態は、一時停止する前にスレッドの状態を参照するJVMDI_SUSPEND_STATUS_BREAK
- スレッドはブレークポイントによって停止。このビットは、スレッドが現在のスレッドであるか、またはスレッドが一時停止中である場合にのみ設定される
JVMDI_ERROR_INVALID_THREAD
thread
が無効JVMDI_ERROR_NULL_POINTER
- ポインタが無効
jvmdiError GetAllThreads(jint *threadsCountPtr, jthread **threadsPtr)
実行中のすべてのスレッドを Virtual Machine に認識させます。VM に接続していないネイティブスレッドは、返される一覧に含まれません。
パラメータ:
この関数は、汎用エラー、または次のエラーのどれかを返します。
- threadsCountPtr
- 戻り値で実行中のスレッドの数を示す
- threadsPtr
- 戻り値で、実行中の各スレッドに 1 つずつ参照の配列を示す。配列内のスレッドは、JNI グローバル参照で、JNI 関数
DeleteGlobalRef
を使って明示的に解放する必要がある。返されるスレッドの配列は、Deallocate
を使って解放する必要がある
JVMDI_ERROR_NULL_POINTER
- ポインタが無効
jvmdiError SuspendThread(jthread thread)
指定されたスレッドを一時停止します。呼び出し中のスレッドが指定されている場合、この関数はほかのスレッドが ResumeThread
を呼び出すまで戻りません。
パラメータ:
- thread
- 一時停止にするスレッド
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_INVALID_THREAD
thread
が無効JVMDI_ERROR_THREAD_SUSPENDED
- スレッドはすでに停止中
jvmdiError ResumeThread(jthread thread)
一時停止中のスレッドの実行を再開します。SuspendThread
によって一時停止したスレッドの実行をすべて再開します。
パラメータ:
- thread
- 再開するスレッド
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_INVALID_THREAD
thread
が無効JVMDI_ERROR_THREAD_NOT_SUSPENDED
- スレッドは一時停止中ではない
JVMDI_ERROR_INVALID_TYPESTATE
- スレッドの状態が変更されたので矛盾している
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 構造体のフィールドには、所有するモニターの詳細が入ります。この関数を現在のスレッド以外のスレッドに対して呼び出す場合は、指定するスレッドを一時停止する必要があります。
この機能はオプションで、すべての Virtual Machine に実装しなければならないわけではありません。特定の Virtual Machine でサポートされている機能を知るには、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
を使ってオブジェクトのモニターに入るのを待っているか、オブジェクトのモニターを獲得し直すのを待っている場合は、そのオブジェクトを取得します。この関数を現在のスレッド以外のスレッドに対して呼び出す場合は、指定するスレッドを一時停止する必要があります。
この機能はオプションで、すべての Virtual Machine に実装しなければならないわけではありません。特定の Virtual Machine でサポートされている機能を知るには、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
特定のスレッドグループ内で作成されたスレッドおよびスレッドグループを取得します。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 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_OPAQUE_FRAME
frame
は Java フレームではないJVMDI_ERROR_INVALID_FRAMEID
frame
は有効なフレーム ID ではない
jvmdiError NotifyFramePop(jframeID frame);
frame
がスタックからポップされると、JVMDI_EVENT_FRAME_POP
イベントが生成されます。「イベント」を参照してください。
パラメータ:
- frame
- フレームのポップイベントが生成されるフレーム
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_NULL_POINTER
- ポインタが無効
JVMDI_ERROR_OPAQUE_FRAME
frame
は Java フレームではない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
- 変数のスロット番号
- value
- 変数の新しい値
この関数は、次のエラーコードのどれかを返します。
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
- 指定されたバイトコードにはブレークポイントが設定されていない
この Virtual Machine で設定されているブレークポイントをすべて解除します。jvmdiError ClearAllBreakpoints()
jvmdiError SetFieldAccessWatch(jclass clazz, jfieldID field)
clazz
および field
で指定されたフィールドへのアクセスが行われようとしているときに、JVMDI_EVENT_FIELD_ACCESS イベントを生成します。イベントは、ClearFieldAccessWatch を使ってキャンセルされるまで、フィールドの各アクセスに対して生成されます。Java 言語コードまたは JNI からのフィールドアクセスは監視され、ほかの方法で修正されたフィールドは監視されません。JVMDI ユーザは、ユーザ自身のフィールドアクセスによって監視が開始されることに注意してください。1 つのフィールドに対し、フィールドアクセスの監視を 1 つだけ設定できます。フィールドの修正はアクセスとはみなされません。 修正を監視するには、SetFieldModificationWatch を使います。
この機能はオプションで、すべての Virtual Machine に実装しなければならないわけではありません。特定の Virtual Machine でサポートされている機能を知るには、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 つだけ設定できます。
この機能はオプションで、すべての Virtual Machine に実装しなければならないわけではありません。特定の Virtual Machine でサポートされている機能を知るには、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 Virtual Machine 仕様で定義されています。
クラスが配列クラスの場合、その 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_PREAPRED
クラスオブジェクト参照が配列を指すかどうかを判定します。クラスが実際にインタフェースである場合、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 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 構造体のフィールドは、モニターの詳細で構成されます。モニターの状態に影響を与える可能性のある各スレッドは、一時停止されるか、または現在のスレッドである必要があります。
この機能はオプションで、すべての Virtual Machine に実装しなければならないわけではありません。特定の Virtual Machine でサポートされている機能を知るには、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 Virtual Machine 仕様で定義されています。
パラメータ:
- 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
を介してそのフィールドが合成であるかどうかを示す値を返します。合成フィールドはコンパイラによって生成されますが、元のソースコード内には存在しません。
この機能はオプションで、すべての Virtual Machine に実装しなければならないわけではありません。特定の Virtual Machine でサポートされている機能を知るには、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
により返します。このシグニチャーは、Java Virtual Machine 仕様ではメソッド記述子とも呼ばれている JNI シグニチャーです。 これは、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 Virtual Machine 仕様で定義されています。
パラメータ:
- 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; /* upto 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
- ポインタが無効
jvmdiError GetBytecodes(jclass clazz, jmethodID method, jint *bytecodeCountPtr, jbyte **bytecodesPtr)
clazz
と method
で指定されたメソッドを実装したバイトコードを返します。バイトコードの数が、bytecodeCountPtr
を介して返されます。バイトコード自体は、bytecodesPtr
を介して返されます。
この機能はオプションで、すべての Virtual Machine に実装しなければならないわけではありません。特定の Virtual Machine でサポートされている機能を知るには、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
を介してそのメソッドが合成であるかどうかを示す値を返します。合成メソッドはコンパイラによって生成されますが、元のソースコード内には存在しません。
この機能はオプションで、すべての Virtual Machine に実装しなければならないわけではありません。特定の Virtual Machine でサポートされている機能を知るには、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)
パラメータ:
- 名前
- モニターを識別する UTF-8 名
- monitorPtr
- 戻り値で、作成されたモニターを示す
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_NULL_POINTER
- ポインタが無効
raw モニターを破棄します。jvmdiError DestroyRawMonitor(JVMDI_RawMonitor monitor)
パラメータ:
- monitor
- モニター
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_NULL_POINTER
- ポインタが無効
raw モニターの排他的所有権を取得します。jvmdiError RawMonitorEnter(JVMDI_RawMonitor monitor)
パラメータ:
- monitor
- モニター
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_INVALID_MONITOR
- モニターが無効
raw モニターの排他的所有権を放棄します。jvmdiError RawMonitorExit(JVMDI_RawMonitor monitor)
パラメータ:
- monitor
- モニター
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_INVALID_MONITOR
- モニターが無効
raw モニターの通知を待ちます。jvmdiError RawMonitorWait(JVMDI_RawMonitor monitor, jlong millis)
パラメータ:
- monitor
- モニター
- millis
- ミリ秒単位のタイムアウト
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_INVALID_MONITOR
- モニターが無効
JVMDI_ERROR_NOT_MONITOR_OWNER
JVMDI_ERROR_INTERRUPT
raw モニターで待機中の単一のスレッドに通知します。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 の場合は、このイベントはグローバルに有効または無効になります。 それ以外の場合は、特定のスレッドに対して有効または無効になります。特定のスレッドに対してイベントが生成されるのは、イベントがスレッドレベルまたはグローバルレベルのいずれかで有効になっている場合です。
特定のイベントについての情報は、あとの項を参照してください。
次のイベントは、この関数を使ってスレッドレベルでは制御できません。
最初は、スレッドレベルで有効になっているイベントはありません。次のイベント以外のイベントは、グローバルレベルで有効になります。
パラメータ:
- mode
- JVMDI_ENABLE または JVMDI_DISABLE
- eventType
- 制御するイベント
- thread
- 制御するスレッド、またはすべてのスレッドの場合は null
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_INVALID_THREAD
thread
が無効JVMDI_ERROR_INVALID_EVENT_TYPE
eventType
の値が無効
jvmdiError GetLoadedClasses(jint *classCountPtr, jclass **classesPtr)
Virtual Machine にロードされている全クラスの配列を返します。 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 の場合は、この関数によって Virtual Machine 内にロードされたすべてのクラスが返されます。 classCountPtr
によって配列内のクラスの数が返され、classesPtr
によって配列自体が返されます。Deallocate()
を使って配列を解放する必要があります。
initiatingLoader
引数は NULL でなければなりません。システムクラスローダにより起動されたクラスのセットは、そのローダにより定義されたクラスのセットと同一です。このセットは、GetLoadedClasses を呼び出し、null クラスローダを使ってそれらのクラスを選択することにより決定できます。
パラメータ:
- initiatingLoader
- 起動クラスローダ
- classCountPtr
- 戻り値でクラスの数を示す
- classesPtr
- 戻り値で、各クラスに 1 つずつ参照の配列を示す。配列内のクラスは JNI グローバル参照で、JNI 関数
DeleteGlobalRef
を使って明示的に解放する必要がある。返されるクラス配列は、Deallocate
を使って解放する必要がある
この関数は、汎用エラー、または次のエラーのどれかを返します。
JVMDI_ERROR_NULL_POINTER
- ポインタが無効
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; } 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 クライアントは、アプリケーション内で発生する多くのイベントについての通知を受けることができます。
イベントを処理するには、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 で可能な限り細かくスレッドの実行を追跡できます。ステップ実行イベントは、スレッドが新しい位置に達する度に生成されます。通常、ステップ実行イベントは、Virtual Machine 仕様に定義されているように、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 節に到達するという保証はありません。呼び出しスタック上で throw の位置と catch 節の間に呼び出しスタック上のネイティブメソッドがある場合は、それらのネイティブメソッドの 1 つによって例外がリセットされる可能性があります。JVMDI クライアントは、この事態を例外キャッチイベントを監視することによって確認できます。
例外イベントはデフォルトでは有効になっており、SetEventNotificationMode
を呼び出すことによって無効にできます。
例外キャッチイベント (JVMDI_EVENT_EXCEPTION_CATCH)
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 によって異なります。以下の説明は、Sun の提供する、Windows 版および Solaris 版の旧来の 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 © 1998-1999 Sun Microsystems, Inc. All Rights Reserved.
コメントの送付先: java-debugger@java.sun.com |
![]() |