Java(tm) Virtual Machine Debug Interface Reference (original) (raw)
| | |
| ---------------------------------------------------------------------- | |
Contents
Introduction
Using JVMDI Functions
Errors
Handling Events
Starting a VM with a JVMDI Client
Introduction
Note: JVMDI is deprecated as of J2SE 5.0. JVMTI should be used instead.
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 was the lowest layer within the Java Platform Debugger Architecture, this role is now handled by JVMTI. 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 documentationfor this release and theJava 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 ofjobject
, 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
- Thread Execution Functions
- Thread Groups
- Stack Frame Access
- Local Variable Access
- Breakpoints
- Watched Fields
- Class Information
- Object Information
- Field Information
- Method Information
- Raw Monitor Support
- Events
- Miscellaneous Functions
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, callSetAllocationHooks
with ahook
anddhook
set to NULL
.
The ahook
function should look in size
for the number of bytes to allocate and return them viamemPtr
. The function should returnJVMDI_ERROR_NULL_POINTER if passed null pointers,JVMDI_ERROR_OUT_OF_MEMORY if it cannot honor a memory request, andJVMDI_ERROR_NONE otherwise.
The dhook
function should look in buffer
for the memory to be deallocated. The function should returnJVMDI_ERROR_NULL_POINTER if passed null pointers, JVMDI_ERROR_NONEotherwise.
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](#JVMDI%5FERROR%5FNONE)
.
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 inSetAllocationHooks.
This function returns either a universal error or one of the following errors:
[JVMDI_ERROR_NULL_POINTER](#JVMDI%5FERROR%5FNULL%5FPOINTER)
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](#JVMDI%5FERROR%5FNULL%5FPOINTER)
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](#JVMDI%5FERROR%5FINVALID%5FTHREAD)
thread
was invalid.
[JVMDI_ERROR_NULL_POINTER](#JVMDI%5FERROR%5FNULL%5FPOINTER)
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](#Deallocate)
.
This function returns either a universal error or one of the following errors:
[JVMDI_ERROR_NULL_POINTER](#JVMDI%5FERROR%5FNULL%5FPOINTER)
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](#JVMDI%5FERROR%5FINVALID%5FTHREAD)
thread
was invalid.
[JVMDI_ERROR_THREAD_SUSPENDED](#JVMDI%5FERROR%5FTHREAD%5FSUSPENDED)
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 orResumeThreadList.
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](#JVMDI%5FERROR%5FILLEGAL%5FARGUMENT)
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](#JVMDI%5FERROR%5FINVALID%5FTHREAD)
thread
was invalid.
[JVMDI_ERROR_THREAD_SUSPENDED](#JVMDI%5FERROR%5FTHREAD%5FSUSPENDED)
Thread already suspended.
[JVMDI_ERROR_NULL_POINTER](#JVMDI%5FERROR%5FNULL%5FPOINTER)
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](#JVMDI%5FERROR%5FINVALID%5FTHREAD)
thread
was invalid.
[JVMDI_ERROR_THREAD_NOT_SUSPENDED](#JVMDI%5FERROR%5FTHREAD%5FNOT%5FSUSPENDED)
Thread was not suspended.
[JVMDI_ERROR_INVALID_TYPESTATE](#JVMDI%5FERROR%5FINVALID%5FTYPESTATE)
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](#JVMDI%5FERROR%5FILLEGAL%5FARGUMENT)
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](#JVMDI%5FERROR%5FINVALID%5FTHREAD)
thread
was invalid.
[JVMDI_ERROR_THREAD_NOT_SUSPENDED](#JVMDI%5FERROR%5FTHREAD%5FNOT%5FSUSPENDED)
Thread was not suspended.
[JVMDI_ERROR_INVALID_TYPESTATE](#JVMDI%5FERROR%5FINVALID%5FTYPESTATE)
The state of the thread has been modified, and is now inconsistent.
[JVMDI_ERROR_NULL_POINTER](#JVMDI%5FERROR%5FNULL%5FPOINTER)
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](#JVMDI%5FERROR%5FINVALID%5FTHREAD)
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](#JVMDI%5FERROR%5FINVALID%5FTHREAD)
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](#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](#JVMDI%5FERROR%5FINVALID%5FTHREAD)
thread
was invalid.
[JVMDI_ERROR_NULL_POINTER](#JVMDI%5FERROR%5FNULL%5FPOINTER)
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 GetCapabilitiesto 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
. Theowned_monitors
buffer containing the array should be freed with[Deallocate](#Deallocate)
This function returns either a universal error or one of the following errors:
[JVMDI_ERROR_INVALID_THREAD](#JVMDI%5FERROR%5FINVALID%5FTHREAD)
thread
was invalid.
[JVMDI_ERROR_NULL_POINTER](#JVMDI%5FERROR%5FNULL%5FPOINTER)
Invalid pointer.
[JVMDI_ERROR_THREAD_NOT_SUSPENDED](#JVMDI%5FERROR%5FTHREAD%5FNOT%5FSUSPENDED)
thread
must be suspended before calling.
[JVMDI_ERROR_NOT_IMPLEMENTED](#JVMDI%5FERROR%5FNOT%5FIMPLEMENTED)
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 GetCapabilitiesto 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](#JVMDI%5FERROR%5FINVALID%5FTHREAD)
thread
was invalid.
[JVMDI_ERROR_NULL_POINTER](#JVMDI%5FERROR%5FNULL%5FPOINTER)
Invalid pointer.
[JVMDI_ERROR_THREAD_NOT_SUSPENDED](#JVMDI%5FERROR%5FTHREAD%5FNOT%5FSUSPENDED)
thread
must be suspended before calling.
[JVMDI_ERROR_NOT_IMPLEMENTED](#JVMDI%5FERROR%5FNOT%5FIMPLEMENTED)
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](#JVMDI%5FERROR%5FNULL%5FPOINTER)
Invalid pointer.
[JVMDI_ERROR_INVALID_THREAD](#JVMDI%5FERROR%5FINVALID%5FTHREAD)
thread
was invalid.
[JVMDI_ERROR_INVALID_PRIORITY](#JVMDI%5FERROR%5FINVALID%5FPRIORITY)
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](#Deallocate)
This function returns one of the following error codes:
[JVMDI_ERROR_NULL_POINTER](#JVMDI%5FERROR%5FNULL%5FPOINTER)
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](#Deallocate)
This function returns one of the following error codes:
[JVMDI_ERROR_NULL_POINTER](#JVMDI%5FERROR%5FNULL%5FPOINTER)
Invalid pointer.
[JVMDI_ERROR_INVALID_THREAD_GROUP](#JVMDI%5FERROR%5FINVALID%5FTHREAD%5FGROUP)
Get Thread Group Children
jvmdiError GetThreadGroupChildren(jthreadGroup group, jint *threadCountPtr, jthread **threadsPtr, jint *groupCountPtr, jthreadGroup **groupsPtr)
Get the live threads and active thread groups created within the given thread group. A thread is alive if it has been started and has not yet been stopped. See java.lang.ThreadGroup for information about 'active' ThreadGroups.
Parameters:
group
the group to query.
threadCountPtr
on return, points to the number of alive owned threads
threadsPtr
on return, refers to a pointer to the alive owned threads 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](#Deallocate)
groupCountPtr
on return, points to the number of active child thread groups
groupsPtr
on return, refers to a pointer to the active 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](#Deallocate)
This function returns one of the following error codes:
[JVMDI_ERROR_NULL_POINTER](#JVMDI%5FERROR%5FNULL%5FPOINTER)
Invalid pointer.
[JVMDI_ERROR_INVALID_THREAD_GROUP](#JVMDI%5FERROR%5FINVALID%5FTHREAD%5FGROUP)
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](#JVMDI%5FERROR%5FINVALID%5FTHREAD)
thread
was invalid.
[JVMDI_ERROR_NULL_POINTER](#JVMDI%5FERROR%5FNULL%5FPOINTER)
Invalid pointer.
[JVMDI_ERROR_THREAD_NOT_SUSPENDED](#JVMDI%5FERROR%5FTHREAD%5FNOT%5FSUSPENDED)
Thread was not suspended.
Get Thread's Current Frame
jvmdiError GetCurrentFrame(jthread thread, jframeID *framePtr)
Get the jframeID
value for the current stack frame ofthread
and return viaframePtr
.
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](#JVMDI%5FERROR%5FINVALID%5FTHREAD)
thread
was invalid.
[JVMDI_ERROR_NULL_POINTER](#JVMDI%5FERROR%5FNULL%5FPOINTER)
Invalid pointer.
[JVMDI_ERROR_THREAD_NOT_SUSPENDED](#JVMDI%5FERROR%5FTHREAD%5FNOT%5FSUSPENDED)
Thread was not suspended.
[JVMDI_ERROR_NO_MORE_FRAMES](#JVMDI%5FERROR%5FNO%5FMORE%5FFRAMES)
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:
- suspend the thread via an event (step, breakpoint, ...)
- call
PopFrame
- resume the thread
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
ofGetCapabilitiesto 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](#JVMDI%5FERROR%5FINVALID%5FTHREAD)
thread
was invalid.
[JVMDI_ERROR_OPAQUE_FRAME](#JVMDI%5FERROR%5FOPAQUE%5FFRAME)
frame
is a native frame.
[JVMDI_ERROR_NULL_POINTER](#JVMDI%5FERROR%5FNULL%5FPOINTER)
Invalid pointer.
[JVMDI_ERROR_THREAD_NOT_SUSPENDED](#JVMDI%5FERROR%5FTHREAD%5FNOT%5FSUSPENDED)
Thread was not suspended or current thread.
[JVMDI_ERROR_NO_MORE_FRAMES](#JVMDI%5FERROR%5FNO%5FMORE%5FFRAMES)
There are no more Java programming language frames on the call stack.
[JVMDI_ERROR_NOT_IMPLEMENTED](#JVMDI%5FERROR%5FNOT%5FIMPLEMENTED)
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 viaframePtr
. 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](#JVMDI%5FERROR%5FNULL%5FPOINTER)
Invalid pointer.
[JVMDI_ERROR_INVALID_FRAMEID](#JVMDI%5FERROR%5FINVALID%5FFRAMEID)
Invalid
jframeID
.
[JVMDI_ERROR_NO_MORE_FRAMES](#JVMDI%5FERROR%5FNO%5FMORE%5FFRAMES)
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](#JVMDI%5FERROR%5FNULL%5FPOINTER)
Invalid pointer.
[JVMDI_ERROR_INVALID_FRAMEID](#JVMDI%5FERROR%5FINVALID%5FFRAMEID)
frame
is not a valid frame ID.
Notify Frame Pop
jvmdiError NotifyFramePop(jframeID frame);
When frame
is popped from the stack, generate aJVMDI_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](#JVMDI%5FERROR%5FNULL%5FPOINTER)
Invalid pointer.
[JVMDI_ERROR_INVALID_FRAMEID](#JVMDI%5FERROR%5FINVALID%5FFRAMEID)
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](#JVMDI%5FERROR%5FNULL%5FPOINTER)
Invalid pointer.
[JVMDI_ERROR_INVALID_FRAMEID](#JVMDI%5FERROR%5FINVALID%5FFRAMEID)
Invalid
frame
.
[JVMDI_ERROR_INVALID_SLOT](#JVMDI%5FERROR%5FINVALID%5FSLOT)
Invalid
slot
.
[JVMDI_ERROR_TYPE_MISMATCH](#JVMDI%5FERROR%5FTYPE%5FMISMATCH)
The variable is not an appropriate type for the function used.
[JVMDI_ERROR_OPAQUE_FRAME](#JVMDI%5FERROR%5FOPAQUE%5FFRAME)
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](#JVMDI%5FERROR%5FOPAQUE%5FFRAME)
Invalid pointer.
[JVMDI_ERROR_INVALID_FRAMEID](#JVMDI%5FERROR%5FINVALID%5FFRAMEID)
Invalid
frame
.
[JVMDI_ERROR_INVALID_SLOT](#JVMDI%5FERROR%5FINVALID%5FSLOT)
Invalid
slot
.
[JVMDI_ERROR_TYPE_MISMATCH](#JVMDI%5FERROR%5FTYPE%5FMISMATCH)
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, aJVMDI_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](#JVMDI%5FERROR%5FINVALID%5FMETHODID)
Invalid
method
.
[JVMDI_ERROR_INVALID_CLASS](#JVMDI%5FERROR%5FINVALID%5FCLASS)
Invalid
clazz
.
[JVMDI_ERROR_INVALID_LOCATION](#JVMDI%5FERROR%5FINVALID%5FLOCATION)
Invalid location.
[JVMDI_ERROR_DUPLICATE](#JVMDI%5FERROR%5FDUPLICATE)
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](#JVMDI%5FERROR%5FINVALID%5FMETHODID)
Invalid
method
.
[JVMDI_ERROR_INVALID_CLASS](#JVMDI%5FERROR%5FINVALID%5FCLASS)
Invalid
clazz
.
[JVMDI_ERROR_INVALID_LOCATION](#JVMDI%5FERROR%5FINVALID%5FLOCATION)
Invalid location.
[JVMDI_ERROR_NOT_FOUND](#JVMDI%5FERROR%5FNOT%5FFOUND)
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 eventwhen the field specified by clazz
andfield
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 SetFieldModificationWatchto monitor modifications.
This is an optional feature which may not be implemented for all virtual machines. Use GetCapabilitiesto 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](#JVMDI%5FERROR%5FINVALID%5FFIELDID)
The jfieldID specified in
field
is not a valid field ID.
[JVMDI_ERROR_INVALID_CLASS](#JVMDI%5FERROR%5FINVALID%5FCLASS)
The jclass specified in
clazz
is no a valid class.
[JVMDI_ERROR_DUPLICATE](#JVMDI%5FERROR%5FDUPLICATE)
The designated field is already being watched for accesses.
[JVMDI_ERROR_NOT_IMPLEMENTED](#JVMDI%5FERROR%5FNOT%5FIMPLEMENTED)
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
andfield
.
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](#JVMDI%5FERROR%5FINVALID%5FFIELDID)
The jfieldID specified in
field
is not a valid field ID.
[JVMDI_ERROR_INVALID_CLASS](#JVMDI%5FERROR%5FINVALID%5FCLASS)
The jclass specified in
clazz
is no a valid class.
[JVMDI_ERROR_NOT_FOUND](#JVMDI%5FERROR%5FNOT%5FFOUND)
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 eventwhen the field specified by clazz
andfield
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 GetCapabilitiesto 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](#JVMDI%5FERROR%5FINVALID%5FFIELDID)
The jfieldID specified in
field
is not a valid field ID.
[JVMDI_ERROR_INVALID_CLASS](#JVMDI%5FERROR%5FINVALID%5FCLASS)
The jclass specified in
clazz
is no a valid class.
[JVMDI_ERROR_DUPLICATE](#JVMDI%5FERROR%5FDUPLICATE)
The designated field is already being watched for modifications.
[JVMDI_ERROR_NOT_IMPLEMENTED](#JVMDI%5FERROR%5FNOT%5FIMPLEMENTED)
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
andfield
.
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](#JVMDI%5FERROR%5FINVALID%5FFIELDID)
The jfieldID specified in
field
is not a valid field ID.
[JVMDI_ERROR_INVALID_CLASS](#JVMDI%5FERROR%5FINVALID%5FCLASS)
The jclass specified in
clazz
is no a valid class.
[JVMDI_ERROR_NOT_FOUND](#JVMDI%5FERROR%5FNOT%5FFOUND)
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](#Deallocate)
This function returns either a universal error or one of the following errors:
[JVMDI_ERROR_NULL_POINTER](#JVMDI%5FERROR%5FNULL%5FPOINTER)
Invalid pointer.
[JVMDI_ERROR_INVALID_CLASS](#JVMDI%5FERROR%5FINVALID%5FCLASS)
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](#JVMDI%5FERROR%5FNULL%5FPOINTER)
Invalid pointer.
[JVMDI_ERROR_INVALID_CLASS](#JVMDI%5FERROR%5FINVALID%5FCLASS)
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](#Deallocate)
This function returns either a universal error or one of the following errors:
[JVMDI_ERROR_NULL_POINTER](#JVMDI%5FERROR%5FNULL%5FPOINTER)
Invalid pointer.
[JVMDI_ERROR_INVALID_CLASS](#JVMDI%5FERROR%5FINVALID%5FCLASS)
Invalid
clazz
.
[JVMDI_ERROR_ABSENT_INFORMATION](#JVMDI%5FERROR%5FABSENT%5FINFORMATION)
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 flagdefinitions and information aboutclass modifierscan be found in theJava 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](#JVMDI%5FERROR%5FNULL%5FPOINTER)
Invalid pointer.
[JVMDI_ERROR_INVALID_CLASS](#JVMDI%5FERROR%5FINVALID%5FCLASS)
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](#JVMDI%5FERROR%5FNULL%5FPOINTER)
Invalid pointer.
[JVMDI_ERROR_INVALID_CLASS](#JVMDI%5FERROR%5FINVALID%5FCLASS)
Invalid
clazz
.
[JVMDI_ERROR_CLASS_NOT_PREPARED](#JVMDI%5FERROR%5FCLASS%5FNOT%5FPREPARED)
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 viafieldsPtr
. 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](#JVMDI%5FERROR%5FNULL%5FPOINTER)
Invalid pointer.
[JVMDI_ERROR_INVALID_CLASS](#JVMDI%5FERROR%5FINVALID%5FCLASS)
Invalid
clazz
.
[JVMDI_ERROR_CLASS_NOT_PREPARED](#JVMDI%5FERROR%5FCLASS%5FNOT%5FPREPARED)
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](#Deallocate)
.
This function returns either a universal error or one of the following errors:
[JVMDI_ERROR_NULL_POINTER](#JVMDI%5FERROR%5FNULL%5FPOINTER)
Invalid pointer.
[JVMDI_ERROR_INVALID_CLASS](#JVMDI%5FERROR%5FINVALID%5FCLASS)
Invalid
clazz
.
[JVMDI_ERROR_CLASS_NOT_PREPARED](#JVMDI%5FERROR%5FCLASS%5FNOT%5FPREPARED)
Is an Interface
jvmdiError IsInterface(jclass clazz, jboolean *isInterfacePtr)
Determines whether a class object reference represents an interface. The jboolean
result isJNI_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](#JVMDI%5FERROR%5FNULL%5FPOINTER)
Invalid pointer.
[JVMDI_ERROR_INVALID_CLASS](#JVMDI%5FERROR%5FINVALID%5FCLASS)
Invalid
clazz
.
Is an Array
jvmdiError IsArrayClass(jclass clazz, jboolean *isArrayClassPtr)
Determines whether a class object reference represents an array. The jboolean
result isJNI_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](#JVMDI%5FERROR%5FNULL%5FPOINTER)
Invalid pointer.
[JVMDI_ERROR_INVALID_CLASS](#JVMDI%5FERROR%5FINVALID%5FCLASS)
Invalid
clazz
.
Class Loader
jvmdiError GetClassLoader(jclass clazz, jobject *classloaderPtr)
For the class indicated by clazz
, return viaclassloaderPtr
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](#JVMDI%5FERROR%5FNULL%5FPOINTER)
Invalid pointer.
[JVMDI_ERROR_INVALID_CLASS](#JVMDI%5FERROR%5FINVALID%5FCLASS)
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](#JVMDI%5FERROR%5FNULL%5FPOINTER)
Invalid pointer.
[JVMDI_ERROR_INVALID_CLASS](#JVMDI%5FERROR%5FINVALID%5FCLASS)
Invalid clazz
.
[JVMDI_ERROR_ABSENT_INFORMATION](#JVMDI%5FERROR%5FABSENT%5FINFORMATION)
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](#JVMDI%5FERROR%5FNULL%5FPOINTER)
Invalid pointer.
[JVMDI_ERROR_INVALID_OBJECT](#JVMDI%5FERROR%5FINVALID%5FOBJECT)
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 GetCapabilitiesto 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](#Deallocate)
This function returns either a universal error or one of the following errors:
[JVMDI_ERROR_INVALID_OBJECT](#JVMDI%5FERROR%5FINVALID%5FOBJECT)
thread
was invalid.
[JVMDI_ERROR_NULL_POINTER](#JVMDI%5FERROR%5FNULL%5FPOINTER)
Invalid pointer.
[JVMDI_ERROR_THREAD_NOT_SUSPENDED](#JVMDI%5FERROR%5FTHREAD%5FNOT%5FSUSPENDED)
thread must be suspended before calling.
[JVMDI_ERROR_NOT_IMPLEMENTED](#JVMDI%5FERROR%5FNOT%5FIMPLEMENTED)
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 viasignaturePtr
.
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](#Deallocate)
signaturePtr
on return, refers to a pointer to the UTF-8 field signature. The string should be freed with
[Deallocate](#Deallocate)
This function returns either a universal error or one of the following errors:
[JVMDI_ERROR_NULL_POINTER](#JVMDI%5FERROR%5FNULL%5FPOINTER)
Invalid pointer.
[JVMDI_ERROR_INVALID_FIELDID](#JVMDI%5FERROR%5FINVALID%5FFIELDID)
Invalid
field
.
[JVMDI_ERROR_INVALID_CLASS](#JVMDI%5FERROR%5FINVALID%5FCLASS)
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](#JVMDI%5FERROR%5FNULL%5FPOINTER)
Invalid pointer.
[JVMDI_ERROR_INVALID_FIELDID](#JVMDI%5FERROR%5FINVALID%5FFIELDID)
Invalid
field
.
[JVMDI_ERROR_INVALID_CLASS](#JVMDI%5FERROR%5FINVALID%5FCLASS)
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 flagdefinitions and information aboutfield modifierscan be found in theJava 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](#JVMDI%5FERROR%5FNULL%5FPOINTER)
Invalid pointer.
[JVMDI_ERROR_INVALID_FIELDID](#JVMDI%5FERROR%5FINVALID%5FFIELDID)
Invalid
method
.
[JVMDI_ERROR_INVALID_CLASS](#JVMDI%5FERROR%5FINVALID%5FCLASS)
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 GetCapabilitiesto 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](#JVMDI%5FERROR%5FNULL%5FPOINTER)
Invalid pointer.
[JVMDI_ERROR_INVALID_FIELDID](#JVMDI%5FERROR%5FINVALID%5FFIELDID)
Invalid
field
.
[JVMDI_ERROR_INVALID_CLASS](#JVMDI%5FERROR%5FINVALID%5FCLASS)
Invalid
clazz
.
[JVMDI_ERROR_NOT_IMPLEMENTED](#JVMDI%5FERROR%5FNOT%5FIMPLEMENTED)
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 viasignaturePtr
. 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](#Deallocate)
signaturePtr
on return, refers to a pointer to the UTF-8 method signature. The string should be freed with
[Deallocate](#Deallocate)
This function returns either a universal error or one of the following errors:
[JVMDI_ERROR_NULL_POINTER](#JVMDI%5FERROR%5FNULL%5FPOINTER)
Invalid pointer.
[JVMDI_ERROR_INVALID_METHODID](#JVMDI%5FERROR%5FINVALID%5FMETHODID)
Invalid
method
.
[JVMDI_ERROR_INVALID_CLASS](#JVMDI%5FERROR%5FINVALID%5FCLASS)
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](#JVMDI%5FERROR%5FNULL%5FPOINTER)
Invalid pointer.
[JVMDI_ERROR_INVALID_METHODID](#JVMDI%5FERROR%5FINVALID%5FMETHODID)
Invalid
method
.
[JVMDI_ERROR_INVALID_CLASS](#JVMDI%5FERROR%5FINVALID%5FCLASS)
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 flagdefinitions and information aboutmethod modifierscan be found in theJava 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](#JVMDI%5FERROR%5FNULL%5FPOINTER)
Invalid pointer.
[JVMDI_ERROR_INVALID_METHODID](#JVMDI%5FERROR%5FINVALID%5FMETHODID)
Invalid
method
.
[JVMDI_ERROR_INVALID_CLASS](#JVMDI%5FERROR%5FINVALID%5FCLASS)
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](#JVMDI%5FERROR%5FNULL%5FPOINTER)
Invalid pointer.
[JVMDI_ERROR_INVALID_METHODID](#JVMDI%5FERROR%5FINVALID%5FMETHODID)
Invalid
method
.
[JVMDI_ERROR_INVALID_CLASS](#JVMDI%5FERROR%5FINVALID%5FCLASS)
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](#JVMDI%5FERROR%5FNULL%5FPOINTER)
Invalid pointer.
[JVMDI_ERROR_INVALID_METHODID](#JVMDI%5FERROR%5FINVALID%5FMETHODID)
Invalid
method
.
[JVMDI_ERROR_INVALID_CLASS](#JVMDI%5FERROR%5FINVALID%5FCLASS)
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](#JVMDI%5FERROR%5FNULL%5FPOINTER)
Invalid pointer.
[JVMDI_ERROR_INVALID_METHODID](#JVMDI%5FERROR%5FINVALID%5FMETHODID)
Invalid
method
.
[JVMDI_ERROR_INVALID_CLASS](#JVMDI%5FERROR%5FINVALID%5FCLASS)
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](#JVMDI%5FERROR%5FNONE)
No error.
[JVMDI_ERROR_NULL_POINTER](#JVMDI%5FERROR%5FNULL%5FPOINTER)
Invalid pointer.
[JVMDI_ERROR_INVALID_METHODID](#JVMDI%5FERROR%5FINVALID%5FMETHODID)
Invalid
method
.
[JVMDI_ERROR_INVALID_CLASS](#JVMDI%5FERROR%5FINVALID%5FCLASS)
Invalid
clazz
.
[JVMDI_ERROR_ABSENT_INFORMATION](#JVMDI%5FERROR%5FABSENT%5FINFORMATION)
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 throughstartLocationPtr
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](#JVMDI%5FERROR%5FNULL%5FPOINTER)
Invalid pointer.
[JVMDI_ERROR_INVALID_METHODID](#JVMDI%5FERROR%5FINVALID%5FMETHODID)
Invalid
method
.
[JVMDI_ERROR_INVALID_CLASS](#JVMDI%5FERROR%5FINVALID%5FCLASS)
Invalid
clazz
.
[JVMDI_ERROR_ABSENT_INFORMATION](#JVMDI%5FERROR%5FABSENT%5FINFORMATION)
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 usingDeallocate.
This function returns either a universal error or one of the following errors:
[JVMDI_ERROR_NULL_POINTER](#JVMDI%5FERROR%5FNULL%5FPOINTER)
Invalid pointer.
[JVMDI_ERROR_INVALID_METHODID](#JVMDI%5FERROR%5FINVALID%5FMETHODID)
Invalid
method
.
[JVMDI_ERROR_INVALID_CLASS](#JVMDI%5FERROR%5FINVALID%5FCLASS)
Invalid
clazz
.
[JVMDI_ERROR_ABSENT_INFORMATION](#JVMDI%5FERROR%5FABSENT%5FINFORMATION)
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 functionDeallocate
This function returns either a universal error or one of the following errors:
[JVMDI_ERROR_NULL_POINTER](#JVMDI%5FERROR%5FNULL%5FPOINTER)
Invalid pointer.
[JVMDI_ERROR_INVALID_METHODID](#JVMDI%5FERROR%5FINVALID%5FMETHODID)
Invalid
method
.
[JVMDI_ERROR_INVALID_CLASS](#JVMDI%5FERROR%5FINVALID%5FCLASS)
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](#Deallocate)
.
This function returns either a universal error or one of the following errors:
[JVMDI_ERROR_NULL_POINTER](#JVMDI%5FERROR%5FNULL%5FPOINTER)
Invalid pointer.
[JVMDI_ERROR_INVALID_METHODID](#JVMDI%5FERROR%5FINVALID%5FMETHODID)
Invalid method.
[JVMDI_ERROR_INVALID_CLASS](#JVMDI%5FERROR%5FINVALID%5FCLASS)
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 GetCapabilitiesto 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](#JVMDI%5FERROR%5FNULL%5FPOINTER)
Invalid pointer.
[JVMDI_ERROR_INVALID_CLASS](#JVMDI%5FERROR%5FINVALID%5FCLASS)
Invalid
clazz
.
[JVMDI_ERROR_INVALID_METHODID](#JVMDI%5FERROR%5FINVALID%5FMETHODID)
Invalid
method
.
[JVMDI_ERROR_NOT_IMPLEMENTED](#JVMDI%5FERROR%5FNOT%5FIMPLEMENTED)
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](#JVMDI%5FERROR%5FNULL%5FPOINTER)
Invalid pointer.
[JVMDI_ERROR_INVALID_METHODID](#JVMDI%5FERROR%5FINVALID%5FMETHODID)
Invalid
method
.
[JVMDI_ERROR_INVALID_CLASS](#JVMDI%5FERROR%5FINVALID%5FCLASS)
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 GetCapabilitiesto 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](#JVMDI%5FERROR%5FNULL%5FPOINTER)
Invalid pointer.
[JVMDI_ERROR_INVALID_METHODID](#JVMDI%5FERROR%5FINVALID%5FMETHODID)
Invalid
method
.
[JVMDI_ERROR_INVALID_CLASS](#JVMDI%5FERROR%5FINVALID%5FCLASS)
Invalid
clazz
.
[JVMDI_ERROR_NOT_IMPLEMENTED](#JVMDI%5FERROR%5FNOT%5FIMPLEMENTED)
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](#JVMDI%5FERROR%5FNULL%5FPOINTER)
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](#JVMDI%5FERROR%5FINVALID%5FMONITOR)
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](#JVMDI%5FERROR%5FINVALID%5FMONITOR)
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](#JVMDI%5FERROR%5FINVALID%5FMONITOR)
Invalid monitor.
[JVMDI_ERROR_NOT_MONITOR_OWNER](#JVMDI%5FERROR%5FNOT%5FMONITOR%5FOWNER)
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](#JVMDI%5FERROR%5FINVALID%5FMONITOR)
Invalid monitor.
[JVMDI_ERROR_NOT_MONITOR_OWNER](#JVMDI%5FERROR%5FNOT%5FMONITOR%5FOWNER)
[JVMDI_ERROR_INTERRUPT](#JVMDI%5FERROR%5FINTERRUPT)
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](#JVMDI%5FERROR%5FINVALID%5FMONITOR)
Invalid monitor.
[JVMDI_ERROR_NOT_MONITOR_OWNER](#JVMDI%5FERROR%5FNOT%5FMONITOR%5FOWNER)
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](#JVMDI%5FERROR%5FINVALID%5FMONITOR)
Invalid monitor.
[JVMDI_ERROR_NOT_MONITOR_OWNER](#JVMDI%5FERROR%5FNOT%5FMONITOR%5FOWNER)
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.
- JVMDI_EVENT_VM_INIT
- JVMDI_EVENT_VM_DEATH
- JVMDI_EVENT_THREAD_START
- JVMDI_EVENT_CLASS_UNLOAD
The following event cannot be controlled (enabled or disabled) at the global level through this function.
- JVMDI_EVENT_SINGLE_STEP
Initially, no events are enabled at the thread level. All events except the following are enabled at the global level.
- JVMDI_EVENT_SINGLE_STEP
- JVMDI_EVENT_EXCEPTION_CATCH
- JVMDI_EVENT_METHOD_ENTRY
- JVMDI_EVENT_METHOD_EXIT 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](#JVMDI%5FERROR%5FINVALID%5FTHREAD)
If
thread
is invalid or the thread has not run.
[JVMDI_ERROR_INVALID_EVENT_TYPE](#JVMDI%5FERROR%5FINVALID%5FEVENT%5FTYPE)
If
eventType
is invalid value.
[JVMDI_ERROR_ILLEGAL_ARGUMENT](#JVMDI%5FERROR%5FILLEGAL%5FARGUMENT)
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 viaclassCountPtr
, and the array itself viaclassesPtr
. You must deallocate the array usingDeallocate()
.
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](#Deallocate)
.
This function returns either a universal error or one of the following errors:
[JVMDI_ERROR_NULL_POINTER](#JVMDI%5FERROR%5FNULL%5FPOINTER)
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 viaclassCountPtr
, and the array itself viaclassesPtr
. You must deallocate the array usingDeallocate()
.
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 callingGetLoadedClasses 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](#Deallocate)
.
This function returns either a universal error or one of the following errors:
[JVMDI_ERROR_NULL_POINTER](#JVMDI%5FERROR%5FNULL%5FPOINTER)
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 returnOBSOLETE_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 PopFrameto pop frames with OBSOLETE_METHOD_ID
s.
An original and a redefined method should be considered equivalent if:
- their bytecodes are the same except for indicies into the constant pool and
- the referenced constants are equal.
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
ofGetCapabilitiesto 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](#JVMDI%5FERROR%5FNULL%5FPOINTER)
Invalid pointer: classDefs or one of class_bytes is NULL.
[JVMDI_ERROR_INVALID_CLASS](#JVMDI%5FERROR%5FINVALID%5FCLASS)
An element of classDefs is not a valid class.
[JVMDI_ERROR_UNSUPPORTED_VERSION](#JVMDI%5FERROR%5FUNSUPPORTED%5FVERSION)
A new class file has a version number not supported by this VM.
[JVMDI_ERROR_INVALID_CLASS_FORMAT](#JVMDI%5FERROR%5FINVALID%5FCLASS%5FFORMAT)
A new class file is malformed (The VM would return a ClassFormatError).
[JVMDI_ERROR_CIRCULAR_CLASS_DEFINITION](#JVMDI%5FERROR%5FCIRCULAR%5FCLASS%5FDEFINITION)
The new class file definitions would lead to a circular definition (the VM would return a ClassCircularityError).
[JVMDI_ERROR_FAILS_VERIFICATION](#JVMDI%5FERROR%5FFAILS%5FVERIFICATION)
The class bytes fail verification.
[JVMDI_ERROR_NAMES_DONT_MATCH](#JVMDI%5FERROR%5FNAMES%5FDONT%5FMATCH)
The class name defined in the new class file is different from the name in the old class object.
[JVMDI_ERROR_NOT_IMPLEMENTED](#JVMDI%5FERROR%5FNOT%5FIMPLEMENTED)
No aspect of this functionality is implemented (can_redefine_classes capability is false).
[JVMDI_ERROR_ADD_METHOD_NOT_IMPLEMENTED](#JVMDI%5FERROR%5FADD%5FMETHOD%5FNOT%5FIMPLEMENTED)
A new class file would require adding a method, (and can_add_method capability is false).
[JVMDI_ERROR_SCHEMA_CHANGE_NOT_IMPLEMENTED](#JVMDI%5FERROR%5FSCHEMA%5FCHANGE%5FNOT%5FIMPLEMENTED)
The new class version changes fields (and can_unrestrictedly_redefine_classes is false).
[JVMDI_ERROR_HIERARCHY_CHANGE_NOT_IMPLEMENTED](#JVMDI%5FERROR%5FHIERARCHY%5FCHANGE%5FNOT%5FIMPLEMENTED)
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](#JVMDI%5FERROR%5FDELETE%5FMETHOD%5FNOT%5FIMPLEMENTED)
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](#JVMDI%5FERROR%5FCLASS%5FMODIFIERS%5FCHANGE%5FNOT%5FIMPLEMENTED)
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](#JVMDI%5FERROR%5FMETHOD%5FMODIFIERS%5FCHANGE%5FNOT%5FIMPLEMENTED)
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](#JVMDI%5FERROR%5FNULL%5FPOINTER)
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](#JVMDI%5FERROR%5FNULL%5FPOINTER)
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
- Introduction
- Single Step Event
- JVMDI_EVENT_SINGLE_STEP
- Breakpoint Event
- JVMDI_EVENT_BREAKPOINT
- Field Events
- JVMDI_EVENT_FIELD_ACCESS
- JVMDI_EVENT_FIELD_MODIFICATION
- Frame Events
- JVMDI_EVENT_FRAME_POP
- JVMDI_EVENT_METHOD_ENTRY
- JVMDI_EVENT_METHOD_EXIT
- Exception Event
- JVMDI_EVENT_EXCEPTION
- Exception Catch Event
- JVMDI_EVENT_EXCEPTION_CATCH
- User Defined Event
- JVMDI_EVENT_USER_DEFINED
- Thread Events
- JVMDI_EVENT_THREAD_END
- JVMDI_EVENT_THREAD_START
- Class Events
- JVMDI_EVENT_CLASS_LOAD
- JVMDI_EVENT_CLASS_UNLOAD
- JVMDI_EVENT_CLASS_PREPARE
- VM Initialization Event
- JVMDI_EVENT_VM_INIT
- VM Death Event
- JVMDI_EVENT_VM_DEATH
JVMDI clients can be informed of many events that occur in application programs.
To handle Events, designate a hook function with[SetEventHook](#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.
- Any exception thrown during the execution of an event hook can overwrite any current pending exception in the current application thread. Care must be taken to preserve a pending exception when an event hook makes a JNI call that might generate an exception.
- Event hook functions must be re-entrant. The JVMDI implementation does not queue events. If a JVMDI client needs to process events one at a time, it can use a raw monitor inside the event hook function to serialize event processing.
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 functionSetEventNotificationMode. 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](#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](#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](#SetFieldAccessWatch)
or with [SetFieldModificationWatch](#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. Theobject
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](#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](#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](#GetFrameLocation)
identifies the initial executable location in the method. On method exit or frame pop, the location reported by[GetFrameLocation](#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](#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](#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](#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](#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](#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](#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), theJVMDI_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
, andJVMDI_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.
JVMDI_EVENT_USER_DEFINED
JVMDI_EVENT_VM_INIT
JVMDI_EVENT_VM_DEATH
JVMDI_EVENT_THREAD_START
JVMDI_EVENT_THREAD_END
JVMDI_EVENT_CLASS_LOAD
JVMDI_EVENT_CLASS_UNLOAD
JVMDI_EVENT_CLASS_PREPARE
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 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 © 2004, 2010Oracle and/or its affiliates. All rights reserved. Send questions or comments to: java-debugger@sun.com. | ![]() |
---|