Java Virtual Machine Debugger Interface Reference

The Java Virtual Machine Debugger Interface (JVMDI) is a low-level debugging API. JVMDI uses the Java Native Interface (JNI). Each debugger thread begins life as a Java thread, but must call native methods to issue JVMDI and JNI calls. Every native method gets a JNIEnv pointer. The JNIEnv pointer is specific to the thread that called the native method, and is passed to all JVMDI functions.


Using JVMDI Functions

For function and constant definitions, add

        #include <jvmdi.h>
to your source code.

JVMDI functions always return a jvmdiError value indicating return status. Some functions can return additional values through pointers provided by the calling function. In some cases, JVMDI functions allocate memory that your program must explicitly deallocate. This is indicated in the individual JVMDI function descriptions.

JVMDI Functions fall into these categories:


Memory Management

Many JVMDI functions require memory allocation external to the Java virtual machine. By default, memory comes from platform-specific allocation functions, such as a malloc(). A system built on JVMDI can provide its own memory allocation scheme. This might be useful, for example, to allocate memory in advance, so a debugger can continue to function in low-memory situations.


Set Allocation Hooks

typedef jvmdiError 
(*JVMDI_AllocHook)(JNIEnv *env, jlong size, jbyte** memPtr);

typedef jvmdiError 
(*JVMDI_DeallocHook)(JNIEnv *env, jbyte* mem);

JNIEXPORT jvmdiError JNICALL
JVMDI_SetAllocationHooks(JNIEnv *env, 
                   JVMDI_AllocHook ahook, JVMDI_DeallocHook dhook);

Specify allocation and deallocation functions used by JVMDI. JVMDI will call ahook() to allocate memory, dhook to deallocate memory. This overrides JVMDI's default memory allocator. To restore the default allocator, call JVMDI_SetAllocationHooks() with ahook and dhook set to NULL.

The ahook function should look in size for the number of bytes to allocate and return them via memPtr. The function should return JVMDI_ERROR_NULL_POINTER if passed null pointers, JVMDI_ERROR_OUT_OF_MEMORY if it cannot honor a memory request, and JVMDI_ERROR_NONE otherwise.

The dhook function should look in buffer for the memory to be deallocated. The function should return JVMDI_ERROR_NULL_POINTER if passed null pointers, JVMDI_ERROR_NONE otherwise.

JVMDI_SetAllocationHooks() always returns JVMDI_ERROR_NONE.


Allocate Memory

JNIEXPORT jvmdiError JNICALL
JVMDI_Allocate(JNIEnv *env, jlong size, jbyte** memPtr);
Allocate size bytes using the JVMDI allocator. A pointer to the allocated memory is returned via memPtr.

The function returns one of the following error codes:

JVMDI_ERROR_NONE
No error.

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_OUT_OF_MEMORY
Not enough memory to complete the operation.

Deallocate Memory

JNIEXPORT jvmdiError JNICALL
JVMDI_Deallocate(JNIEnv *env, jbyte* mem);
Deallocate mem using the JVMDI allocator.

The function returns one of the following error codes:

JVMDI_ERROR_NONE
No error.

JVMDI_ERROR_NULL_POINTER
Invalid pointer.


Thread Execution Functions


Get Thread Status

JNIEXPORT jvmdiError JNICALL
JVMDI_GetThreadStatus(JNIEnv *env, jthread thread, jint *statusPtr);

Get status of thread. The function returns one of the following values via statusPtr.

JVMDI_THREAD_STATUS_UNKNOWN
Status unknown.

JVMDI_THREAD_STATUS_ZOMBIE
Thread is waiting to die.

JVMDI_THREAD_STATUS_RUNNING
Thread is runnable.

JVMDI_THREAD_STATUS_SLEEPING
Thread sleeping. (Thread.sleep() or JVM_Sleep().)

JVMDI_THREAD_STATUS_MONITOR
Synchronization block.

JVMDI_THREAD_STATUS_WAIT
Thread waiting. (Thread.wait() or JVM_MonitorWait().)

JVMDI_THREAD_STATUS_SUSPENDED
Thread suspended. (Thread.suspend(), JVM_Suspend(), or JVMDI_Suspend().)

JVMDI_THREAD_STATUS_BREAK
Thread at breakpoint.
The function returns one of the following error codes:
JVMDI_ERROR_NONE
No error.

JVMDI_ERROR_INVALID_THREAD
thread was invalid.

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

Suspend Thread

JNIEXPORT jvmdiError JNICALL
JVMDI_SuspendThread(JNIEnv *env, jthread thread); 

Suspend thread.

The function returns one of the following error codes:

JVMDI_ERROR_NONE
No error.

JVMDI_ERROR_INVALID_THREAD
thread was invalid.

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_THREAD_SUSPENDED
Thread already suspended.

JVMDI_ERROR_VM_DEAD
The virtual machine is no longer running.

Resume Thread

JNIEXPORT jvmdiError JNICALL
JVMDI_ResumeThread(JNIEnv *env, jthread thread);
Resume suspended thread.

The function returns one of the following error codes:

JVMDI_ERROR_NONE
No error.

JVMDI_ERROR_INVALID_THREAD
thread was invalid.

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_THREAD_NOT_SUSPENDED
Thread was not suspended.

JVMDI_ERROR_VM_DEAD
The virtual machine is no longer running.

Set Single-Step Mode

JNIEXPORT jvmdiError JNICALL
JVMDI_SetSingleStep(JNIEnv *env, jthread thread, jboolean shouldStep);
If shouldStep is true, put thread in single-step mode. Otherwise, put thread in normal mode. In single-step mode, a thread generates a JVMDI_EVENT_SINGLE_STEP event every time it executes a byte code. See Events.

The single-step/normal status of a thread can only be changed when it is suspended.

The function returns one of the following error codes:

JVMDI_ERROR_NONE
No error.

JVMDI_ERROR_INVALID_THREAD
thread was invalid.

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_THREAD_NOT_SUSPENDED
Thread was not suspended.

JVMDI_ERROR_VM_DEAD
The virtual machine is no longer running.


Stack Frame Access


Get Thread's Current Frame

JNIEXPORT jvmdiError JNICALL
JVMDI_GetCurrentFrame(JNIEnv *env, jthread thread, jframeID *framePtr);
Get the jframeID value for the current stack frame on thread and return via framePtr.

The thread must be suspended, and the return value remains valid only as long as thread remains suspended. The thread must be in a Java or JNI method.

The function returns one of the following error codes:

JVMDI_ERROR_NONE
No error.

JVMDI_ERROR_INVALID_THREAD
thread was invalid.

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_THREAD_NOT_SUSPENDED
Thread was not suspended.

JVMDI_ERROR_NO_MORE_FRAMES
The current frame is not in a Java or JNI method.

Get Caller Frame

JNIEXPORT jvmdiError JNICALL
JVMDI_GetCallerFrame(JNIEnv *env, jframeID called, jframeID *framePtr);
For frame, return the frame that called it via framePtr. Both called and the caller must be in a Java or JNI method.

The function returns one of the following error codes:

JVMDI_ERROR_NONE
No error.

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_FRAMEID
called is invalid.

JVMDI_ERROR_NO_MORE_FRAMES
The caller frame is not in a Java or JNI method.

Get Frame Method

JNIEXPORT jvmdiError JNICALL
JVMDI_GetFrameMethod(JNIEnv *env, jframeID frame, 
                   jclass *classPtr, jmethodID *methodPtr);
Get information identifying the active method in frame. Return the active method's class in the location via classPtr. Return the method itself via methodPtr.

The returned jclass Object is a Global Object. You must explicitly free the Global Object with the JNI function DeleteGlobalRef().

The function returns one of the following error codes:

JVMDI_ERROR_NONE
No error.

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_FRAMEID
frame is invalid.

JVMDI_ERROR_NO_MORE_FRAMES
The caller frame is not in a Java or JNI method.

JVMDI_ERROR_OUT_OF_MEMORY
The virtual machine could not allocate memory to complete the operation.

Frame Location

JNIEXPORT jvmdiError JNICALL
JVMDI_GetFrameLocation(JNIEnv *env, jframeID frame, 
                       jclass *classPtr, jmethodID *methodPtr,
                       jlocation *locationPtr);

For frame, return the location of the instruction currently executing. The current class is returned via classPtr, the current method via methodPtr, and the specific instruction location via locationPtr.

The function returns one of the following error codes:

JVMDI_ERROR_NONE
No error.

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_NATIVE_FRAME
frame is not a Java frame.

JVMDI_ERROR_INVALID_FRAMEID
frame is not a valid frame ID.

Notify Frame Pop

JNIEXPORT jvmdiError JNICALL
JVMDI_NotifyFramePop(JNIEnv *env, jframeID frame); 
When frame is popped from the stack, generate a JVMDI_EVENT_FRAME_POP event. See Events.

The function returns one of the following error codes:

JVMDI_ERROR_NONE
No error.

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_NATIVE_FRAME
frame is not a Java frame.

JVMDI_ERROR_INVALID_FRAMEID
frame is not a valid frame ID.


Local Variable Access


Get Local Variable

JNIEXPORT jvmdiError JNICALL
JVMDI_GetLocalObject(JNIEnv *env, jframeID frame, jint slot, 
                     jobject *valuePtr);

JNIEXPORT jvmdiError JNICALL
JVMDI_GetLocalInt(JNIEnv *env, jframeID frame, jint slot, 
                  jint *valuePtr);

JNIEXPORT jvmdiError JNICALL
JVMDI_GetLocalLong(JNIEnv *env, jframeID frame, jint slot, 
                   jlong *valuePtr);

JNIEXPORT jvmdiError JNICALL
JVMDI_GetLocalFloat(JNIEnv *env, jframeID frame, jint slot, 
                    jfloat *valuePtr);

JNIEXPORT jvmdiError JNICALL
JVMDI_GetLocalDouble(JNIEnv *env, jframeID frame, jint slot, 
                     jdouble *valuePtr);
Get the value of the local variable indicated by frame and slot. Place a copy of the value in the location indicated by valuePtr.

These functions create a new Global Object. You must explicitly free the Global Object with the JNI function DeleteGlobalRef().

The functions return one of the following error codes:

JVMDI_ERROR_NONE
No error.

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_FRAMEID
Invalid frame.

JVMDI_ERROR_INVALID_SLOT
Invalid slot.

JVMDI_ERROR_TYPE_MISMATCH
The variable is not an appropriate type for the function used.

Set Local Variable

JNIEXPORT jvmdiError JNICALL
JVMDI_SetLocalObject(JNIEnv *env, jframeID frame, jint slot, jobject value);

JNIEXPORT jvmdiError JNICALL
JVMDI_SetLocalInt(JNIEnv *env, jframeID frame, jint slot, jint value);

JNIEXPORT jvmdiError JNICALL
JVMDI_SetLocalFloat(JNIEnv *env, jframeID frame, jint slot, jfloat value);

JNIEXPORT jvmdiError JNICALL
JVMDI_SetLocalLong(JNIEnv *env, jframeID frame, jint slot, jlong value);

JNIEXPORT jvmdiError JNICALL
JVMDI_SetLocalDouble(JNIEnv *env, jframeID frame, jint slot, jdouble value);

Set the value of the local variable indicated by frame and slot to value.

The functions return one of the following error codes:

JVMDI_ERROR_NONE
No error.

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_FRAMEID
Invalid frame.

JVMDI_ERROR_INVALID_SLOT
Invalid slot.

JVMDI_ERROR_TYPE_MISMATCH
The variable is not an appropriate type for the function used.


Breakpoints


Set a Breakpoint

JNIEXPORT jvmdiError JNICALL
JVMDI_SetBreakpoint(JNIEnv *env, jclass clazz, 
                    jmethodID method, jlocation location);

Set a breakpoint at the instruction indicated by clazz, method, and location. An instruction can only have one breakpoint.

Whenever the designated instruction is about to be executed, a JVMDI_EVENT_BREAKPOINT event is generated. See Events.

The function returns one of the following error codes:

JVMDI_ERROR_NONE
No error.

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_METHODID
Invalid method.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

JVMDI_ERROR_INVALID_LOCATION
Invalid location.

JVMDI_ERROR_DUPLICATE_BREAKPOINT
The designated bytecode already has a breakpoint.

JVMDI_ERROR_VM_DEAD
The virtual machine is dead.

JVMDI_ERROR_OUT_OF_MEMORY
The virtual machine could not allocate memory to complete the operation.

Clear a Breakpoint

JNIEXPORT jvmdiError JNICALL
JVMDI_ClearBreakpoint(JNIEnv *env, jclass clazz, 
                      jmethodID method, jlocation location);

Clear the breakpoint at the bytecode indicated by clazz, method, and location.

The function returns one of the following error codes:

JVMDI_ERROR_NONE
No error.

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_METHODID
Invalid method.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

JVMDI_ERROR_INVALID_LOCATION
Invalid location.

JVMDI_ERROR_NO_SUCH_BREAKPOINT
There's no breakpoint at the designated bytecode.

JVMDI_ERROR_VM_DEAD
The virtual machine is dead.

Clear All Breakpoints

JNIEXPORT jvmdiError JNICALL
JVMDI_ClearAllBreakpoints(JNIEnv *env);
Clear all breakpoints in this virtual machine.

The function returns one of the following error codes:

JVMDI_ERROR_NONE
No error.

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_VM_DEAD
The virtual machine is dead.


Class Information


Class Name

JNIEXPORT jvmdiError JNICALL
JVMDI_GetClassName(JNIEnv *env, jclass clazz, char **namePtr);
For the class indicated by clazz, return the class name via namePtr. The return value is a UTF8 string.

The function returns one of the following error codes:

JVMDI_ERROR_NONE
No error.

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

JVMDI_ERROR_OUT_OF_MEMORY
The virtual machine could not allocate memory to complete the operation.

Source Path

JNIEXPORT jvmdiError JNICALL
JVMDI_GetSourcePath(JNIEnv *env, jclass clazz, char **sourcePathPtr);
For the class indicated by clazz, return the source path via sourcePathPtr. The return value is a UTF8 string.

The function returns one of the following error codes:

JVMDI_ERROR_NONE
No error.

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

JVMDI_ERROR_OUT_OF_MEMORY
The virtual machine could not allocate memory to complete the operation.

JVMDI_ERROR_ABSENT_INFORMATION
Class information does not include a source path.

Class Access Flags

JNIEXPORT jvmdiError JNICALL
JVMDI_GetClassModifiers(JNIEnv *env, jclass clazz, jint *modifiersPtr);
For the class indicated by clazz, return the access flags via modifiersPtr. Access flags are defined in the Java virtual machine specification.

The function returns one of the following error codes:

JVMDI_ERROR_NONE
No error.

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

Class Methods

JNIEXPORT jvmdiError JNICALL
JVMDI_GetClassMethods(JNIEnv *env, jclass clazz, 
                      jint *methodCountPtr, jmethodID **methodsPtr);
For the class indicated by clazz, return a count of methods and constructors via methodCountPtr and a list of method IDs via methodsPtr. The JVMDI allocator provides memory for the list. You must deallocate the list using JVMDI_Deallocate().

The function returns one of the following error codes:

JVMDI_ERROR_NONE
No error.

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

JVMDI_ERROR_OUT_OF_MEMORY
The virtual machine could not allocate memory to complete the operation.

Class Fields

JNIEXPORT jvmdiError JNICALL
JVMDI_GetClassFields(JNIEnv *env, jclass clazz, 
                     jint *fieldCountPtr, jfieldID **fieldsPtr);
For the class indicated by clazz, return a count of fields via fieldCountPtr and a list of field IDs via fieldsPtr. The JVMDI allocator provides space for the list. You must deallocate the list using JVMDI_Deallocate().

The function returns one of the following error codes:

JVMDI_ERROR_NONE
No error.

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

JVMDI_ERROR_OUT_OF_MEMORY
The virtual machine could not allocate memory to complete the operation.

Implemented Interfaces

JVMDI_GetImplementedInterfaces(JNIEnv *env, jclass clazz,
                               jint *interfaceCountPtr, 
                               jclass **interfacesPtr);
For the class indicated by clazz, return a count of implemented interfaces via interfaceCountPtr and a list implemented interfaces via interfacesPtr. The JVMDI allocator provides space for the list. You must deallocate the list using JVMDI_Deallocate(). The jclass objects in the list are new Global Objects which you must free with the JNI function DeleteGlobalRef().

The function returns one of the following error codes:

JVMDI_ERROR_NONE
No error.

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

JVMDI_ERROR_OUT_OF_MEMORY
The virtual machine could not allocate memory to complete the operation.

Is an Interface

JNIEXPORT jvmdiError JNICALL
JVMDI_IsInterface(JNIEnv *env, jclass clazz, jboolean *isInterfacePtr);
For the class indicated by clazz, return a jboolean object. The jboolean is true if the "class" is actually an interface, false otherwise. The return value is a new Global Object which you must explicitly free with the JNI function DeleteGlobalRef().

The function returns one of the following error codes:

JVMDI_ERROR_NONE
No error.

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

Is an Array

JNIEXPORT jvmdiError JNICALL
JVMDI_IsInterface(JNIEnv *env, jclass clazz, jboolean *isArrayPtr);
For the class indicated by clazz, return a jboolean object. The jboolean is true if the class is an array, false otherwise. The return value is a new Global Object which you must explicitly free with the JNI function DeleteGlobalRef().

The function returns one of the following error codes:

JVMDI_ERROR_NONE
No error.

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

Class Loader

JNIEXPORT jvmdiError JNICALL
JVMDI_ClassLoader(JNIEnv *env, jclass clazz, jobject *classloaderPtr);
For the class indicated by clazz, return via classloaderPtr a reference to the class loader for the class. If the class was not created by a class loader, classloaderPtr points to NULL.


Field Information


Field Name and Signature

JNIEXPORT jvmdiError JNICALL
JVMDI_GetFieldName(JNIEnv *env, jclass clazz, jfieldID field, 
                   char **namePtr, char **signaturePtr);
For the field indicated by clazz and field, return the field name via namePtr and field signature via signaturePtr. The two return values are new Global Objects which you must explicitly free with the JNI function DeleteGlobalRef().

The function returns one of the following error codes:

JVMDI_ERROR_NONE
No error.

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_FIELDID
Invalid field.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

JVMDI_ERROR_OUT_OF_MEMORY
The virtual machine could not allocate memory to complete the operation.

Field Declaring Class

JNIEXPORT jvmdiError JNICALL
JVMDI_GetFieldDeclaringClass(JNIEnv *env, jclass clazz, jfieldID field,
 			     jclass *declaringClassPtr);
For the field indicated by clazz and field return the class that defined it via declaringClassPtr. The return values is a new Global Object which you must explicitly free with the JNI function DeleteGlobalRef().

The function returns one of the following error codes:

JVMDI_ERROR_NONE
No error.

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_FIELDID
Invalid field.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

JVMDI_ERROR_OUT_OF_MEMORY
The virtual machine could not allocate memory to complete the operation.

Field Access Flags

JNIEXPORT jvmdiError JNICALL
JVMDI_GetFieldModifiers(JNIEnv *env, jclass clazz, jfieldID field,
                        jint *modifiersPtr);
For the field indicated by clazz and field return the access flags via modifiersPtr. Access flags are defined in the Java virtual machine specification.

The function returns one of the following error codes:

JVMDI_ERROR_NONE
No error.

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_FIELDID
Invalid method.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.


Method Information


Method Name and Signature

JNIEXPORT jvmdiError JNICALL
JVMDI_GetMethodName(JNIEnv *env, jclass clazz, jmethodID method, 
                    jstring *namePtr, jstring *signaturePtr);

For the method indicated by clazz and method, return the method name via namePtr and method signature via signaturePtr. The two return values are new Global Objects which you must explicitly free with the JNI function DeleteGlobalRef().

The function returns one of the following error codes:

JVMDI_ERROR_NONE
No error.

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_METHODID
Invalid method.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

JVMDI_ERROR_OUT_OF_MEMORY
The virtual machine could not allocate memory to complete the operation.

Method Declaring Class

JNIEXPORT jvmdiError JNICALL
JVMDI_GetMethodDeclaringClass(JNIEnv *env, jclass clazz, jmethodID method,
                              jclass *declaringClassPtr);
For the method indicated by clazz and method, return the Class that defined it via declaringClassPtr. The return value is new Global Object which you must explicitly free with the JNI function DeleteGlobalRef().

The function returns one of the following error codes:

JVMDI_ERROR_NONE
No error.

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_METHODID
Invalid method.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

JVMDI_ERROR_OUT_OF_MEMORY
The virtual machine could not allocate memory to complete the operation.

Method Access Flags

JNIEXPORT jvmdiError JNICALL
JVMDI_GetMethodModifiers(JNIEnv *env, jclass clazz, jmethodID method,
                         jint *modifiersPtr);
For the method indicated by clazz and method return the access flags via modifiersPtr. Access flags are defined in the Java virtual machine specification.

The function returns one of the following error codes:

JVMDI_ERROR_NONE
No error.

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_METHODID
Invalid method.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

Maximum Stack

JNIEXPORT jvmdiError JNICALL
JVMDI_GetMaxStack(JNIEnv *env, jclass clazz, jmethodID method,
                  jint *maxPtr);
For the method indicated by clazz and method, return via maxPtr the maximum number of words that can be on the stack while the method is executing.

The function returns one of the following error codes:

JVMDI_ERROR_NONE
No error.

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_METHODID
Invalid method.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

Locals Slots

JNIEXPORT jvmdiError JNICALL
JVMDI_GetMaxLocals(JNIEnv *env, jclass clazz, jmethodID method,
                  jint *maxPtr);
For the method indicated by clazz and method, return via maxPtr the number of local variable slots used by the whole method. Note that two-word arguments use two slots.

The function returns one of the following error codes:

JVMDI_ERROR_NONE
No error.

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_METHODID
Invalid method.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

Argument Slots

JNIEXPORT jvmdiError JNICALL
JVMDI_GetArgumentsSize(JNIEnv *env, jclass clazz, jmethodID method,
                  jint *sizePtr);
For the method indicated by clazz and method, return via maxPtr the number of local variable slots used by the method's arguments. Note that two-word arguments use two slots.

The function returns one of the following error codes:

JVMDI_ERROR_NONE
No error.

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_METHODID
Invalid method.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

Source Line Numbers

JNIEXPORT jvmdiError JNICALL
JVMDI_GetLineNumberTable(JNIEnv *env, jclass clazz, jmethodID method,
 			 jint *entryCountPtr, 
                         JVMDI_line_number_entry **tablePtr);
For the method indicated by clazz and method, return a table of source line number entries. The size of the table is returned via entryCountPtr and the table itself is returned via tablePtr. The JVMDI allocator provides space for the table. You must deallocate the table using JVMDI_Deallocate(). A table entry is an instance of the following structure:
typedef struct {
    jlocation start_location;
    jint line_number;
} JVMDI_line_number_entry;

The function returns one of the following error codes:

JVMDI_ERROR_NONE
No error.

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_METHODID
Invalid method.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

JVMDI_ERROR_OUT_OF_MEMORY
The virtual machine could not allocate memory to complete the operation.

JVMDI_ERROR_ABSENT_INFORMATION
Class information does not include line numbers.

Method Location

JNIEXPORT jvmdiError JNICALL
JVMDI_GetMethodLocation(JNIEnv *env, jclass clazz, jmethodID method,
                        jlocation *startLocationPtr, 
                        jlocation *endLocationPtr);
For the method indicated by clazz and method, return the beginning and ending addresses through startLocationPtr and endLocationPtr. In a conventional byte code indexing scheme, these values are always zero and the byte code count minus one. If location information is not available, both return values are -1.
JVMDI_ERROR_NONE
No error.

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_METHODID
Invalid method.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

JVMDI_ERROR_OUT_OF_MEMORY
The virtual machine could not allocate memory to complete the operation.

JVMDI_ERROR_ABSENT_INFORMATION
Class information does not include method sizes.

Local Variables

JNIEXPORT jvmdiError JNICALL
JVMDI_GetLocalVariableTable(JNIEnv *env, jclass clazz, jmethodID method,
                            jint *entryCountPtr, 
                            JVMDI_local_variable_entry **tablePtr);
For the method indicated by clazz and method, return a table of local variables. The size of the table is returned via entryCountPtr and the table itself is returned via tablePtr. The JVMDI allocator provides space for the table. You must deallocate the table using JVMDI_Deallocate(). A table entry has this structure:
typedef struct {
    jlocation start_location;   /* variable valid start_location */
    jint length;                /* upto start_location+length */ 
    char *name;                 /* name in UTF8 */
    char *signature;            /* type signature in UTF8 */
    jint slot;                  /* variable slot, see JVMDI_GetLocal*()  */
} JVMDI_local_variable_entry;

The function returns one of the following error codes:

JVMDI_ERROR_NONE
No error.

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_METHODID
Invalid method.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

JVMDI_ERROR_OUT_OF_MEMORY
The virtual machine could not allocate memory to complete the operation.

JVMDI_ERROR_ABSENT_INFORMATION
Class information does not include local variable information.

Exception Handlers

JNIEXPORT jvmdiError JNICALL
JVMDI_GetExceptionHandlerTable(JNIEnv *env, jclass clazz, jmethodID method,
                               jint *entryCountPtr, 
                               JVMDI_exception_handler_entry **tablePtr)
For the method indicated by clazz and method, return a table of exception handlers. The size of the table is returned via entryCountPtr and the table itself is returned via tablePtr. The JVMDI allocator provides space for the table. You must deallocate the table using JVMDI_Deallocate(). A table entry has this structure:
typedef struct {
    jlocation start_location;
    jlocation end_location;
    jlocation handler_location;
    jclass exception;           /* if null, all exceptions */
} JVMDI_exception_handler_entry;

The function returns one of the following error codes:

JVMDI_ERROR_NONE
No error.

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_METHODID
Invalid method.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

JVMDI_ERROR_OUT_OF_MEMORY
The virtual machine could not allocate memory to complete the operation.

JVMDI_ERROR_ABSENT_INFORMATION
Class information does not include local variable information.

Thrown Exceptions

JNIEXPORT jvmdiError JNICALL
JVMDI_GetThrownExceptions(JNIEnv *env, jclass clazz, jmethodID method,
                          jint *exceptionCountPtr, jclass **exceptionsPtr);
For the method indicated by clazz and method, return an array of exceptions the method might throw. The number of exception is returned via exceptionCountPtr. The exceptions array is returned via exceptionsPtr.

The function returns one of the following error codes:

JVMDI_ERROR_NONE
No error.

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_METHODID
Invalid method.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

JVMDI_ERROR_OUT_OF_MEMORY
The virtual machine could not allocate memory to complete the operation.

Get Bytecodes

JNIEXPORT jvmdiError JNICALL
JVMDI_GetBytecodes(JNIEnv *env, jclass clazz, jmethodID method,
                         jint *bytecodeCountPtr,
                         jbyte **bytecodesPtr);
For the method indicated by clazz and method, return the byte codes that implement the method. The number of bytecodes is returned via bytecodeCountPtr. The byte codes themselves are returned via bytecodesPtr. The JVMDI memory allocator provides memory for the byte code array. You must deallocate the table using JVMDI_Deallocate().

The function returns one of the following error codes:

JVMDI_ERROR_NONE
No error.

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

Is Method Native

JNIEXPORT jvmdiError JNICALL
JVMDI_IsMethodNative(JNIEnv *env, jclass clazz, jmethodID method, 
                    jboolean *isNativePtr);

For the method indicated by clazz and method, return a value indicating whether the method is native via isNativePtr

The function returns one of the following error codes:

JVMDI_ERROR_NONE
No error.

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_METHODID
Invalid method.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

JVMDI_ERROR_OUT_OF_MEMORY
The virtual machine could not allocate memory to complete the operation.


Events

To handle Events, designate a hook function with JVMDI_SetEventHook().

typedef void (*JVMDI_EventHook)(JNIEnv *env, JVMDI_Event *event);

JNIEXPORT jvmdiError JNICALL
JVMDI_SetEventHook(JNIEnv *env, JVMDI_EventHook hook);

If hook is a function pointer, that function is called whenever an Event is generated. If hook is NULL, any existing Event Hook is unset.

The JVMDI_Event data structure passed to the Event Hook describes the event.


typedef struct {
    jint kind;		/* the discriminant */

    union {
	struct { /* kind = JVMDI_EVENT_SINGLE_STEP */
            jthread thread;
            jclass clazz;
            jmethodID method;
            jlocation location;
        } single_step;
			
	struct { /* kind = JVMDI_EVENT_BREAKPOINT */
            jthread thread;
            jclass clazz;
            jmethodID method;
            jlocation location;
        } breakpoint;

	struct { /* kind = JVMDI_EVENT_FRAME_POP */
            jthread thread;
            jframeID frame;
        } frame_pop;

	struct { /* kind = JVMDI_EVENT_EXCEPTION */
            jthread thread;
            jclass clazz;
            jmethodID method;
            jlocation location;
            jobject exception;
            jclass catch_clazz;
            jmethodID catch_method;
            jlocation catch_location;
        } exception;

	struct { /* kind = JVMDI_EVENT_USER_DEFINED */
            jobject object;
            jint key;
        } user;
			
	struct { /* kind = JVMDI_EVENT_THREAD_END or */
	         /* JVMDI_EVENT_THREAD_START */
            jthread thread;
        } thread_change;
			
	struct { /* kind = JVMDI_EVENT_CLASS_LINK or */
	         /* JVMDI_EVENT_CLASS_UNLINK */
            jclass clazz;
        } link;
			
                 /* kind = JVMDI_EVENT_VM_DEATH */
                 /* no additional fields */		
    } u;
} JVMDI_Event;
The JVMDI_Event data structure is allocated locally and deallocated when the event hook function returns.

A thread that generates an event does not change its execution status. If an event should cause a thread to be suspended, then the event hook function should issue the Suspend.

The event hook function is called by the thread that generated the event. An event hook function should not create virtual machine objects or call virtual machine methods.


Miscellaneous Functions


Get Loaded Classes

JNIEXPORT jvmdiError JNICALL
JVMDI_GetLoadedClasses(JNIEnv *env, 
                       jint *classCountPtr, jclass **classesPtr);

Return an array of all classes loaded in the virtual machine. The number of classes in the array is returned via classCountPtr, and the array itself via classesPtr. You must deallocate the array using JVMDI_Deallocate().

The function returns one of the following error codes:

JVMDI_ERROR_NONE
No error.

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_OUT_OF_MEMORY
The virtual machine could not allocate memory to complete the operation.

Get Version Number

JNIEXPORT jvmdiError JNICALL
JVMDI_GetVersionNumber(JNIEnv *env, jint *versionPtr);
Return the JVMDI version via versionPtr The return value contains the Major Version Number in its high-order 16 bits and the Minor Version Number in its low-order 16 bits.

The function always returns JVMDI_ERROR_NONE.