Java

JavaTM Virtual Machine Debug Interface Reference

Contents

Introduction
Using JVMDI Functions
Errors
Handling Events
Starting a VM with a JVMDI Client


Introduction

The JavaTM Virtual Machine Debug Interface (JVMDI) is a programming interface used by debuggers and other programming tools. It provides a way both to inspect the state and to control the execution of applications running in the JavaTM Virtual Machine.

JVMDI is a two-way interface. The JVMDI client can be notified of interesting occurrences through events. The JVMDI can query and control the application through many different functions, either in response to events or independent of them.

JVMDI clients run in the same virtual machine as the application being debugged and access JVMDI through a native interface. The native, in-process interface allows maximal control with minimal intrusion on the part of a debugging tool. Typically, JVMDI clients are relatively compact. They can be controlled by a separate process which implements the bulk of a debugger's function without interfering with the target application's normal execution.

JVMDI is the lowest layer within the Java Platform Debugger Architecture. This architecture also contains higher-level, out-of-process debugger interfaces. The higher-level interfaces are more appropriate than JVMDI for most debugging tools. For more information on the Java Platform Debugger Architecture, see the Java Platform Debugger Architecture documentation for this release and the Java Platform Debugger Architecture website.


Using JVMDI Functions

For function and constant definitions, add

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

Like Java Native Interface (JNI) functions, JVMDI functions are accessed through a function table. The JVMDI function table can be obtained through the JNI GetEnv function. For example, the following code obtains the function table for version 1 of the JVMDI.

        JVMDI_Interface_1 *jvmdi;
        ...
        (*jvm)->GetEnv(jvm, &jvmdi, JVMDI_VERSION_1);

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. Empty lists, arrays, sequences, etc are returned as allocated zero length arrays (not as NULL).

JVMDI functions identify objects with JNI references. References passed to JVMDI functions can be either global or local, but they must be strong references. All references returned by JVMDI functions are strong, global references.

In the event that the JVMDI function encounters an error (any return value other than JVMDI_ERROR_NONE) the values of memory referenced by argument pointers is undefined, but no memory will have been allocated and no global references will have been allocated.

JVMDI extends the data types defined by JNI with the following: jthread and jthreadGroup are subtypes of jobject, representing the corresponding objects; jframeID is a pointer type representing a single stack frame of a suspended or current thread (it is invalid upon the resumption of the thread); jlocation is a 64 bit unsigned value, representing a monotonically increasing executable position within a method; jvmdiError is a jint, discussed above.

JVMDI functions fall into these categories:


Memory Management

Many JVMDI functions require memory allocation. 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. Also, replacing the default memory allocation functions with debugger-specific functions can reduce the potential for deadlock on systems where malloc cannot be entered by a debugger thread while an application thread is suspended while executing inside a memory management function.


Set Allocation Hooks

jvmdiError
SetAllocationHooks(JVMDI_AllocHook ahook, JVMDI_DeallocHook dhook)

Set the functions which will perform allocation and deallocation. The hook functions are defined as follows.

typedef jvmdiError (*JVMDI_AllocHook)(jlong size, jbyte** memPtr)
typedef jvmdiError (*JVMDI_DeallocHook)(jbyte* buffer)

JVMDI will call ahook to allocate memory, dhook to deallocate memory. This overrides JVMDI's default memory allocator. To restore the default allocator, call 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.

Parameters:

ahook
the function to use for memory allocation, or NULL to revert to the default allocator.
dhook
the function to use for memory deallocation, or NULL to revert to the default deallocator.

SetAllocationHooks always returns JVMDI_ERROR_NONE.


Allocate Memory

jvmdiError
Allocate(jlong size, jbyte** memPtr)

Allocate an area of memory through the JVMDI allocator. The allocated memory should be freed with Deallocate.

Parameters:

size
the number of bytes to allocate.
memPtr
on return, a pointer to the beginning of the memory allocated by the allocator specified in SetAllocationHooks.

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

Deallocate Memory

jvmdiError
Deallocate(jbyte* mem)
Deallocate mem using the JVMDI allocator. This function should be used to deallocate any memory allocated and returned by a JVMDI function or any memory allocated with Allocate.

Parameters:

mem
a pointer to the beginning of the allocated memory.

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_NULL_POINTER
Invalid pointer.


Thread Execution Functions


Get Thread Status

jvmdiError
GetThreadStatus(jthread thread, jint *threadStatusPtr, jint *suspendStatusPtr)

Get status information for a thread.

Parameters:

thread
the thread to query
threadStatusPtr
on return, points to the current status of the thread. If the thread is suspended, the returned status refers to the thread status before suspension. The thread status is one of the following values.
JVMDI_THREAD_STATUS_UNKNOWN
Status unknown.

JVMDI_THREAD_STATUS_ZOMBIE
Thread has completed execution.

JVMDI_THREAD_STATUS_RUNNING
Thread is runnable.

JVMDI_THREAD_STATUS_SLEEPING
Thread sleeping. (Thread.sleep() has been called.)

JVMDI_THREAD_STATUS_MONITOR
Thread is waiting to enter a synchronization block.

JVMDI_THREAD_STATUS_WAIT
Thread waiting. (Object.wait() has been called.)
suspendStatusPtr
on return, points to information on suspension. The suspend status is a combination of zero or more of the following bit flags.

JVMDI_SUSPEND_STATUS_SUSPENDED
Thread suspended. (java.lang.Thread.suspend() or SuspendThread or SuspendThreadList has been called.)

JVMDI_SUSPEND_STATUS_BREAK
Thread has hit a breakpoint. This bit is only valid if the thread is the current thread or the thread is suspended.
This function returns either a universal error or one of the following errors:

JVMDI_ERROR_INVALID_THREAD
thread was invalid.

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

Get All Threads

jvmdiError
GetAllThreads(jint *threadsCountPtr, jthread **threadsPtr)

Get all running threads known to the virtual machine. Native threads which are not attached to the VM are not included in the returned list.

Parameters:

threadsCountPtr
on return, points to the number of running threads.
threadsPtr
on return, points to an array of references, one for each running thread. Threads in the array are JNI global references and must be explicitly freed with the JNI function DeleteGlobalRef. The returned thread array should be freed with Deallocate.
This function returns either a universal error or one of the following errors:

JVMDI_ERROR_NULL_POINTER
Invalid pointer.


Suspend Thread

jvmdiError
SuspendThread(jthread thread)

Suspend the specified thread. If the calling thread is specified, this function will not return until some other thread calls ResumeThread or ResumeThreadList.

Parameters:

thread
the thread to suspend

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_INVALID_THREAD
thread was invalid.

JVMDI_ERROR_THREAD_SUSPENDED
Thread already suspended.

Suspend Thread List

jvmdiError
SuspendThreadList(jint reqCount, jthread *reqList, jvmdiError *results)
Suspend the reqCount threads specified in the reqList array. If the calling thread is specified in the reqList array, this function will not return until some other thread calls ResumeThread or ResumeThreadList.

Parameters:

reqCount
the number of threads to suspend
reqList
the list of threads to suspend
results
the list of per-thread suspend results

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_ILLEGAL_ARGUMENT
reqCount is less than zero (0).

Note that the function return value does not include per-thread error conditions; per-thread error conditions are returned via the results array.

The results array element for a specific thread contains either a universal error or one of the following errors:

JVMDI_ERROR_INVALID_THREAD
thread was invalid.

JVMDI_ERROR_THREAD_SUSPENDED
Thread already suspended.

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

Resume Thread

jvmdiError
ResumeThread(jthread thread)

Resume a suspended thread. Any thread suspended through java.lang.Thread.suspend(), SuspendThread or SuspendThreadList will resume execution.

Parameters:

thread
the thread to resume

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_INVALID_THREAD
thread was invalid.

JVMDI_ERROR_THREAD_NOT_SUSPENDED
Thread was not suspended.

JVMDI_ERROR_INVALID_TYPESTATE
The state of the thread has been modified, and is now inconsistent.

Resume Thread List

jvmdiError
ResumeThreadList(jint reqCount, jthread *reqList, jvmdiError *results)

Resume the reqCount threads specified in the reqList array. Any thread suspended through java.lang.Thread.suspend(), SuspendThread, or SuspendThreadList will resume execution.

Parameters:

reqCount
the number of threads to resume
reqList
the list of threads to resume
results
the list of per-thread resume results

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_ILLEGAL_ARGUMENT
reqCount is less than zero (0).

The results array element for a specific thread contains either a universal error or one of the following errors:

JVMDI_ERROR_INVALID_THREAD
thread was invalid.

JVMDI_ERROR_THREAD_NOT_SUSPENDED
Thread was not suspended.

JVMDI_ERROR_INVALID_TYPESTATE
The state of the thread has been modified, and is now inconsistent.

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

Stop Thread

jvmdiError
StopThread(jthread thread, jobject exception)

Send the specified asynchronous exception to the specified thread (similar to java.lang.Thread.stop). Normally, this function is used to kill the specified thread with an instance of the exception ThreadDeath.

Parameters:

thread
the thread to stop
exception
the asynchronous exception object

The function returns one of the following error code:

JVMDI_ERROR_INVALID_THREAD

Interrupt Thread

jvmdiError
InterruptThread(jthread thread)

Interrupt the specified thread (similar to java.lang.Thread.interrupt).

Parameters:

thread
the thread to interrupt

The function returns one of the following error code:

JVMDI_ERROR_INVALID_THREAD

Get Thread Info

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)

Get thread information. The fields of the JVMDI_thread_info structure are filled in with details of the specified thread.

Parameters:

thread
the thread to query
infoPtr
on return, filled with information describing the specified thread. Returned objects (thread group and context class loader) are global references and must be explicitly freed with the JNI function DeleteGlobalRef. The returned thread name string should be freed with Deallocate

For JDK 1.1 implementations which don't recognize context class loaders, the context_class_loader field should be NULL.

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_INVALID_THREAD
thread was invalid.

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

Get Owned Monitor Info

typedef struct {
    jint owned_monitor_count;
    jobject *owned_monitors;
} JVMDI_owned_monitor_info;


jvmdiError
GetOwnedMonitorInfo(jthread thread, JVMDI_owned_monitor_info *infoPtr)

Get information about the monitors owned by the specified thread. The fields of the JVMDI_owned_monitor_info structure are filled in with details of the owned monitors. If this function is called for a thread different than the current thread, the specified thread must be suspended.

This is an optional feature which may not be implemented for all virtual machines. Use GetCapabilities to determine whether this and other features are supported in a particular virtual machine.

Parameters:

thread
the thread to query
infoPtr
on return, filled with owned monitor information. Returned objects (array of owned monitors) are global references and must be explicitly freed with the JNI function DeleteGlobalRef. The owned_monitors buffer containing the array should be freed with Deallocate

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_INVALID_THREAD
thread was invalid.

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_THREAD_NOT_SUSPENDED
thread must be suspended before calling.

JVMDI_ERROR_NOT_IMPLEMENTED
Optional feature not present in this VM.

Get Current Contended Monitor

jvmdiError
GetCurrentContendedMonitor(jthread thread, jobject *monitorPtr)

Get the object, if any, whose monitor the specified thread is waiting to enter or waiting to regain through java.lang.Object.wait. If this function is called for a thread different than the current thread, the specified thread must be suspended.

This is an optional feature which may not be implemented for all virtual machines. Use GetCapabilities to determine whether this and other features are supported in a particular virtual machine.

Parameters:

thread
the thread to query
monitorPtr
on return, filled with the current contended monitor, or NULL if there is none. The contended monitor object is a global reference and must be explicitly freed with the JNI function DeleteGlobalRef.

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_INVALID_THREAD
thread was invalid.

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_THREAD_NOT_SUSPENDED
thread must be suspended before calling.

JVMDI_ERROR_NOT_IMPLEMENTED
Optional feature not present in this VM.

Run Debug Thread

typedef void (*JVMDI_StartFunction)(void *);
jvmdiError
RunDebugThread(jthread thread, JVMDI_StartFunction proc, void *arg, int priority);

Starts the execution of a debugger thread. with the specified native function. The start function is given the single argument, arg, and the specified priority. This function allows the creation of debugger threads for handling communication with another process or for handling events without the need to load a special subclass of java.lang.Thread or implementor of java.lang.Runnable. Instead, the created thread can completely native. However, the created thread does require a newly created instance of java.lang.Thread (referenced by the argument thread) to which it will be associated. The thread object can be created with JNI calls, but it is recommended that all such calls to Java programming language code be done during debugger initialization to avoid any interaction with the application being debugged.

The new thread is started as a daemon thread.

Upon execution of proc, the new thread will be attached to the VM.

Parameters:

thread
the thread to run
proc
the start function
arg
the argument to the start function
priority
the priority of the started thread. Any thread priority allowed by java.lang.Thread.setPriority can be used including
  • JVMDI_THREAD_MIN_PRIORITY
  • JVMDI_THREAD_NORM_PRIORITY
  • JVMDI_THREAD_MAX_PRIORITY

This function returns one of the following error codes:

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_THREAD
thread was invalid.

JVMDI_ERROR_INVALID_PRIORITY


Thread Groups


Get Top Thread Groups

jvmdiError
GetTopThreadGroups(jint *groupCountPtr, jthreadGroup **groupsPtr)

Return all top-level (parentless) thread groups in the VM.

Parameters:

groupCountPtr
on return, points to the number of top-level thread groups
groupsPtr
on return, refers to a pointer to the top-level thread group array. Returned group array contains global references which must be explicitly freed with the JNI function DeleteGlobalRef. The group array array buffer should be freed with Deallocate

This function returns one of the following error codes:

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

Get Thread Group Info

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)

Get information about the thread group. The fields of the JVMDI_thread_group_info structure are filled in with details of the specified thread group.

Parameters:

group
the thread group to query
infoPtr
on return, filled with information describing the specified thread group. The returned thread group parent is a global references and must be explicitly freed with the JNI function DeleteGlobalRef. The returned thread group name string should be freed with Deallocate

This function returns one of the following error codes:

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_THREAD_GROUP

Get Thread Group Children

jvmdiError
GetThreadGroupChildren(jthreadGroup group,
                 jint *threadCountPtr, jthread **threadsPtr,
                 jint *groupCountPtr, jthreadGroup **groupsPtr)
Get the threads and thread groups created within the given thread group.

Parameters:

group
the group to query.
threadCountPtr
on return, points to the number of owned threads
threadsPtr
on return, refers to a pointer to the owned thread array. Returned thread array contains global references which must be explicitly freed with the JNI function DeleteGlobalRef. The thread array buffer should be freed with Deallocate
groupCountPtr
on return, points to the number of child thread groups
groupsPtr
on return, refers to a pointer to the child thread group array. Returned group array contains global references which must be explicitly freed with the JNI function DeleteGlobalRef. The group array array buffer should be freed with Deallocate

This function returns one of the following error codes:

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_THREAD_GROUP


Stack Frame Access


Get Thread's Frame Count

jvmdiError
GetFrameCount(jthread thread, jint *countPtr)

Get the number of frames currently in the specified thread's call stack.

If this function is called for a thread different than the current thread, the specified thread must be suspended.

Parameters:

thread
The thread to query
countPtr
on return, points to the number of frames in the call stack.
This function returns either a universal error or one of the following errors:

JVMDI_ERROR_INVALID_THREAD
thread was invalid.

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_THREAD_NOT_SUSPENDED
Thread was not suspended.

Get Thread's Current Frame

jvmdiError
GetCurrentFrame(jthread thread, jframeID *framePtr)

Get the jframeID value for the current stack frame of thread and return via framePtr.

If this function is called for a thread different than the current thread, the specified thread must be suspended. The returned frame ID value remains valid only until thread continues executing. The thread must be in a Java programming language or JNI method.

Parameters:

thread
The thread to query
framePtr
on return, points to the frame ID for the current stack frame of this thread.
This function returns either a universal error or one of the following errors:

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
There are no more Java programming language or JNI frames on the call stack.

Pop Frame from Thread's Stack

jvmdiError
PopFrame(jthread thread)

Pop the topmost stack frame of thread's stack. Popping a frame takes you to the frame for the caller of the topmost stack frame.. When the thread is resumed, the thread state is reset to the state immediately before the called method was invoked: the operand stack is restored (objectref if appropriate and arguments are added back), note however, that any changes to the arguments, which occurred in the called method, remain; when execution continues, the first instruction to execute will be the invoke.

Between calling PopFrame and resuming the thread the state of the stack is undefined. To pop frames beyond the first, these three steps must be repeated:

Locks acquired by a popped frame are released when it is popped. This applies to synchronized methods that are popped, and to any synchronized blocks within them.

Finally blocks are not executed.

Changes to global state are not addressed.

If this function is called for a thread different than the current thread, the specified thread must be suspended. The thread must be in a Java programming language or JNI method.

All frame IDs for this thread are invalidated.

No JVMDI events are generated by this function.

Native frames may not be popped, nor may a Java frame be popped if its caller is native code.

This is an optional feature which may not be implemented for all virtual machines. Examine can_pop_frame of GetCapabilities to determine whether this feature is supported in a particular virtual machine.

Parameters:

thread
The thread whose top frame is to be popped.
This function returns either a universal error or one of the following errors:

JVMDI_ERROR_INVALID_THREAD
thread was invalid.

JVMDI_ERROR_OPAQUE_FRAME
frame is a native frame.

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_THREAD_NOT_SUSPENDED
Thread was not suspended or current thread.

JVMDI_ERROR_NO_MORE_FRAMES
There are no more Java programming language frames on the call stack.

JVMDI_ERROR_NOT_IMPLEMENTED
This functionality is not implemented (can_pop_frame capability is false).

Get Caller Frame

jvmdiError
GetCallerFrame(jframeID called, jframeID *framePtr)
For frame, return the frame that called it via framePtr. Both called and the caller must be in a Java programming language or JNI method.

Parameters:

called
the called frame.
framePtr
on return, points to the frame ID for the calling frame.

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_FRAMEID
Invalid jframeID.

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

Frame Location

jvmdiError
GetFrameLocation(jframeID frame, jclass *classPtr, jmethodID *methodPtr,
                       jlocation *locationPtr)

For a Java programming language frame, return the location of the instruction currently executing.

Parameters:

frame
the frame to query.
classPtr
on return, points to the class for the current location. The returned class is a JNI global reference must be explicitly freed with the JNI function DeleteGlobalRef.
methodPtr
on return, points to the method for the current location.
locationPtr
on return, points to the index of the currently executing instruction.

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_FRAMEID
frame is not a valid frame ID.

Notify Frame Pop

jvmdiError
NotifyFramePop(jframeID frame); 
When frame is popped from the stack, generate a JVMDI_EVENT_FRAME_POP event. See Events.

Parameters:

frame
the frame for which the frame pop event will be generated.

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_FRAMEID
frame is not a valid frame ID.


Local Variable Access


Get Local Variable

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)

These functions are used to retrieve the value of a local variable. GetLocalInt can be used to retrieve int, char, byte, and boolean values. The variable is identified by the frame containing its value and the variable's slot number. The mapping of variables to slot numbers can be obtained with the function GetLocalVariableTable.

Parameters:

frame
the frame containing the variable's value.
slot
the variable's slot number.
valuePtr
on return, points to the variable's value. For GetLocalObject, the returned value is a global reference and must be explicitly freed with the JNI function DeleteGlobalRef().

The functions return one of the following error codes:

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.

JVMDI_ERROR_OPAQUE_FRAME

Set Local Variable

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)

These functions are used to set the value of a local variable. SetLocalInt can be used to set int, char, byte, and boolean values. The variable is identified by the frame containing its value and the variable's slot number. The mapping of variables to slot numbers can be obtained with the function GetLocalVariableTable.

Parameters:

frame
the frame containing the variable's value.
slot
the variable's slot number.
value
the new value for the variable

The functions return one of the following error codes:

JVMDI_ERROR_OPAQUE_FRAME
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

jvmdiError
SetBreakpoint(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.

Parameters:

clazz
the class in which to set the breakpoint
method
the method in which to set the breakpoint
location
the index of the instruction at which to set the breakpoint

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_INVALID_METHODID
Invalid method.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

JVMDI_ERROR_INVALID_LOCATION
Invalid location.

JVMDI_ERROR_DUPLICATE
The designated bytecode already has a breakpoint.

Clear a Breakpoint

jvmdiError
ClearBreakpoint(jclass clazz, jmethodID method, jlocation location)

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

Parameters:

clazz
the class in which to clear the breakpoint
method
the method in which to clear the breakpoint
location
the index of the instruction at which to clear the breakpoint

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_INVALID_METHODID
Invalid method.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

JVMDI_ERROR_INVALID_LOCATION
Invalid location.

JVMDI_ERROR_NOT_FOUND
There's no breakpoint at the designated bytecode.

Clear All Breakpoints

jvmdiError
ClearAllBreakpoints()
Clear all breakpoints in this virtual machine.


Watched Fields


Set a Field Access Watch

jvmdiError
SetFieldAccessWatch(jclass clazz, jfieldID field)

Generate a JVMDI_EVENT_FIELD_ACCESS event when the field specified by clazz and field is about to be accessed. An event will be generated for each access of the field until it is cancelled with ClearFieldAccessWatch. Field accesses from Java programming language code or from JNI are watched, fields modified by other means are not watched. Note that JVMDI users should be aware that their own field accesses will trigger the watch. A field can only have one field access watch set. Modification of a field is not considered an access - use SetFieldModificationWatch to monitor modifications.

This is an optional feature which may not be implemented for all virtual machines. Use GetCapabilities to determine whether this and other features are supported in a particular virtual machine.

Parameters:

clazz
the class containing the field to watch
field
the field to watch

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_INVALID_FIELDID
The jfieldID specified in field is not a valid field ID.

JVMDI_ERROR_INVALID_CLASS
The jclass specified in clazz is no a valid class.

JVMDI_ERROR_DUPLICATE
The designated field is already being watched for accesses.

JVMDI_ERROR_NOT_IMPLEMENTED
Optional feature not present in this VM.


Clear a Field Access Watch

jvmdiError
ClearFieldAccessWatch(jclass clazz, jfieldID field)

Cancel a field access watch previously set by SetFieldAccessWatch, on the field specified by clazz and field.

Parameters:

clazz
the class containing the field to watch
field
the field to watch

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_INVALID_FIELDID
The jfieldID specified in field is not a valid field ID.

JVMDI_ERROR_INVALID_CLASS
The jclass specified in clazz is no a valid class.

JVMDI_ERROR_NOT_FOUND
The designated field is not being watched for accesses.


Set a Field Modification Watch

jvmdiError
SetFieldModificationWatch(jclass clazz, jfieldID field)

Generate a JVMDI_EVENT_FIELD_MODIFICATION event when the field specified by clazz and field is about to be modified. An event will be generated for each modification of the field until it is cancelled with ClearFieldModificationWatch. Field modifications from Java programming language code or from JNI are watched, fields modified by other means are not watched. Note that JVMDI users should be aware that their own field modifications will trigger the watch. A field can only have one field modification watch set.

This is an optional feature which may not be implemented for all virtual machines. Use GetCapabilities to determine whether this and other features are supported in a particular virtual machine.

Parameters:

clazz
the class containing the field to watch
field
the field to watch

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_INVALID_FIELDID
The jfieldID specified in field is not a valid field ID.

JVMDI_ERROR_INVALID_CLASS
The jclass specified in clazz is no a valid class.

JVMDI_ERROR_DUPLICATE
The designated field is already being watched for modifications.

JVMDI_ERROR_NOT_IMPLEMENTED
Optional feature not present in this VM.


Clear a Field Modification Watch

jvmdiError
ClearFieldModificationWatch(jclass clazz, jfieldID field)

Cancel a field modification watch previously set by SetFieldModificationWatch, on the field specified by clazz and field.

Parameters:

clazz
the class containing the field to watch
field
the field to watch

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_INVALID_FIELDID
The jfieldID specified in field is not a valid field ID.

JVMDI_ERROR_INVALID_CLASS
The jclass specified in clazz is no a valid class.

JVMDI_ERROR_NOT_FOUND
The designated field is not being watched for modifications.


Class Information


Class Signature

jvmdiError
GetClassSignature(jclass clazz, char **sigPtr)
For the class indicated by clazz, return the class signature via sigPtr. The return value is a UTF-8 string.

The returned signature for primitive classes (for example, java.lang.Integer.TYPE) is the signature of the corresponding primitive type (for example, "I").

Parameters:

clazz
the class to query
sigPtr
on return, refers to a pointer to the class's signature (UTF-8). The returned signature string should be freed with Deallocate

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

Class Status

jvmdiError
GetClassStatus(jclass clazz, jint *statusPtr)
Get the status of the class. Zero or more of the following bits can be set.
JVMDI_CLASS_STATUS_VERIFIED
Class bytecodes have been verified.
JVMDI_CLASS_STATUS_PREPARED
Class preparation is complete.
JVMDI_CLASS_STATUS_INITIALIZED
Class initialization is complete. Static initializer has been run.
JVMDI_CLASS_STATUS_ERROR
Error during initialization makes class unusable.

The status value for primitive classes (for example, java.lang.Integer.TYPE) and for arrays is undefined.

Parameters:

clazz
the class to query
statusPtr
on return, points to the current state of this class as one or more of flags described above.

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

Source File Name

jvmdiError
GetSourceFileName(jclass clazz, char **sourceNamePtr)
For the class indicated by clazz, return the source file name via sourceNamePtr. The returned UTF-8 string is a file name only and never contains a directory name.

For primitive classes (for example, java.lang.Integer.TYPE) and for arrays this function returns JVMDI_ERROR_ABSENT_INFORMATION.

Parameters:

clazz
the class to query
sourceNamePtr
on return, refers to a pointer to the class's source file name (UTF-8). The returned file name string should be freed with Deallocate

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

JVMDI_ERROR_ABSENT_INFORMATION
Class information does not include a source path. This includes the case where the class is an array class or primitive class.

Class Modifier Flags

jvmdiError
GetClassModifiers(jclass clazz, jint *modifiersPtr)
For the class indicated by clazz, return the access flags via modifiersPtr. Access flag definitions and information about class modifiers can be found in the Java virtual machine specification.

If the class is an array class, then its public, private and protected modifiers are the same as those of its component type. For arrays of primitives, this component type is represented by one of the primitive classes (for example, java.lang.Integer.TYPE).

If the class is a primitive class, its public modifier is always true, and its protected and private modifiers are always false.

If the class is an array class or a primitive class then its final modifier is always true and its interface modifier is always false. The values of its other modifiers are not determined by this specification.

Parameters:

clazz
the class to query
modifiersPtr
on return, points to the current access flags of this class.

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

Class Methods

jvmdiError
GetClassMethods(jclass clazz, jint *methodCountPtr, jmethodID **methodsPtr)
For the class indicated by clazz, return a count of methods via methodCountPtr and a list of method IDs via methodsPtr. The method list contains constructors and static initializers as well as true methods. Only directly declared methods are returned (not inherited methods). Methods are returned in the order they occur in the class file. An empty method list is returned for array classes and primitive classes (for example, java.lang.Integer.TYPE).

Parameters:

clazz
the class to query
methodCountPtr
on return, points to the number of methods declared in this class.
methodsPtr
on return, points to the method ID array. The JVMDI allocator provides memory for the array. You must deallocate the array using Deallocate().

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

JVMDI_ERROR_CLASS_NOT_PREPARED

Class Fields

jvmdiError
GetClassFields(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. Only directly declared fields are returned (not inherited fields). Fields are returned in the order they occur in the class file. An empty field list is returned for array classes and primitive classes (for example, java.lang.Integer.TYPE). Use JNI to determine the length of an array.

Parameters:

clazz
the class to query
fieldCountPtr
on return, points to the number of fields declared in this class.
fieldsPtr
on return, points to the field ID array. The JVMDI allocator provides memory for the array. You must deallocate it using Deallocate().

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

JVMDI_ERROR_CLASS_NOT_PREPARED

Implemented Interfaces

jvmdiError
GetImplementedInterfaces(jclass clazz,
                       jint *interfaceCountPtr, 
                       jclass **interfacesPtr);
Return the direct super-interfaces of this class. For a class, this function returns the interfaces declared in its implements clause. For an interface, this function returns the interfaces declared in its extends clause. An empty interface list is returned for array classes and primitive classes (for example, java.lang.Integer.TYPE).

Parameters:

clazz
the class to query
interfaceCountPtr
on return, points to the number of interfaces.
interfacesPtr
on return, points to the interface array. Interfaces in the array are JNI global references and must be explicitly freed with the JNI function DeleteGlobalRef. The returned interface array should be freed with Deallocate.

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

JVMDI_ERROR_CLASS_NOT_PREPARED

Is an Interface

jvmdiError
IsInterface(jclass clazz, jboolean *isInterfacePtr)
Determines whether a class object reference represents an interface. The jboolean result is JNI_TRUE if the "class" is actually an interface, JNI_FALSE otherwise.

Parameters:

clazz
the class to query
isInterfacePtr
on return, points to the boolean result of this function.

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

Is an Array

jvmdiError
IsArrayClass(jclass clazz, jboolean *isArrayClassPtr)
Determines whether a class object reference represents an array. The jboolean result is JNI_TRUE if the class is an array, JNI_FALSE otherwise.

Parameters:

clazz
the class to query
isArrayClassPtr
on return, points to the boolean result of this function.

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

Class Loader

jvmdiError
GetClassLoader(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.

Parameters:

clazz
the class to query
classloaderPtr
on return, points to the class loader that loaded this class or interface, or NULL if there it has no class loader. The returned classloader is a JNI global reference and must be explicitly freed with the JNI function DeleteGlobalRef.

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

Source Debug Extension

jvmdiError
GetSourceDebugExtension(jclass clazz, char **sourceDebugExtensionPtr)
For the class indicated by clazz, return the debug extension via sourceDebugExtensionPtr. The returned UTF-8 string contains exactly the debug extension information present in the class file of clazz.

Parameters:

clazz
the class to query
sourceDebugExtensionPtr
on return, refers to a pointer to the class's debug extension name (UTF-8). The returned debug extension string should be freed with Deallocate

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

JVMDI_ERROR_ABSENT_INFORMATION
Class information does not include a debug extension.


Object Information


Object Hash Code

jvmdiError
GetObjectHashCode(jobject object, jint *hashCodePtr) 
For the object indicated by object return via hashCodePtr a hash code that can be used in maintaining hash table of object references. This function guarantees the same hash code value for a particular object throughout its life

Parameters:

object
the object to query
hashCodePtr
on return, points to the object's hash code

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_OBJECT
Invalid object.

Get Monitor Info

typedef struct {
    jthread owner;
    jint entry_count;
    jint waiter_count;
    jthread *waiters;
} JVMDI_monitor_info;

jvmdiError
GetMonitorInfo(jobject object, JVMDI_monitor_info *infoPtr)

Get information about the the object's monitor The fields of the JVMDI_owned_monitor_info structure are filled in with details of the monitor. Each thread that might affect the monitor state must either be suspended or must be the current thread.

This is an optional feature which may not be implemented for all virtual machines. Use GetCapabilities to determine whether this and other features are supported in a particular virtual machine.

Parameters:

object
the object to query
infoPtr
on return, filled with monitor information for the specified object. Returned objects (owner, array of waiters) are global references and must be explicitly freed with the JNI function DeleteGlobalRef. The returned waiter array buffer should be freed with Deallocate

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_INVALID_OBJECT
thread was invalid.

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_THREAD_NOT_SUSPENDED
thread must be suspended before calling.

JVMDI_ERROR_NOT_IMPLEMENTED
Optional feature not present in this VM.


Field Information


Field Name and Signature

jvmdiError
GetFieldName(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.

Parameters:

clazz
the class to query
field
the field to query
namePtr
on return, refers to a pointer to the UTF-8 field name. The string should be freed with Deallocate
signaturePtr
on return, refers to a pointer to the UTF-8 field signature. The string should be freed with Deallocate

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_FIELDID
Invalid field.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

Field Declaring Class

jvmdiError
GetFieldDeclaringClass(jclass clazz, jfieldID field, jclass *declaringClassPtr)
For the field indicated by clazz and field return the class that defined it via declaringClassPtr. The declaring class will either be clazz. a superclass, or an implemented interface.

Parameters:

clazz
the class to query
field
the field to query
declaringClassPtr
on return, points to the declaring class The returned class is a JNI global reference and must be explicitly freed with freed with the JNI function DeleteGlobalRef.

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_FIELDID
Invalid field.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

Field Modifier Flags

jvmdiError
GetFieldModifiers(jclass clazz, jfieldID field, jint *modifiersPtr)
For the field indicated by clazz and field return the access flags via modifiersPtr. Access flag definitions and information about field modifiers can be found in the Java virtual machine specification.

Parameters:

clazz
the class to query
field
the field to query
modifiersPtr
on return, points to the access flags.

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_FIELDID
Invalid method.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

Is Field Synthetic

jvmdiError
IsFieldSynthetic(jclass clazz, jfieldID field, jboolean *isSyntheticPtr)

For the field indicated by clazz and field, return a value indicating whether the field is synthetic via isSyntheticPtr Synthetic fields are generated by the compiler but not present in the original source code.

This is an optional feature which may not be implemented for all virtual machines. Use GetCapabilities to determine whether this and other features are supported in a particular virtual machine.

Parameters:

clazz
the class to query
field
the field to query
isSyntheticPtr
on return, points to the boolean result of this function.

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_FIELDID
Invalid field.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

JVMDI_ERROR_NOT_IMPLEMENTED
Optional feature not present in this VM.


Method Information


Method Name and Signature

jvmdiError
GetMethodName(jclass clazz, jmethodID method, 
                    char **namePtr, char **signaturePtr)

For the method indicated by clazz and method, return the method name via namePtr and method signature via signaturePtr. The signature is a JNI signature also called a method descriptor in the Java Virtual Machine Specification; note this is different then method signature as defined in the Java Language Specification.

Parameters:

clazz
the class to query
method
the method to query
namePtr
on return, refers to a pointer to the UTF-8 method name. The string should be freed with Deallocate
signaturePtr
on return, refers to a pointer to the UTF-8 method signature. The string should be freed with Deallocate

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_METHODID
Invalid method.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

Method Declaring Class

jvmdiError
GetMethodDeclaringClass(jclass clazz, jmethodID method,
                                 jclass *declaringClassPtr)
For the method indicated by clazz and method, return the Class that defined it via declaringClassPtr.

Parameters:

clazz
the class to query
method
the method to query
declaringClassPtr
on return, points to the declaring class The returned class is a JNI global reference and must be explicitly freed with freed with the JNI function DeleteGlobalRef.

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_METHODID
Invalid method.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

Method Modifier Flags

jvmdiError
GetMethodModifiers(jclass clazz, jmethodID method,
                         jint *modifiersPtr)
For the method indicated by clazz and method return the access flags via modifiersPtr. Access flag definitions and information about method modifiers can be found in the Java virtual machine specification.

Parameters:

clazz
the class to query
method
the method to query
modifiersPtr
on return, points to the access flags.

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_METHODID
Invalid method.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

Maximum Stack

jvmdiError
GetMaxStack(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.

Parameters:

clazz
the class to query
method
the method to query
maxPtr
on return, points to the maximum number of stack words

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_METHODID
Invalid method.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

Locals Slots

jvmdiError
GetMaxLocals(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.

Parameters:

clazz
the class to query
method
the method to query
maxPtr
on return, points to the maximum number of local slots

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_METHODID
Invalid method.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

Argument Slots

jvmdiError
GetArgumentsSize(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.

Parameters:

clazz
the class to query
method
the method to query
sizePtr
on return, points to the number of argument slots

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_METHODID
Invalid method.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

Source Line Numbers

jvmdiError
GetLineNumberTable(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. A table entry is an instance of the following structure:
typedef struct {
    jlocation start_location;
    jint line_number;
} JVMDI_line_number_entry;

Parameters:

clazz
the class to query
method
the method to query
entryCountPtr
on return, points to the number of entries in the table
tablePtr
on return, points to the line number table pointer. The JVMDI allocator provides space for the table. You must deallocate the table using Deallocate().

This function returns either a universal error or one of the following errors:

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_ABSENT_INFORMATION
Class information does not include line numbers.

Method Location

jvmdiError
GetMethodLocation(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.

Parameters:

clazz
the class to query
method
the method to query
startLocationPtr
on return, points to the first location, or -1 if location information is not available.
endLocationPtr
on return, points to the last location, or -1 if location information is not available.

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_METHODID
Invalid method.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

JVMDI_ERROR_ABSENT_INFORMATION
Class information does not include method sizes.

Local Variables

jvmdiError
GetLocalVariableTable(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. A table entry has this structure:
typedef struct {
    jlocation start_location;   /* variable valid start_location */
    jint length;                /* up to start_location+length */ 
    char *name;                 /* name in UTF-8 */
    char *signature;            /* type signature in UTF-8 */
    jint slot;                  /* variable slot, see JVMDI_GetLocal*()  */
} JVMDI_local_variable_entry;

Parameters:

clazz
the class to query
method
the method to query
entryCountPtr
on return, points to the number of entries in the table
tablePtr
on return, points to the local variable table pointer. The JVMDI allocator provides space for the table. In addition, each name and signature string in the table is allocated with the JVMDI allocator. You must deallocate these buffers using Deallocate.

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_METHODID
Invalid method.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

JVMDI_ERROR_ABSENT_INFORMATION
Class information does not include local variable information.

Exception Handlers

jvmdiError
GetExceptionHandlerTable(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. 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;

A call to this function may trigger class loading for the thrown exception classes that have not yet been loaded. It should not be called while threads are suspended.

Parameters:

clazz
the class to query
method
the method to query
entryCountPtr
on return, points to the number of entries in the table
tablePtr
on return, points to the exception handler table pointer. The JVMDI allocator provides space for the table. You must deallocate the table using Deallocate(). The classes returned in the "exception" field of JVMDI_exception_handler_entry are global references and must be explicitly freed with the JNI function Deallocate

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_METHODID
Invalid method.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

Thrown Exceptions

jvmdiError
GetThrownExceptions(jclass clazz, jmethodID method,
                          jint *exceptionCountPtr, jclass **exceptionsPtr)
For the method indicated by clazz and method, return an array of exception classes the method might throw. The number of exceptions is returned via exceptionCountPtr. The exceptions array is returned via exceptionsPtr.

A call to this function may trigger class loading for the thrown exception classes that have not yet been loaded. It should not be called while threads are suspended.

Parameters:

clazz
the class to query
method
the method to query
exceptionCountPtr
on return, points to the number of running threads.
exceptionsPtr
on return, points to an array of references, one for each thrown exception. Exception classes in the array are JNI global references and must be explicitly freed with the JNI function DeleteGlobalRef. The returned exception array should be freed with Deallocate.

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_METHODID
Invalid method.

JVMDI_ERROR_INVALID_CLASS
Invalid class.

Get Bytecodes

jvmdiError
GetBytecodes(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.

This is an optional feature which may not be implemented for all virtual machines. Use GetCapabilities to determine whether this and other features are supported in a particular virtual machine.

Parameters:

clazz
the class to query
method
the method to query
bytecodeCountPtr
on return, points to the length of the byte code array
bytecodesPtr
on return, points to the pointer to the byte code array The JVMDI memory allocator provides memory for the byte code array. You must deallocate the table using Deallocate().

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

JVMDI_ERROR_INVALID_METHODID
Invalid method.

JVMDI_ERROR_NOT_IMPLEMENTED
Optional feature not present in this VM.

Is Method Native

jvmdiError
IsMethodNative(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

Parameters:

clazz
the class to query
method
the method to query
isNativePtr
on return, points to the boolean result of this function.

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_METHODID
Invalid method.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

Is Method Synthetic

jvmdiError
IsMethodSynthetic(jclass clazz, jmethodID method, jboolean *isSyntheticPtr)

For the method indicated by clazz and method, return a value indicating whether the method is synthetic via isSyntheticPtr. Synthetic methods are generated by the compiler but not present in the original source code.

This is an optional feature which may not be implemented for all virtual machines. Use GetCapabilities to determine whether this and other features are supported in a particular virtual machine.

Parameters:

clazz
the class to query
method
the method to query
isSyntheticPtr
on return, points to the boolean result of this function.

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

JVMDI_ERROR_INVALID_METHODID
Invalid method.

JVMDI_ERROR_INVALID_CLASS
Invalid clazz.

JVMDI_ERROR_NOT_IMPLEMENTED
Optional feature not present in this VM.


Raw Monitor Support


Create Raw Monitor

jvmdiError
CreateRawMonitor(char *name, JVMDI_RawMonitor *monitorPtr)
Create a raw monitor.

Parameters:

name
a name in UTF-8 to identify the monitor
monitorPtr
on return, points to the created monitor.

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

Destroy Raw Monitor

jvmdiError
DestroyRawMonitor(JVMDI_RawMonitor monitor)
Destroy the raw monitor.

Parameters:

monitor
the monitor

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_INVALID_MONITOR
Invalid monitor.

Raw Monitor Enter

jvmdiError
RawMonitorEnter(JVMDI_RawMonitor monitor)
Gain exclusive ownership of a raw monitor.

Parameters:

monitor
the monitor

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_INVALID_MONITOR
Invalid monitor.

Raw Monitor Exit

jvmdiError
RawMonitorExit(JVMDI_RawMonitor monitor)
Release exclusive ownership of a raw monitor.

Parameters:

monitor
the monitor

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_INVALID_MONITOR
Invalid monitor.

JVMDI_ERROR_NOT_MONITOR_OWNER

Raw Monitor Wait

jvmdiError
RawMonitorWait(JVMDI_RawMonitor monitor, jlong millis)
Wait for notification of the raw monitor.

Parameters:

monitor
the monitor
millis
the timeout, in milliseconds

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_INVALID_MONITOR
Invalid monitor.

JVMDI_ERROR_NOT_MONITOR_OWNER

JVMDI_ERROR_INTERRUPT

Raw Monitor Notify

jvmdiError
RawMonitorNotify(JVMDI_RawMonitor monitor)
Notify a single thread waiting on the raw monitor.

Parameters:

monitor
the monitor

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_INVALID_MONITOR
Invalid monitor.

JVMDI_ERROR_NOT_MONITOR_OWNER

Raw Monitor Notify All

jvmdiError
RawMonitorNotifyAll(JVMDI_RawMonitor monitor)
Notify all threads waiting on the raw monitor.

Parameters:

monitor
the monitor

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_INVALID_MONITOR
Invalid monitor.

JVMDI_ERROR_NOT_MONITOR_OWNER


Events


Set Event Hook

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

jvmdiError
SetEventHook(JVMDI_EventHook hook)
Set the function to be called on every event. Details on events are described later in this document.

Parameters:

hook
the new event hook, or NULL to remove the existing hook.

This function returns a universal error on error.


Enable/Disable Events

jvmdiError
SetEventNotificationMode(jint mode, jint eventType, jthread thread, ...)
Control the generation of events. If mode is JVMDI_ENABLE, the event eventType is enabled; if mode is JVMDI_DISABLE, the event is disabled. If thread is NULL, the event is enabled or disabled globally; otherwise, it is enabled or disabled for a particular thread. An event is generated for a particular thread if it is enabled either at the thread or global levels.

Global and per-thread enabling of events is independent. For example, if MethodEntry is initially disabled both globally and on each thread, MethodEntry is still disabled per-thread when it is enabled globally. When an executing thread encounters a potential event condition, an event will be sent if either that event is globally enabled OR that event is enabled for the executing thread. Thus globally enabling an event applies to threads created after the call as well.

See below for information on specific events.

The following events cannot be controlled (enabled or disabled) at the thread level through this function.

The following event cannot be controlled (enabled or disabled) at the global level through this function.

Initially, no events are enabled at the thread level. All events except the following are enabled at the global level.

Set the function to be called on every event. Details on events are described later in this document.

Parameters:

mode
JVMDI_ENABLE or JVMDI_DISABLE
eventType
the event to control
thread
the thread to control, or NULL for all threads

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_INVALID_THREAD
If thread is invalid or the thread has not run.

JVMDI_ERROR_INVALID_EVENT_TYPE
If eventType is invalid value.

JVMDI_ERROR_ILLEGAL_ARGUMENT
If thread argument is specified with one of the following events:
  • JVMDI_EVENT_VM_INIT
  • JVMDI_EVENT_VM_DEATH
  • JVMDI_EVENT_THREAD_START
  • JVMDI_EVENT_CLASS_UNLOAD


Miscellaneous Functions


Get Loaded Classes

jvmdiError
GetLoadedClasses(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 Deallocate().

Array classes of all types (including arrays of primitive types) are included in the returned list. Primitive classes (for example, java.lang.Integer.TYPE) are not included in this list.

Parameters:

classCountPtr
on return, points to the number of classes.
classesPtr
on return, points to an array of references, one for each class. Classes in the array are JNI global references and must be explicitly freed with the JNI function DeleteGlobalRef. The returned class array should be freed with Deallocate.

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

Get Classloader Classes

jvmdiError
GetClassLoaderClasses(jobject initiatingLoader, jint *classCountPtr, jclass **classesPtr)

Returns an array of all classes for which this class loader has been recorded as the initiating loader. Each class in the returned array was created by this class loader, either by defining it directly or by delegation to another class loader.

For JDK 1.1 implementations which don't recognize the distinction between initiating and defining classloaders, this function should return 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 Deallocate().

The initiatingLoader argument must not be null. The set of classes initiated by the system class loader is identical to the set of classes defined by that loader. This set can be determined by calling GetLoadedClasses and selecting those classes with a null class loader.

Parameters:

initiatingLoader
the initiating class loader.
classCountPtr
on return, points to the number of classes.
classesPtr
on return, points to an array of references, one for each class. Classes in the array are JNI global references and must be explicitly freed with the JNI function DeleteGlobalRef. The returned class array should be freed with Deallocate.

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

Redefine Classes

typedef struct {
    jclass clazz;              /* Class to be redefined */
    jint class_byte_count;     /* number of bytes defining class (below) */
    jbyte *class_bytes;        /* bytes defining class */
                               /* (in Class File Format of JVM spec) */
} JVMDI_class_definition;

jvmdiError
RedefineClasses(jint classCount, JVMDI_class_definition *classDefs)

All classes given are redefined according to the definitions supplied. If any redefined methods have active stack frames, those active frames continue to run the bytecodes of the original method. The redefined methods will be used on new invokes. Any JVMDI function or event which returns a jmethodID, will return OBSOLETE_METHOD_ID when referring to the original method (for example, when examining a stack frame where the original method is still executing) unless it is equivalent to the redefined method (see below). The original method ID refers to the redefined method. Care should be taken thoughout a JVMDI client to handle OBSOLETE_METHOD_ID. If reseting of stack frames is desired, use PopFrame to pop frames with OBSOLETE_METHOD_IDs.

An original and a redefined method should be considered equivalent if:

This function does not cause any initialization except that which would occur under the customary JVM semantics. In other words, redefining a class does not cause its initializers to be run. The values of preexisting static variables will remain as they were prior to the call. However, completely uninitialized (new) static variables will be assigned their default value.

If a redefined class has instances then all those instances will have the fields defined by the redefined class at the completion of the call. Preexisting fields will retain their previous values. Any new fields will have their default values; no instance initializers or constructors are run.

Threads need not be suspended.

All breakpoints in the class are cleared.

All attributes are updated.

No JVMDI events are generated by this function.

This is an optional feature which may not be implemented for all virtual machines. Examine can_redefine_classes, can_add_method and can_unrestrictedly_redefine_classes of GetCapabilities to determine whether this feature is supported in a particular virtual machine.

Parameters:

classCount
the number of classes specified in classDefs
classDefs
the array of new class definitions
This function returns either a universal error or one of the following errors:

JVMDI_ERROR_NULL_POINTER
Invalid pointer: classDefs or one of class_bytes is NULL.

JVMDI_ERROR_INVALID_CLASS
An element of classDefs is not a valid class.

JVMDI_ERROR_UNSUPPORTED_VERSION
A new class file has a version number not supported by this VM.

JVMDI_ERROR_INVALID_CLASS_FORMAT
A new class file is malformed (The VM would return a ClassFormatError).

JVMDI_ERROR_CIRCULAR_CLASS_DEFINITION
The new class file definitions would lead to a circular definition (the VM would return a ClassCircularityError).

JVMDI_ERROR_FAILS_VERIFICATION
The class bytes fail verification.

JVMDI_ERROR_NAMES_DONT_MATCH
The class name defined in the new class file is different from the name in the old class object.

JVMDI_ERROR_NOT_IMPLEMENTED
No aspect of this functionality is implemented (can_redefine_classes capability is false).

JVMDI_ERROR_ADD_METHOD_NOT_IMPLEMENTED
A new class file would require adding a method, (and can_add_method capability is false).

JVMDI_ERROR_SCHEMA_CHANGE_NOT_IMPLEMENTED
The new class version changes fields (and can_unrestrictedly_redefine_classes is false).

JVMDI_ERROR_HIERARCHY_CHANGE_NOT_IMPLEMENTED
A direct superclass is different for the new class version, or the set of directly implemented interfaces is different (and can_unrestrictedly_redefine_classes is false).

JVMDI_ERROR_DELETE_METHOD_NOT_IMPLEMENTED
The new class version does not declare a method declared in the old class version. (and can_unrestrictedly_redefine_classes is false).

JVMDI_ERROR_CLASS_MODIFIERS_CHANGE_NOT_IMPLEMENTED
The new version of a class has different class modifiers (public, abstract, final, ...) then the old version (and can_unrestrictedly_redefine_classes is false).

JVMDI_ERROR_METHOD_MODIFIERS_CHANGE_NOT_IMPLEMENTED
The new version of a class has a different method modifier (public, abstract, synchronized, ...) then the old version (and can_unrestrictedly_redefine_classes is false).

Get Version Number

jvmdiError
GetVersionNumber(jint *versionPtr)
Return the JVMDI version via versionPtr The return value is the version identifier. The low-order 16 bits represent the minor version number. The next 12 bits represent the major version number. The high-order 4 bits are undefined.

Parameters:

versionPtr
on return, points to the JVMDI version.

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_NULL_POINTER
Invalid pointer.

Get Capabilities

typedef struct {
    unsigned int can_watch_field_modification        : 1;
    unsigned int can_watch_field_access              : 1;
    unsigned int can_get_bytecodes                   : 1;
    unsigned int can_get_synthetic_attribute         : 1;
    unsigned int can_get_owned_monitor_info          : 1;
    unsigned int can_get_current_contended_monitor   : 1;
    unsigned int can_get_monitor_info                : 1;
    unsigned int reserved1                           : 1;
    unsigned int reserved2                           : 1;
    unsigned int reserved3                           : 1;
    unsigned int can_pop_frame                       : 1;
    unsigned int reserved4                           : 1;
    unsigned int can_redefine_classes                : 1; 
    unsigned int can_add_method                      : 1;
    unsigned int can_unrestrictedly_redefine_classes : 1;
    unsigned int reserved5                           : 1;
} JVMDI_capabilities;

jvmdiError
GetCapabilities(JVMDI_capabilities *capabilitiesPtr)
Return via capabilitiesPtr the optional JVMDI features supported by this implementation. The capabilities structure contains a number of boolean flags indicating whether the named feature is supported.

Parameters:

capabilitiesPtr
on return, points to the JVMDI capabilities.

This function returns either a universal error or one of the following errors:

JVMDI_ERROR_NULL_POINTER
Invalid pointer.


Errors

Every JVMDI function returns a jvmdiError error code.

Universal Errors

The following errors may be returned by any JVMDI function (and are thus not listed in the function descriptions):

JVMDI_ERROR_NONE
No error has occurred. This is the error code that is returned on successful completion of the function.

JVMDI_ERROR_OUT_OF_MEMORY
The function needed to allocate memory and no more memory was available for allocation.

JVMDI_ERROR_ACCESS_DENIED
Debugging has not been enabled in this virtual machine. JVMDI cannot be used.

JVMDI_ERROR_UNATTACHED_THREAD
The thread being used to call this function is not attached to the virtual machine. Calls must be made from attached threads. See AttachCurrentThread() in the JNI invocation API.

JVMDI_ERROR_VM_DEAD
The virtual machine is not running.

JVMDI_ERROR_INTERNAL
An unexpected internal error has occurred.

Function Specific Errors

The following errors are returned by some JVMDI functions (and are listed in the function descriptions):

JVMDI_ERROR_INVALID_THREAD
passed thread is NULL, is not a valid thread or has exited

JVMDI_ERROR_INVALID_FIELDID
invalid field

JVMDI_ERROR_INVALID_METHODID
invalid method

JVMDI_ERROR_INVALID_LOCATION
invalid location

JVMDI_ERROR_INVALID_FRAMEID
invalid jframeID

JVMDI_ERROR_NO_MORE_FRAMES
There are no more Java programming language or JNI frames on the call stack.

JVMDI_ERROR_OPAQUE_FRAME
information about the frame is not available (e.g. for native frames)

JVMDI_ERROR_NOT_CURRENT_FRAME
operation can only be performed on current frame

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

JVMDI_ERROR_INVALID_SLOT
invalid slot

JVMDI_ERROR_DUPLICATE
item already set

JVMDI_ERROR_THREAD_NOT_SUSPENDED
thread was not suspended

JVMDI_ERROR_THREAD_SUSPENDED
thread already suspended

JVMDI_ERROR_INVALID_OBJECT
invalid object

JVMDI_ERROR_INVALID_CLASS
invalid class

JVMDI_ERROR_CLASS_NOT_PREPARED
class has been loaded but not yet prepared

JVMDI_ERROR_NULL_POINTER
invalid pointer

JVMDI_ERROR_ABSENT_INFORMATION
The requested information is not available.

JVMDI_ERROR_INVALID_EVENT_TYPE
The specified event type id is not recognized.

JVMDI_ERROR_NOT_IMPLEMENTED
The functionality is not implemented in this virtual machine

JVMDI_ERROR_INVALID_THREAD_GROUP
thread group invalid

JVMDI_ERROR_INVALID_PRIORITY
invalid priority

JVMDI_ERROR_NOT_FOUND
Desired element (e.g. field or breakpoint) not found

JVMDI_ERROR_INVALID_MONITOR
invalid monitor

JVMDI_ERROR_ILLEGAL_ARGUMENT
illegal argument

JVMDI_ERROR_NOT_MONITOR_OWNER
This thread doesn't own the monitor.

JVMDI_ERROR_ABSENT_INFORMATION
Desired information is not available.

JVMDI_ERROR_INTERRUPT
The call has been interrupted before completion.

JVMDI_ERROR_INVALID_TYPESTATE
The state of the thread has been modified, and is now inconsistent.

JVMDI_ERROR_UNSUPPORTED_VERSION
A new class file has a version number not supported by this VM.

JVMDI_ERROR_INVALID_CLASS_FORMAT
A new class file is malformed (The VM would return a ClassFormatError).

JVMDI_ERROR_CIRCULAR_CLASS_DEFINITION
The new class file definitions would lead to a circular definition (the VM would return a ClassCircularityError).

JVMDI_ERROR_ADD_METHOD_NOT_IMPLEMENTED
A new class file would require adding a method, and can_add_method is false.

JVMDI_ERROR_SCHEMA_CHANGE_NOT_IMPLEMENTED
A new class file would require a schema change, and can_unrestrictedly_redefine_classes is false.

JVMDI_ERROR_FAILS_VERIFICATION
The class bytes fail verification.

JVMDI_ERROR_HIERARCHY_CHANGE_NOT_IMPLEMENTED
A direct superclass is different for the new class version, or the set of directly implemented interfaces is different and can_unrestrictedly_redefine_classes is false.

JVMDI_ERROR_DELETE_METHOD_NOT_IMPLEMENTED
The new class version does not declare a method declared in the old class version and can_unrestrictedly_redefine_classes is false.

JVMDI_ERROR_NAMES_DONT_MATCH
The class name defined in the new class file is different from the name in the old class object.

JVMDI_ERROR_CLASS_MODIFIERS_CHANGE_NOT_IMPLEMENTED
The new version of a class has different class modifiers (public, abstract, final, ...) then the old version (and can_unrestrictedly_redefine_classes is false).

JVMDI_ERROR_METHOD_MODIFIERS_CHANGE_NOT_IMPLEMENTED
The new version of a class has a different method modifier (public, abstract, synchronized, ...) then the old version (and can_unrestrictedly_redefine_classes is false).


Handling Events

JVMDI clients can be informed of many events that occur in application programs.

To handle Events, designate a hook function with SetEventHook. For each event the hook function will be called with a JVMDI_Event argument describing the event type and, depending on the event, additional information. The hook function is usually called from within application threads and the JVMDI implementation does not queue events in any way. This means that event hook functions must be written carefully. Here are some general guidelines. See the individual event descriptions for further suggestions.

Some JVMDI events identify objects with JNI references. All such references are passed to the event hook function via the JVMDI_Event argument. All references in JVMDI events are JNI local references and will become invalid after the event hook returns. The JVMDI_Event data structure is allocated locally and deallocated when the event hook function returns.

Events can be enabled and disabled with the function SetEventNotificationMode. Some events are enabled at application startup; others are not. Refer to the documentation for this function for details.

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 is responsible for explicitly suspending the thread with SuspendThread.

The JVMDI_Event contains the event kind and a union of event-specific structures containing more information.

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;

More information on specific events is given in the sections below.


Single Step Events (JVMDI_EVENT_SINGLE_STEP)

    typedef struct { 
        jthread thread;
        jclass clazz;
        jmethodID method;
        jlocation location;
    } JVMDI_single_step_event_data;

Single step events allow the JVMDI client to trace thread execution at the finest granularity allowed by the VM. A single step event is generated whenever a thread reaches a new location. Typically, single step events represent the completion of one VM instruction as defined the VM Specification; however, some implementations may define location differently. In any case the clazz, method, and location fields of the event structure uniquely identify the current location and allow the mapping to source file and line number when that information is available.

No single step events are generated from within native methods.

Single step events are disabled by default and can be enabled for a thread by calling SetEventNotificationMode


Breakpoint Events (JVMDI_EVENT_BREAKPOINT)

    typedef struct { 
        jthread thread;
        jclass clazz;
        jmethodID method;
        jlocation location;
    } JVMDI_breakpoint_event_data;

Breakpoint Events are generated whenever a thread reaches a location designated as a breakpoint with SetBreakpoint. The clazz, method, and location fields of the event structure uniquely identify the current location and allow the mapping to source file and line number when that information is available.

Breakpoint reporting, in general, can be enabled or disabled by calling SetEventNotificationMode and are enabled by default. If they are disabled, set breakpoints are ignored.


Field Events (JVMDI_EVENT_FIELD_ACCESS, JVMDI_EVENT_FIELD_MODIFICATION)

    /* 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;

Field Events are generated whenever a thread accesses or modifies a field designated as a watchpoint with SetFieldAccessWatch or with SetFieldModificationWatch. The clazz, method, and location fields of the event structures uniquely identify the current location and allow the mapping to source file and line number when that information is available. The field_clazz and field fields uniquely identify the field which is being accessed or modified. The object identifies the containing object if the field is an instance field. It is NULL otherwise.

Field watchpoint reporting, in general, can be enabled or disabled by calling SetEventNotificationMode and are enabled by default. If they are disabled, set watches are ignored.


Frame Events (JVMDI_EVENT_FRAME_POP, JVMDI_EVENT_METHOD_ENTRY, JVMDI_EVENT_METHOD_EXIT)

    typedef struct { 
        jthread thread;
        jclass clazz;
        jmethodID method;
        jframeID frame;
    } JVMDI_frame_event_data;

Method entry events are generated upon entry of Java programming language or native methods. Method exit events are generated upon exit from a Java programming language or native methods. Frame pop events are generated upon exit from a single method in a single frame as specified in a call to NotifyFramePop. If a method terminates by throwing an exception to its caller, neither a method exit event nor a frame pop event will be generated. JVMDI clients can check for this occurrence by monitoring exception catch events

The clazz and method fields uniquely identify the method being entered or exited. The frame field provides access to the stack frame for the method. On method entry, the location reported by GetFrameLocation identifies the initial executable location in the method. On method exit or frame pop, the location reported by GetFrameLocation identifies the executable location in the returning method, immediately prior to the return.

Method entry and exit are disabled by default and can be enabled by calling SetEventNotificationMode. Frame pop events are enabled by default and can be disabled similarly.


Exception Events (JVMDI_EVENT_EXCEPTION)

    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;

Exception events are generated whenever an exception is first detected in a Java programming language method. The exception may have been thrown by a Java programming language or native method, but in the case of native methods, the event is not generated until the exception is first seen by a Java programming language method. If an exception is set and cleared in a native method (and thus is never visible to Java programming language code), no exception event is generated.

The clazz, method, and location fields of the event structure uniquely identify the current location (where the exception was detected) and allow the mapping to source file and line number when that information is available. The exception field identifies the thrown exception object. The catch_clazz, catch_method, and catch_location identify the location of the catch clause, if any, that handles thrown exception. If there is no such catch clause, each field is set to 0. There is no guarantee that the thread will ever reach this catch clause. If there are native methods on the call stack between the throw location and the catch clause, the exception may be reset by one of those native methods. JVMDI clients can check for this occurrence by monitoring exception catch events

Exception events are enabled by default and can be disabled by calling SetEventNotificationMode.


Exception Catch Events (JVMDI_EVENT_EXCEPTION_CATCH)

    typedef struct { 
        jthread thread;
        jclass clazz;
        jmethodID method;
        jlocation location;
        jobject exception;
    } JVMDI_exception_catch_event_data;

Exception catch events are generated whenever a thrown exception is caught. If the exception is caught in a Java programming language method, the event is generated when the catch clause is reached. If the exception is caught in a native method, the event is generated as soon as control is returned to a Java programming language method. Exception catch events are generated for any exception for which a throw was detected in a Java programming language method.

The clazz, method, and location fields of the event structure uniquely identify the current location and allow the mapping to source file and line number when that information is available. For exceptions caught in a Java programming language method, the exception object identifies the exception object. Exceptions caught in native methods are not necessarily available by the time the exception catch is reported, so the exception field is set to NULL.

Exception catch events are disabled by default and can be enabled by calling SetEventNotificationMode.


User Defined Events (JVMDI_EVENT_USER_DEFINED)

    typedef struct { 
        jobject object;
        jint key;
    } JVMDI_user_event_data;

The meaning of user defined events and the fields in the user event data structure are defined by particular JVMDI implementations.


Thread Events (JVMDI_EVENT_THREAD_END, JVMDI_EVENT_THREAD_START)

    typedef struct { 
        jthread thread;
    } JVMDI_thread_change_event_data;

Thread start events are generated by a new thread before its initial method executes. Thread end events are generated by a terminating thread after its initial method has finished execution. A thread may be listed in the array returned by GetAllThreads before its thread start event is generated and after its thread end event is generated. It is possible for other events to be generated for a thread before its thread start event, but no events are generated after its thread end event.

Thread events are enabled by default and can be disabled by calling SetEventNotificationMode.


Class Events (JVMDI_EVENT_CLASS_LOAD, JVMDI_EVENT_CLASS_UNLOAD, JVMDI_EVENT_CLASS_PREPARE)

    typedef struct { 
        jthread thread;
        jclass clazz;
    } JVMDI_class_event_data;

Class events signal a change in status for a particular class.

A class load event is generated when a class is first loaded. The order of class load events are generated by a particular thread are guaranteed to match the order of class loading within that thread. Arrays of non-primitive types have class load events. Arrays of primitive types do not have class load events (they are considered loaded at the time of VM initialization). Primitive classes (for example, java.lang.Integer.TYPE) do not have class load events.

A class prepare event is generated when class preparation is complete. At this point, class fields, methods, and implemented interfaces are available, and no code from the class has been executed. Since array classes never have fields or methods, class prepare events are not generated for them. Class prepare events are not generated for primitive classes (for example, java.lang.Integer.TYPE).

A class unload event is generated when the class is about to be unloaded. Class unload events take place during garbage collection and must be handled extremely carefully. The garbage collector holds many locks and has suspended all other threads, so the event handler cannot depend on the ability to acquire any locks. The class unload event handler should do as little as possible, perhaps by queueing information to be processed later.

Class events are enabled by default and can be disabled by calling SetEventNotificationMode.


VM Initialization Event (JVMDI_EVENT_VM_INIT)

The VM initialization event signals the completion of VM initialization. Once this event is generated, the JVMDI client is free to call any JNI or JVMDI function. The VM initialization event can be preceded by or can be concurrent with other events, but the preceding events should be handled carefully, if at all because the VM has not completed its initialization. The thread start event for the main application thread is guaranteed not to occur until after the handler for the VM initialization event returns.


VM Death Event (JVMDI_EVENT_VM_DEATH)

The VM death event notifies the JVMDI client of the termination of the VM.

Multiple Co-located Events

In many situations it is possible for multiple events to occur at the same location in one thread. When this happens, all of the events are reported through the event hook in the order specified in the following paragraphs.

If the current location is at the entry point of a method, the JVMDI_EVENT_METHOD_ENTRY event is reported before any other event at the current location in the same thread.

If an exception catch has been detected at the current location, (either because it is the beginning of a catch clause or a native method which cleared a pending exception has returned), the JVMDI_EVENT_EXCEPTION_CATCH event is reported before any other event at the current location in the same thread.

If a JVMDI_EVENT_SINGLE_STEP event or JVMDI_EVENT_BREAKPOINT event is triggered at the current location, the event is defined to occur immediately before the code at the current location is executed. These events are reported before any events which are triggered by the execution of code at the current location in the same thread (specifically, JVMDI_EVENT_EXCEPTION, JVMDI_EVENT_FIELD_ACCESS, and JVMDI_EVENT_FIELD_MODIFICATION). If both a step and breakpoint event are triggered for the same thread and location, the step event is reported before the breakpoint event.

If the current location is the exit point of a method (that is, the last location before returning to the caller), the JVMDI_EVENT_METHOD_EXIT event and the JVMDI_EVENT_FRAME_POP event (if requested) are reported after all other events at the current location in the same thread. There is no specified ordering of these two events with respect to each other.

Co-located events can be triggered during the processing of some other event by the JVMDI client at the same location in the same thread. If such an event, of type y, is triggered during the processing of an event of type x, and if x precedes y in the ordering specified above, then the co-located event y is reported for the current thread and location. If x does not precede y, then y is not reported for the current thread and location. For example, if a breakpoint is set at the current location during the processing of JVMDI_EVENT_SINGLE_STEP, that breakpoint will be reported before the thread moves off the current location.

The following events are never considered to be co-located with other events.


Starting a VM with a JVMDI Client

The initial loading of a JVMDI client at VM startup can vary from VM to VM. The following description applies to the Sun J2SE SDK 1.2 classic VM for Windows and Solaris.

The following command-line arguments are required on VM startup to properly load and run JVMDI clients.

-Xdebug
Enables debugging
-Xnoagent
Prevents the default debug agent (used with jdb) from running.
-Djava.compiler=NONE
Disables the JIT. The classic VM does not support debugging with the JIT enabled.
-Xrun:
Identifies the library containing the JVMDI client as well as an options string to be passed in at startup. The library must export a startup function with the following prototype.
JNIEXPORT jint JNICALL 
JVM_OnLoad(JavaVM *vm, char *options, void *reserved) 
This function will be called at startup by the VM. For example, if the option -Xrunfoo:opt1,opt2 is specified, the VM will attempt to load the shared library foo.dll under Windows or libfoo.so under Solaris. It will then attempt to find JVM_OnLoad and call it with "opt1,opt2" as the second argument. Since the VM is not initialized at the time of this call, there is very little that can be done safely inside JVM_OnLoad. It can safely process the options and set an event hook with SetEventHook. Once that event hook is called for the VM initialization event, the JVMDI client can complete its initialization.

Copyright © 1996-2001 Sun Microsystems, Inc. All Rights Reserved.

Send questions or comments to: java-debugger@sun.com.

Sun