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.
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:
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.
Specify allocation and deallocation functions used by JVMDI. JVMDI will calltypedef 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);
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
.
AllocateJNIEXPORT jvmdiError JNICALL JVMDI_Allocate(JNIEnv *env, jlong size, jbyte** memPtr);
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.
DeallocateJNIEXPORT jvmdiError JNICALL JVMDI_Deallocate(JNIEnv *env, jbyte* mem);
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.
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
.
The function returns one of the following error codes:
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()
orJVM_Sleep()
.)JVMDI_THREAD_STATUS_MONITOR
- Synchronization block.
JVMDI_THREAD_STATUS_WAIT
- Thread waiting. (
Thread.wait()
orJVM_MonitorWait()
.)JVMDI_THREAD_STATUS_SUSPENDED
- Thread suspended. (
Thread.suspend()
,JVM_Suspend()
, orJVMDI_Suspend()
.)JVMDI_THREAD_STATUS_BREAK
- Thread at breakpoint.
JVMDI_ERROR_NONE
- No error.
JVMDI_ERROR_INVALID_THREAD
thread
was invalid.JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
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 suspendedJNIEXPORT jvmdiError JNICALL JVMDI_ResumeThread(JNIEnv *env, jthread thread);
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.
IfJNIEXPORT jvmdiError JNICALL JVMDI_SetSingleStep(JNIEnv *env, jthread thread, jboolean shouldStep);
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.
Get theJNIEXPORT jvmdiError JNICALL JVMDI_GetCurrentFrame(JNIEnv *env, jthread thread, jframeID *framePtr);
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.
ForJNIEXPORT jvmdiError JNICALL JVMDI_GetCallerFrame(JNIEnv *env, jframeID called, jframeID *framePtr);
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 information identifying the active method inJNIEXPORT jvmdiError JNICALL JVMDI_GetFrameMethod(JNIEnv *env, jframeID frame, jclass *classPtr, jmethodID *methodPtr);
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.
ForJNIEXPORT jvmdiError JNICALL JVMDI_GetFrameLocation(JNIEnv *env, jframeID frame, jclass *classPtr, jmethodID *methodPtr, jlocation *locationPtr);
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.
WhenJNIEXPORT jvmdiError JNICALL JVMDI_NotifyFramePop(JNIEnv *env, jframeID frame);
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.
Get the value of the local variable indicated byJNIEXPORT 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);
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.
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.
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.
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 in this virtual machine.JNIEXPORT jvmdiError JNICALL JVMDI_ClearAllBreakpoints(JNIEnv *env);
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.
For the class indicated byJNIEXPORT jvmdiError JNICALL JVMDI_GetClassName(JNIEnv *env, jclass clazz, char **namePtr);
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.
For the class indicated byJNIEXPORT jvmdiError JNICALL JVMDI_GetSourcePath(JNIEnv *env, jclass clazz, char **sourcePathPtr);
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.
For the class indicated byJNIEXPORT jvmdiError JNICALL JVMDI_GetClassModifiers(JNIEnv *env, jclass clazz, jint *modifiersPtr);
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
.
For the class indicated byJNIEXPORT jvmdiError JNICALL JVMDI_GetClassMethods(JNIEnv *env, jclass clazz, jint *methodCountPtr, jmethodID **methodsPtr);
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.
For the class indicated byJNIEXPORT jvmdiError JNICALL JVMDI_GetClassFields(JNIEnv *env, jclass clazz, jint *fieldCountPtr, jfieldID **fieldsPtr);
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.
For the class indicated byJVMDI_GetImplementedInterfaces(JNIEnv *env, jclass clazz, jint *interfaceCountPtr, jclass **interfacesPtr);
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.
For the class indicated byJNIEXPORT jvmdiError JNICALL JVMDI_IsInterface(JNIEnv *env, jclass clazz, jboolean *isInterfacePtr);
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
.
For the class indicated byJNIEXPORT jvmdiError JNICALL JVMDI_IsInterface(JNIEnv *env, jclass clazz, jboolean *isArrayPtr);
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
.
For the class indicated byJNIEXPORT jvmdiError JNICALL JVMDI_ClassLoader(JNIEnv *env, jclass clazz, jobject *classloaderPtr);
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
.
For the field indicated byJNIEXPORT jvmdiError JNICALL JVMDI_GetFieldName(JNIEnv *env, jclass clazz, jfieldID field, char **namePtr, char **signaturePtr);
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.
For the field indicated byJNIEXPORT jvmdiError JNICALL JVMDI_GetFieldDeclaringClass(JNIEnv *env, jclass clazz, jfieldID field, jclass *declaringClassPtr);
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.
For the field indicated byJNIEXPORT jvmdiError JNICALL JVMDI_GetFieldModifiers(JNIEnv *env, jclass clazz, jfieldID field, jint *modifiersPtr);
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
.
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.
For the method indicated byJNIEXPORT jvmdiError JNICALL JVMDI_GetMethodDeclaringClass(JNIEnv *env, jclass clazz, jmethodID method, jclass *declaringClassPtr);
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.
For the method indicated byJNIEXPORT jvmdiError JNICALL JVMDI_GetMethodModifiers(JNIEnv *env, jclass clazz, jmethodID method, jint *modifiersPtr);
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
.
For the method indicated byJNIEXPORT jvmdiError JNICALL JVMDI_GetMaxStack(JNIEnv *env, jclass clazz, jmethodID method, jint *maxPtr);
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
.
For the method indicated byJNIEXPORT jvmdiError JNICALL JVMDI_GetMaxLocals(JNIEnv *env, jclass clazz, jmethodID method, jint *maxPtr);
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
.
For the method indicated byJNIEXPORT jvmdiError JNICALL JVMDI_GetArgumentsSize(JNIEnv *env, jclass clazz, jmethodID method, jint *sizePtr);
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
.
For the method indicated byJNIEXPORT jvmdiError JNICALL JVMDI_GetLineNumberTable(JNIEnv *env, jclass clazz, jmethodID method, jint *entryCountPtr, JVMDI_line_number_entry **tablePtr);
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.
For the method indicated byJNIEXPORT jvmdiError JNICALL JVMDI_GetMethodLocation(JNIEnv *env, jclass clazz, jmethodID method, jlocation *startLocationPtr, jlocation *endLocationPtr);
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.
For the method indicated byJNIEXPORT jvmdiError JNICALL JVMDI_GetLocalVariableTable(JNIEnv *env, jclass clazz, jmethodID method, jint *entryCountPtr, JVMDI_local_variable_entry **tablePtr);
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.
For the method indicated byJNIEXPORT jvmdiError JNICALL JVMDI_GetExceptionHandlerTable(JNIEnv *env, jclass clazz, jmethodID method, jint *entryCountPtr, JVMDI_exception_handler_entry **tablePtr)
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.
For the method indicated byJNIEXPORT jvmdiError JNICALL JVMDI_GetThrownExceptions(JNIEnv *env, jclass clazz, jmethodID method, jint *exceptionCountPtr, jclass **exceptionsPtr);
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.
For the method indicated byJNIEXPORT jvmdiError JNICALL JVMDI_GetBytecodes(JNIEnv *env, jclass clazz, jmethodID method, jint *bytecodeCountPtr, jbyte **bytecodesPtr);
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.
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.
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.
Thetypedef 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;
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.
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
The function returns one of the following error codes:
The function always returns classCountPtr, and the array itself via
classesPtr
.
You must deallocate the array using
JVMDI_Deallocate()
.
JVMDI_ERROR_NONE
JVMDI_ERROR_NULL_POINTER
JVMDI_ERROR_OUT_OF_MEMORY
Get Version Number
Return the JVMDI version via
JNIEXPORT jvmdiError JNICALL
JVMDI_GetVersionNumber(JNIEnv *env, jint *versionPtr);
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.
JVMDI_ERROR_NONE
.