JavaTM Virtual Machine Debug Interface Reference |
Introduction
Using JVMDI Functions
Errors
Handling Events
Starting a VM with a JVMDI Client
JVMDI is a two-way interface. The JVMDI client can be notified of interesting occurrences through events. The JVMDI can query and control the application through many different functions, either in response to events or independent of them.
JVMDI clients run in the same virtual machine as the application being debugged and access JVMDI through a native interface. The native, in-process interface allows maximal control with minimal intrusion on the part of a debugging tool. Typically, JVMDI clients are relatively compact. They can be controlled by a separate process which implements the bulk of a debugger's function without interfering with the target application's normal execution.
JVMDI is the lowest layer within the Java Platform Debugger Architecture. This architecture also contains higher-level, out-of-process debugger interfaces. The higher-level interfaces are more appropriate than JVMDI for most debugging tools. For more information on the Java Platform Debugger Architecture, see the Java Platform Debugger Architecture documentation for this release and the Java Platform Debugger Architecture website.
For function and constant definitions, add
#include <jvmdi.h>to your source code.
Like Java Native Interface (JNI) functions, JVMDI functions
are accessed through a function table.
The JVMDI function table can be obtained through the JNI
GetEnv
function.
For example, the following code obtains the function table for version 1
of the JVMDI.
JVMDI_Interface_1 *jvmdi; ... (*jvm)->GetEnv(jvm, &jvmdi, JVMDI_VERSION_1);
JVMDI functions always return a
jvmdiError
value
indicating return status. Some functions can return additional
values through pointers provided by the calling function.
In some cases, JVMDI functions allocate memory that your program must
explicitly deallocate. This is indicated in the individual JVMDI
function descriptions. Empty lists, arrays, sequences, etc are
returned as allocated zero length arrays (not as NULL).
JVMDI functions identify objects with JNI references. References passed to JVMDI functions can be either global or local, but they must be strong references. All references returned by JVMDI functions are strong, global references.
In the event that the JVMDI function encounters an error (any return value other than JVMDI_ERROR_NONE) the values of memory referenced by argument pointers is undefined, but no memory will have been allocated and no global references will have been allocated.
JVMDI extends the data types defined by JNI with the following:
jthread
and jthreadGroup
are subtypes of
jobject
, representing the corresponding objects;
jframeID
is a pointer type representing a single stack frame
of a suspended or current thread (it is invalid upon
the resumption of the thread); jlocation
is a 64 bit
unsigned value, representing a monotonically increasing
executable position within a method;
jvmdiError
is a jint
, discussed above.
JVMDI functions fall into these categories:
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.
jvmdiError SetAllocationHooks(JVMDI_AllocHook ahook, JVMDI_DeallocHook dhook)
Set the functions which will perform allocation and deallocation. The hook functions are defined as follows.
typedef jvmdiError (*JVMDI_AllocHook)(jlong size, jbyte** memPtr) typedef jvmdiError (*JVMDI_DeallocHook)(jbyte* buffer)
JVMDI will call ahook
to allocate memory, dhook
to
deallocate memory. This overrides JVMDI's default memory allocator. To
restore the default allocator, call
SetAllocationHooks
with ahook
and
dhook
set to NULL
.
The ahook
function should look in size
for
the number of bytes to allocate and return them via
memPtr
. The function should return
JVMDI_ERROR_NULL_POINTER if passed null pointers,
JVMDI_ERROR_OUT_OF_MEMORY if it cannot honor a memory request, and
JVMDI_ERROR_NONE otherwise.
The dhook
function should look in buffer
for the
memory to be deallocated. The function should return
JVMDI_ERROR_NULL_POINTER if passed null pointers, JVMDI_ERROR_NONE
otherwise.
Parameters:
- ahook
- the function to use for memory allocation, or NULL to revert to the default allocator.
- dhook
- the function to use for memory deallocation, or NULL to revert to the default deallocator.
SetAllocationHooks
always returns
JVMDI_ERROR_NONE
.
jvmdiError Allocate(jlong size, jbyte** memPtr)
Allocate an area of memory through the JVMDI allocator. The allocated
memory should be freed with Deallocate
.
Parameters:
- size
- the number of bytes to allocate.
- memPtr
- on return, a pointer to the beginning of the memory allocated by the allocator specified in
SetAllocationHooks
.
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
DeallocatejvmdiError Deallocate(jbyte* mem)
mem
using the JVMDI allocator. This function should
be used to deallocate any memory allocated and returned by a JVMDI function
or any memory allocated with Allocate
.
Parameters:
- mem
- a pointer to the beginning of the allocated memory.
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
jvmdiError GetThreadStatus(jthread thread, jint *threadStatusPtr, jint *suspendStatusPtr)
Get status information for a thread.
Parameters:
This function returns either a universal error or one of the following errors:
- 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()
orSuspendThread
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.
JVMDI_ERROR_INVALID_THREAD
thread
was invalid.JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
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:
This function returns either a universal error or one of the following errors:
- 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 withDeallocate
.
JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
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
.
Parameters:
- thread
- the thread to suspend
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_INVALID_THREAD
thread
was invalid.JVMDI_ERROR_THREAD_SUSPENDED
- Thread already suspended.
jvmdiError ResumeThread(jthread thread)
Resume a suspended thread. Any thread suspended through
SuspendThread
will resume
execution.
Parameters:
- thread
- the thread to resume
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_INVALID_THREAD
thread
was invalid.JVMDI_ERROR_THREAD_NOT_SUSPENDED
- Thread was not suspended.
JVMDI_ERROR_INVALID_TYPESTATE
- The state of the thread has been modified, and is now inconsistent.
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
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
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 withDeallocate
For JDK 1.1 implementations which don't recognize context class loaders, the
context_class_loader
field should be NULL.
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_INVALID_THREAD
thread
was invalid.JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
typedef struct { jint owned_monitor_count; jobject *owned_monitors; } JVMDI_owned_monitor_info; jvmdiError GetOwnedMonitorInfo(jthread thread, JVMDI_owned_monitor_info *infoPtr)
Get information about the monitors owned by the specified thread. The fields of the JVMDI_owned_monitor_info structure are filled in with details of the owned monitors. If this function is called for a thread different than the current thread, the specified thread must be suspended.
This is an optional feature which may not be implemented for all
virtual machines. Use GetCapabilities
to determine whether this and other features are supported in a
particular virtual machine.
Parameters:
- thread
- the thread to query
- infoPtr
- on return, filled with owned monitor information. Returned objects (array of owned monitors) are global references and must be explicitly freed with the JNI function
DeleteGlobalRef
. Theowned_monitors
buffer containing the array should be freed withDeallocate
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_INVALID_THREAD
thread
was invalid.JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
JVMDI_ERROR_THREAD_NOT_SUSPENDED
thread
must be suspended before calling.JVMDI_ERROR_NOT_IMPLEMENTED
- Optional feature not present in this VM.
jvmdiError GetCurrentContendedMonitor(jthread thread, jobject *monitorPtr)
Get the object, if any, whose monitor the specified thread is waiting to
enter or waiting to regain through java.lang.Object.wait
.
If this function is called for a thread different than the current thread,
the specified thread must be suspended.
This is an optional feature which may not be implemented for all
virtual machines. Use GetCapabilities
to determine whether this and other features are supported in a
particular virtual machine.
Parameters:
- thread
- the thread to query
- monitorPtr
- on return, filled with the current contended monitor, or NULL if there is none. The contended monitor object is a global reference and must be explicitly freed with the JNI function
DeleteGlobalRef
.
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_INVALID_THREAD
thread
was invalid.JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
JVMDI_ERROR_THREAD_NOT_SUSPENDED
thread
must be suspended before calling.JVMDI_ERROR_NOT_IMPLEMENTED
- Optional feature not present in this VM.
typedef void (*JVMDI_StartFunction)(void *); jvmdiError RunDebugThread(jthread thread, JVMDI_StartFunction proc, void *arg, int priority);
Starts the execution of a debugger thread. with the specified native function.
The start function is given the single argument, arg
,
and the specified
priority. This function allows the creation of debugger threads
for handling communication with another process or for handling events
without the need to load a special subclass of java.lang.Thread or
implementor of java.lang.Runnable. Instead, the created thread can completely
native. However, the created thread does require a newly created instance
of java.lang.Thread (referenced by the argument thread
) to
which it will be associated.
The thread object can be created with JNI calls, but it is recommended that
all such calls to Java programming language
code be done during debugger initialization
to avoid any interaction with the application being debugged.
The new thread is started as a daemon thread.
Upon execution of proc
, the new thread will be attached to the
VM.
Parameters:
- thread
- the thread to run
- proc
- the start function
- arg
- the argument to the start function
- priority
- the priority of the started thread. Any thread priority allowed by java.lang.Thread.setPriority can be used including
JVMDI_THREAD_MIN_PRIORITY
JVMDI_THREAD_NORM_PRIORITY
JVMDI_THREAD_MAX_PRIORITY
This function returns one of the following error codes:
JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
JVMDI_ERROR_INVALID_THREAD
thread
was invalid.JVMDI_ERROR_INVALID_PRIORITY
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 withDeallocate
This function returns one of the following error codes:
JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
typedef struct { jthreadGroup parent; char *name; /* Name in UTF-8 */ jint max_priority; jboolean is_daemon; } JVMDI_thread_group_info; jvmdiError GetThreadGroupInfo(jthreadGroup group, JVMDI_thread_group_info *infoPtr)
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 withDeallocate
This function returns one of the following error codes:
JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
JVMDI_ERROR_INVALID_THREAD_GROUP
Get the threads and thread groups created within the given thread group.jvmdiError GetThreadGroupChildren(jthreadGroup group, jint *threadCountPtr, jthread **threadsPtr, jint *groupCountPtr, jthreadGroup **groupsPtr)
Parameters:
- group
- the group to query.
- threadCountPtr
- on return, points to the number of owned threads
- threadsPtr
- on return, refers to a pointer to the owned thread array. Returned thread array contains global references which must be explicitly freed with the JNI function
DeleteGlobalRef
. The thread array buffer should be freed withDeallocate
- groupCountPtr
- on return, points to the number of child thread groups
- groupsPtr
- on return, refers to a pointer to the child thread group array. Returned group array contains global references which must be explicitly freed with the JNI function
DeleteGlobalRef
. The group array array buffer should be freed withDeallocate
This function returns one of the following error codes:
JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
JVMDI_ERROR_INVALID_THREAD_GROUP
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:
This function returns either a universal error or one of the following errors:
- thread
- The thread to query
- countPtr
- on return, points to the number of frames in the call stack.
JVMDI_ERROR_INVALID_THREAD
thread
was invalid.JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
JVMDI_ERROR_THREAD_NOT_SUSPENDED
- Thread was not suspended.
jvmdiError GetCurrentFrame(jthread thread, jframeID *framePtr)
Get the jframeID
value for the current stack frame of
thread
and return via
framePtr
.
If this function is called for a thread different than the current thread,
the specified thread must be suspended.
The returned frame ID value
remains valid only until thread
continues executing.
The thread must be in a Java programming language or JNI method.
Parameters:
This function returns either a universal error or one of the following errors:
- thread
- The thread to query
- framePtr
- on return, points to the frame ID for the current stack frame of this thread.
JVMDI_ERROR_INVALID_THREAD
thread
was invalid.JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
JVMDI_ERROR_THREAD_NOT_SUSPENDED
- Thread was not suspended.
JVMDI_ERROR_NO_MORE_FRAMES
- There are no more Java programming language or JNI frames on the call stack.
jvmdiError PopFrame(jthread thread)
Pop the topmost stack frame of thread
's stack.
Popping a frame takes you to the preceding 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:
PopFrame
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 frame may not be popped.
This is an optional feature which may not be implemented for all
virtual machines. Examine can_pop_frame
of
GetCapabilities
to determine whether this feature is supported in a
particular virtual machine.
Parameters:
This function returns either a universal error or one of the following errors:
- thread
- The thread whose top frame is to be popped.
JVMDI_ERROR_INVALID_THREAD
thread
was invalid.JVMDI_ERROR_OPAQUE_FRAME
frame
is a native frame.JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
JVMDI_ERROR_THREAD_NOT_SUSPENDED
- Thread was not suspended or current thread.
JVMDI_ERROR_NO_MORE_FRAMES
- There are no more Java programming language frames on the call stack.
JVMDI_ERROR_NOT_IMPLEMENTED
- This functionality is not implemented (can_pop_frame capability is false).
ForjvmdiError GetCallerFrame(jframeID called, jframeID *framePtr)
frame
, return the frame that called it via
framePtr
.
Both called
and the caller must be in a Java programming language or JNI
method.
Parameters:
- called
- the called frame.
- framePtr
- on return, points to the frame ID for the calling frame.
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
JVMDI_ERROR_INVALID_FRAMEID
- Invalid
jframeID
.JVMDI_ERROR_NO_MORE_FRAMES
- The caller frame is not in a Java programming language or JNI method.
jvmdiError GetFrameLocation(jframeID frame, jclass *classPtr, jmethodID *methodPtr, jlocation *locationPtr)
For a Java programming language frame, return the location of the instruction currently executing.
Parameters:
- frame
- the frame to query.
- classPtr
- on return, points to the class for the current location. The returned class is a JNI global reference must be explicitly freed with the JNI function
DeleteGlobalRef
.- methodPtr
- on return, points to the method for the current location.
- locationPtr
- on return, points to the index of the currently executing instruction.
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
JVMDI_ERROR_OPAQUE_FRAME
frame
is not a Java programming language frame.JVMDI_ERROR_INVALID_FRAMEID
frame
is not a valid frame ID.
WhenjvmdiError NotifyFramePop(jframeID frame);
frame
is popped from the stack, generate a
JVMDI_EVENT_FRAME_POP
event. See Events.
Parameters:
- frame
- the frame for which the frame pop event will be generated.
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
JVMDI_ERROR_OPAQUE_FRAME
frame
is not a Java programming language frame.JVMDI_ERROR_INVALID_FRAMEID
frame
is not a valid frame ID.
jvmdiError GetLocalObject(jframeID frame, jint slot, jobject *valuePtr)
jvmdiError GetLocalInt(jframeID frame, jint slot, jint *valuePtr)
jvmdiError GetLocalLong(jframeID frame, jint slot, jlong *valuePtr)
jvmdiError GetLocalFloat(jframeID frame, jint slot, jfloat *valuePtr)
jvmdiError GetLocalDouble(jframeID frame, jint slot, jdouble *valuePtr)
These functions are used to retrieve the value of a local variable.
GetLocalInt
can be used to retrieve int, char, byte, and
boolean values. The variable is identified by the frame containing its
value and the variable's slot number. The mapping of variables to
slot numbers can be obtained with the function
GetLocalVariableTable
.
Parameters:
- frame
- the frame containing the variable's value.
- slot
- the variable's slot number.
- valuePtr
- on return, points to the variable's value. For GetLocalObject, the returned value is a global reference and must be explicitly freed with the JNI function
DeleteGlobalRef()
.
The functions return one of the following error codes:
JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
JVMDI_ERROR_INVALID_FRAMEID
- Invalid
frame
.JVMDI_ERROR_INVALID_SLOT
- Invalid
slot
.JVMDI_ERROR_TYPE_MISMATCH
- The variable is not an appropriate type for the function used.
JVMDI_ERROR_OPAQUE_FRAME
jvmdiError SetLocalObject(jframeID frame, jint slot, jobject value)
jvmdiError SetLocalInt(jframeID frame, jint slot, jint value)
jvmdiError SetLocalLong(jframeID frame, jint slot, jlong value)
jvmdiError SetLocalFloat(jframeID frame, jint slot, jfloat value)
jvmdiError SetLocalDouble(jframeID frame, jint slot, jdouble value)
These functions are used to set the value of a local variable.
SetLocalInt
can be used to set int, char, byte, and
boolean values. The variable is identified by the frame containing its
value and the variable's slot number. The mapping of variables to
slot numbers can be obtained with the function
GetLocalVariableTable
.
Parameters:
- frame
- the frame containing the variable's value.
- slot
- the variable's slot number.
- value
- the new value for the variable
The functions return one of the following error codes:
JVMDI_ERROR_OPAQUE_FRAME
- Invalid pointer.
JVMDI_ERROR_INVALID_FRAMEID
- Invalid
frame
.JVMDI_ERROR_INVALID_SLOT
- Invalid
slot
.JVMDI_ERROR_TYPE_MISMATCH
- The variable is not an appropriate type for the function used.
jvmdiError SetBreakpoint(jclass clazz, jmethodID method, jlocation location)
Set a breakpoint at the instruction indicated by clazz
,
method
, and location
.
An instruction can only have one breakpoint.
Whenever the designated instruction is about to be executed, a
JVMDI_EVENT_BREAKPOINT
event is generated. See
Events.
Parameters:
- clazz
- the class in which to set the breakpoint
- method
- the method in which to set the breakpoint
- location
- the index of the instruction at which to set the breakpoint
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_INVALID_METHODID
- Invalid
method
.JVMDI_ERROR_INVALID_CLASS
- Invalid
clazz
.JVMDI_ERROR_INVALID_LOCATION
- Invalid location.
JVMDI_ERROR_DUPLICATE
- The designated bytecode already has a breakpoint.
jvmdiError ClearBreakpoint(jclass clazz, jmethodID method, jlocation location)
Clear the breakpoint at the bytecode indicated by clazz
,
method
, and location
.
Parameters:
- clazz
- the class in which to clear the breakpoint
- method
- the method in which to clear the breakpoint
- location
- the index of the instruction at which to clear the breakpoint
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_INVALID_METHODID
- Invalid
method
.JVMDI_ERROR_INVALID_CLASS
- Invalid
clazz
.JVMDI_ERROR_INVALID_LOCATION
- Invalid location.
JVMDI_ERROR_NOT_FOUND
- There's no breakpoint at the designated bytecode.
Clear all breakpoints in this virtual machine.jvmdiError ClearAllBreakpoints()
jvmdiError SetFieldAccessWatch(jclass clazz, jfieldID field)
Generate a JVMDI_EVENT_FIELD_ACCESS event
when the field specified
by clazz
and
field
is about to be accessed.
An event will be generated for each access of the field
until it is cancelled with
ClearFieldAccessWatch.
Field accesses from Java programming language code or from JNI are watched,
fields modified by other means are not watched.
Note that JVMDI users should be aware that their own field accesses
will trigger the watch.
A field can only have one field access watch set.
Modification of a field is not considered an access - use
SetFieldModificationWatch
to monitor modifications.
This is an optional feature which may not be implemented for all
virtual machines. Use GetCapabilities
to determine whether this and other features are supported in a
particular virtual machine.
Parameters:
- clazz
- the class containing the field to watch
- field
- the field to watch
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_INVALID_FIELDID
- The jfieldID specified in
field
is not a valid field ID.JVMDI_ERROR_INVALID_CLASS
- The jclass specified in
clazz
is no a valid class.JVMDI_ERROR_DUPLICATE
- The designated field is already being watched for accesses.
JVMDI_ERROR_NOT_IMPLEMENTED
- Optional feature not present in this VM.
jvmdiError ClearFieldAccessWatch(jclass clazz, jfieldID field)
Cancel a field access watch previously set by
SetFieldAccessWatch, on the
field specified
by clazz
and
field
.
Parameters:
- clazz
- the class containing the field to watch
- field
- the field to watch
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_INVALID_FIELDID
- The jfieldID specified in
field
is not a valid field ID.JVMDI_ERROR_INVALID_CLASS
- The jclass specified in
clazz
is no a valid class.JVMDI_ERROR_NOT_FOUND
- The designated field is not being watched for accesses.
jvmdiError SetFieldModificationWatch(jclass clazz, jfieldID field)
Generate a JVMDI_EVENT_FIELD_MODIFICATION event
when the field specified
by clazz
and
field
is about to be modified.
An event will be generated for each modification of the field
until it is cancelled with
ClearFieldModificationWatch.
Field modifications from Java programming language code or from JNI are watched,
fields modified by other means are not watched.
Note that JVMDI users should be aware that their own field modifications
will trigger the watch.
A field can only have one field modification watch set.
This is an optional feature which may not be implemented for all
virtual machines. Use GetCapabilities
to determine whether this and other features are supported in a
particular virtual machine.
Parameters:
- clazz
- the class containing the field to watch
- field
- the field to watch
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_INVALID_FIELDID
- The jfieldID specified in
field
is not a valid field ID.JVMDI_ERROR_INVALID_CLASS
- The jclass specified in
clazz
is no a valid class.JVMDI_ERROR_DUPLICATE
- The designated field is already being watched for modifications.
JVMDI_ERROR_NOT_IMPLEMENTED
- Optional feature not present in this VM.
jvmdiError ClearFieldModificationWatch(jclass clazz, jfieldID field)
Cancel a field modification watch previously set by
SetFieldModificationWatch, on the
field specified
by clazz
and
field
.
Parameters:
- clazz
- the class containing the field to watch
- field
- the field to watch
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_INVALID_FIELDID
- The jfieldID specified in
field
is not a valid field ID.JVMDI_ERROR_INVALID_CLASS
- The jclass specified in
clazz
is no a valid class.JVMDI_ERROR_NOT_FOUND
- The designated field is not being watched for modifications.
For the class indicated byjvmdiError GetClassSignature(jclass clazz, char **sigPtr)
clazz
, return the class signature
via sigPtr
. The return value is a UTF-8 string.
The returned signature for primitive classes (for example, java.lang.Integer.TYPE) is the signature of the corresponding primitive type (for example, "I").
Parameters:
- clazz
- the class to query
- sigPtr
- on return, refers to a pointer to the class's signature (UTF-8). The returned signature string should be freed with
Deallocate
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
JVMDI_ERROR_INVALID_CLASS
- Invalid
clazz
.
Get the status of the class. Zero or more of the following bits can be set.jvmdiError GetClassStatus(jclass clazz, jint *statusPtr)
JVMDI_CLASS_STATUS_VERIFIED
- Class bytecodes have been verified.
JVMDI_CLASS_STATUS_PREPARED
- Class preparation is complete.
JVMDI_CLASS_STATUS_INITIALIZED
- Class initialization is complete. Static initializer has been run.
JVMDI_CLASS_STATUS_ERROR
- Error during initialization makes class unusable.
The status value for primitive classes (for example, java.lang.Integer.TYPE) and for arrays is undefined.
Parameters:
- clazz
- the class to query
- statusPtr
- on return, points to the current state of this class as one or more of flags described above.
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
JVMDI_ERROR_INVALID_CLASS
- Invalid
clazz
.
For the class indicated byjvmdiError GetSourceFileName(jclass clazz, char **sourceNamePtr)
clazz
, return the source file
name via sourceNamePtr
. The returned UTF-8 string
is a file name only and never contains a directory name.
For primitive classes (for example, java.lang.Integer.TYPE) and for arrays this function returns JVMDI_ERROR_ABSENT_INFORMATION.
Parameters:
- clazz
- the class to query
- sourceNamePtr
- on return, refers to a pointer to the class's source file name (UTF-8). The returned file name string should be freed with
Deallocate
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
JVMDI_ERROR_INVALID_CLASS
- Invalid
clazz
.JVMDI_ERROR_ABSENT_INFORMATION
- Class information does not include a source path. This includes the case where the class is an array class or primitive class.
For the class indicated byjvmdiError GetClassModifiers(jclass clazz, jint *modifiersPtr)
clazz
, return the access
flags
via modifiersPtr
.
Access flag
definitions and information about
class modifiers
can be found in the
Java
virtual machine specification.
If the class is an array class, then its public, private and protected modifiers are the same as those of its component type. For arrays of primitives, this component type is represented by one of the primitive classes (for example, java.lang.Integer.TYPE).
If the class is a primitive class, its public modifier is always true, and its protected and private modifiers are always false.
If the class is an array class or a primitive class then its final modifier is always true and its interface modifier is always false. The values of its other modifiers are not determined by this specification.
Parameters:
- clazz
- the class to query
- modifiersPtr
- on return, points to the current access flags of this class.
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
JVMDI_ERROR_INVALID_CLASS
- Invalid
clazz
.
For the class indicated byjvmdiError GetClassMethods(jclass clazz, jint *methodCountPtr, jmethodID **methodsPtr)
clazz
, return a count of
methods via methodCountPtr
and a list of
method IDs via methodsPtr
. The method list contains
constructors and static initializers as well as true methods.
Only directly declared methods are returned (not inherited methods).
Methods are returned in the order they occur in the class file.
An empty method list is returned for array classes and primitive classes
(for example, java.lang.Integer.TYPE).
Parameters:
- clazz
- the class to query
- methodCountPtr
- on return, points to the number of methods declared in this class.
- methodsPtr
- on return, points to the method ID array. The JVMDI allocator provides memory for the array. You must deallocate the array using
Deallocate()
.
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
JVMDI_ERROR_INVALID_CLASS
- Invalid
clazz
.JVMDI_ERROR_CLASS_NOT_PREPARED
For the class indicated byjvmdiError GetClassFields(jclass clazz, jint *fieldCountPtr, jfieldID **fieldsPtr)
clazz
, return a count of fields
via fieldCountPtr
and a list of field IDs via
fieldsPtr
.
Only directly declared fields are returned (not inherited fields).
Fields are returned in the order they occur in the class file.
An empty field list is returned for array classes and primitive classes
(for example, java.lang.Integer.TYPE).
Use JNI to determine the length of an array.
Parameters:
- clazz
- the class to query
- fieldCountPtr
- on return, points to the number of fields declared in this class.
- fieldsPtr
- on return, points to the field ID array. The JVMDI allocator provides memory for the array. You must deallocate it using
Deallocate()
.
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
JVMDI_ERROR_INVALID_CLASS
- Invalid
clazz
.JVMDI_ERROR_CLASS_NOT_PREPARED
Return the direct super-interfaces of this class. For a class, this function returns the interfaces declared in itsjvmdiError GetImplementedInterfaces(jclass clazz, jint *interfaceCountPtr, jclass **interfacesPtr);
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 withDeallocate
.
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
JVMDI_ERROR_INVALID_CLASS
- Invalid
clazz
.JVMDI_ERROR_CLASS_NOT_PREPARED
Determines whether a class object reference represents an interface. ThejvmdiError IsInterface(jclass clazz, jboolean *isInterfacePtr)
jboolean
result is
JNI_TRUE
if the "class" is actually an interface,
JNI_FALSE
otherwise.
Parameters:
- clazz
- the class to query
- isInterfacePtr
- on return, points to the boolean result of this function.
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
JVMDI_ERROR_INVALID_CLASS
- Invalid
clazz
.
Determines whether a class object reference represents an array. ThejvmdiError IsArrayClass(jclass clazz, jboolean *isArrayClassPtr)
jboolean
result is
JNI_TRUE
if the class is an array,
JNI_FALSE
otherwise.
Parameters:
- clazz
- the class to query
- isArrayClassPtr
- on return, points to the boolean result of this function.
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
JVMDI_ERROR_INVALID_CLASS
- Invalid
clazz
.
For the class indicated byjvmdiError GetClassLoader(jclass clazz, jobject *classloaderPtr)
clazz
, return via
classloaderPtr
a reference to the class loader for the
class. If the class was not created by a class loader,
classloaderPtr
points to NULL
.
Parameters:
- clazz
- the class to query
- classloaderPtr
- on return, points to the class loader that loaded this class or interface, or NULL if there it has no class loader. The returned classloader is a JNI global reference and must be explicitly freed with the JNI function
DeleteGlobalRef
.
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
JVMDI_ERROR_INVALID_CLASS
- Invalid
clazz
.
For the class indicated byjvmdiError GetSourceDebugExtension(jclass clazz, char **sourceDebugExtensionPtr)
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_ERROR_INVALID_CLASS
clazz
.
JVMDI_ERROR_ABSENT_INFORMATION
For the object indicated byjvmdiError GetObjectHashCode(jobject object, jint *hashCodePtr)
object
return via hashCodePtr
a hash code that can be used in
maintaining hash table of object references. This function guarantees
the same hash code value for a particular object throughout its life
Parameters:
- object
- the object to query
- hashCodePtr
- on return, points to the object's hash code
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
JVMDI_ERROR_INVALID_OBJECT
- Invalid
object
.
typedef struct { jthread owner; jint entry_count; jint waiter_count; jthread *waiters; } JVMDI_monitor_info; jvmdiError GetMonitorInfo(jobject object, JVMDI_monitor_info *infoPtr)
Get information about the the object's monitor The fields of the JVMDI_owned_monitor_info structure are filled in with details of the monitor. Each thread that might affect the monitor state must either be suspended or must be the current thread.
This is an optional feature which may not be implemented for all
virtual machines. Use GetCapabilities
to determine whether this and other features are supported in a
particular virtual machine.
Parameters:
- object
- the object to query
- infoPtr
- on return, filled with monitor information for the specified object. Returned objects (owner, array of waiters) are global references and must be explicitly freed with the JNI function
DeleteGlobalRef
. The returned waiter array buffer should be freed withDeallocate
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_INVALID_OBJECT
thread
was invalid.JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
JVMDI_ERROR_THREAD_NOT_SUSPENDED
- thread must be suspended before calling.
JVMDI_ERROR_NOT_IMPLEMENTED
- Optional feature not present in this VM.
For the field indicated byjvmdiError GetFieldName(jclass clazz, jfieldID field, char **namePtr, char **signaturePtr)
clazz
and field
,
return the field name via namePtr
and field signature via
signaturePtr
.
Parameters:
- clazz
- the class to query
- field
- the field to query
- namePtr
- on return, refers to a pointer to the UTF-8 field name. The string should be freed with
Deallocate
- signaturePtr
- on return, refers to a pointer to the UTF-8 field signature. The string should be freed with
Deallocate
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
JVMDI_ERROR_INVALID_FIELDID
- Invalid
field
.JVMDI_ERROR_INVALID_CLASS
- Invalid
clazz
.
For the field indicated byjvmdiError GetFieldDeclaringClass(jclass clazz, jfieldID field, jclass *declaringClassPtr)
clazz
and field
return the class that defined it via declaringClassPtr
.
The declaring class will either be clazz
. a superclass, or
an implemented interface.
Parameters:
- clazz
- the class to query
- field
- the field to query
- declaringClassPtr
- on return, points to the declaring class The returned class is a JNI global reference and must be explicitly freed with freed with the JNI function
DeleteGlobalRef
.
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
JVMDI_ERROR_INVALID_FIELDID
- Invalid
field
.JVMDI_ERROR_INVALID_CLASS
- Invalid
clazz
.
For the field indicated byjvmdiError GetFieldModifiers(jclass clazz, jfieldID field, jint *modifiersPtr)
clazz
and field
return the access flags via modifiersPtr
.
Access flag
definitions and information about
field modifiers
can be found in the
Java
virtual machine specification.
Parameters:
- clazz
- the class to query
- field
- the field to query
- modifiersPtr
- on return, points to the access flags.
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
JVMDI_ERROR_INVALID_FIELDID
- Invalid
method
.JVMDI_ERROR_INVALID_CLASS
- Invalid
clazz
.
jvmdiError IsFieldSynthetic(jclass clazz, jfieldID field, jboolean *isSyntheticPtr)
For the field indicated by clazz
and field
, return a
value indicating whether the field is synthetic via isSyntheticPtr
Synthetic fields are generated by the compiler but not present in the
original source code.
This is an optional feature which may not be implemented for all
virtual machines. Use GetCapabilities
to determine whether this and other features are supported in a
particular virtual machine.
Parameters:
- clazz
- the class to query
- field
- the field to query
- isSyntheticPtr
- on return, points to the boolean result of this function.
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
JVMDI_ERROR_INVALID_FIELDID
- Invalid
field
.JVMDI_ERROR_INVALID_CLASS
- Invalid
clazz
.JVMDI_ERROR_NOT_IMPLEMENTED
- Optional feature not present in this VM.
jvmdiError GetMethodName(jclass clazz, jmethodID method, char **namePtr, char **signaturePtr)
For the method indicated by clazz
and method
,
return the method name via namePtr
and method signature via
signaturePtr
.
The signature is a JNI signature also called a method descriptor
in the Java Virtual Machine Specification; note this is different
then method signature as defined in the Java Language Specification.
Parameters:
- clazz
- the class to query
- method
- the method to query
- namePtr
- on return, refers to a pointer to the UTF-8 method name. The string should be freed with
Deallocate
- signaturePtr
- on return, refers to a pointer to the UTF-8 method signature. The string should be freed with
Deallocate
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
JVMDI_ERROR_INVALID_METHODID
- Invalid
method
.JVMDI_ERROR_INVALID_CLASS
- Invalid
clazz
.
For the method indicated byjvmdiError GetMethodDeclaringClass(jclass clazz, jmethodID method, jclass *declaringClassPtr)
clazz
and method
,
return the Class that defined it via declaringClassPtr
.
Parameters:
- clazz
- the class to query
- method
- the method to query
- declaringClassPtr
- on return, points to the declaring class The returned class is a JNI global reference and must be explicitly freed with freed with the JNI function
DeleteGlobalRef
.
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
JVMDI_ERROR_INVALID_METHODID
- Invalid
method
.JVMDI_ERROR_INVALID_CLASS
- Invalid
clazz
.
For the method indicated byjvmdiError GetMethodModifiers(jclass clazz, jmethodID method, jint *modifiersPtr)
clazz
and method
return the access flags via modifiersPtr
.
Access flag
definitions and information about
method modifiers
can be found in the
Java
virtual machine specification.
Parameters:
- clazz
- the class to query
- method
- the method to query
- modifiersPtr
- on return, points to the access flags.
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
JVMDI_ERROR_INVALID_METHODID
- Invalid
method
.JVMDI_ERROR_INVALID_CLASS
- Invalid
clazz
.
For the method indicated byjvmdiError GetMaxStack(jclass clazz, jmethodID method, jint *maxPtr)
clazz
and method
,
return via maxPtr
the maximum number of words that can be
on the stack while the method is executing.
Parameters:
- clazz
- the class to query
- method
- the method to query
- maxPtr
- on return, points to the maximum number of stack words
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
JVMDI_ERROR_INVALID_METHODID
- Invalid
method
.JVMDI_ERROR_INVALID_CLASS
- Invalid
clazz
.
For the method indicated byjvmdiError GetMaxLocals(jclass clazz, jmethodID method, jint *maxPtr);
clazz
and method
,
return via maxPtr
the number of local variable slots used
by the whole method.
Note that two-word arguments use two slots.
Parameters:
- clazz
- the class to query
- method
- the method to query
- maxPtr
- on return, points to the maximum number of local slots
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
JVMDI_ERROR_INVALID_METHODID
- Invalid
method
.JVMDI_ERROR_INVALID_CLASS
- Invalid
clazz
.
For the method indicated byjvmdiError GetArgumentsSize(jclass clazz, jmethodID method, jint *sizePtr)
clazz
and method
,
return via maxPtr
the number of local variable slots used
by the method's arguments.
Note that two-word arguments use two slots.
Parameters:
- clazz
- the class to query
- method
- the method to query
- sizePtr
- on return, points to the number of argument slots
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
JVMDI_ERROR_INVALID_METHODID
- Invalid
method
.JVMDI_ERROR_INVALID_CLASS
- Invalid
clazz
.
For the method indicated byjvmdiError GetLineNumberTable(jclass clazz, jmethodID method, jint *entryCountPtr, JVMDI_line_number_entry **tablePtr)
clazz
and method
,
return a table of source line number entries. The size of the table is
returned via entryCountPtr
and the table itself is
returned via tablePtr
.
A table entry is an instance of the following structure:
typedef struct { jlocation start_location; jint line_number; } JVMDI_line_number_entry;
Parameters:
- clazz
- the class to query
- method
- the method to query
- entryCountPtr
- on return, points to the number of entries in the table
- tablePtr
- on return, points to the line number table pointer. The JVMDI allocator provides space for the table. You must deallocate the table using
Deallocate()
.
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_NONE
- No error.
JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
JVMDI_ERROR_INVALID_METHODID
- Invalid
method
.JVMDI_ERROR_INVALID_CLASS
- Invalid
clazz
.JVMDI_ERROR_ABSENT_INFORMATION
- Class information does not include line numbers.
For the method indicated byjvmdiError GetMethodLocation(jclass clazz, jmethodID method, jlocation *startLocationPtr, jlocation *endLocationPtr)
clazz
and method
,
return the beginning and ending addresses through
startLocationPtr
and endLocationPtr
. In a
conventional byte code indexing scheme, these values are always zero
and the byte code count minus one.
Parameters:
- clazz
- the class to query
- method
- the method to query
- startLocationPtr
- on return, points to the first location, or -1 if location information is not available.
- endLocationPtr
- on return, points to the last location, or -1 if location information is not available.
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
JVMDI_ERROR_INVALID_METHODID
- Invalid
method
.JVMDI_ERROR_INVALID_CLASS
- Invalid
clazz
.JVMDI_ERROR_ABSENT_INFORMATION
- Class information does not include method sizes.
For the method indicated byjvmdiError GetLocalVariableTable(jclass clazz, jmethodID method, jint *entryCountPtr, JVMDI_local_variable_entry **tablePtr)
clazz
and method
,
return a table of local variables.
The size of the table is
returned via entryCountPtr
and the table itself is
returned via tablePtr
.
A table entry has this structure:
typedef struct { jlocation start_location; /* variable valid start_location */ jint length; /* up to start_location+length */ char *name; /* name in UTF-8 */ char *signature; /* type signature in UTF-8 */ jint slot; /* variable slot, see JVMDI_GetLocal*() */ } JVMDI_local_variable_entry;
Parameters:
- clazz
- the class to query
- method
- the method to query
- entryCountPtr
- on return, points to the number of entries in the table
- tablePtr
- on return, points to the local variable table pointer. The JVMDI allocator provides space for the table. In addition, each name and signature string in the table is allocated with the JVMDI allocator. You must deallocate these buffers using
Deallocate
.
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
JVMDI_ERROR_INVALID_METHODID
- Invalid
method
.JVMDI_ERROR_INVALID_CLASS
- Invalid
clazz
.JVMDI_ERROR_ABSENT_INFORMATION
- Class information does not include local variable information.
For the method indicated byjvmdiError GetExceptionHandlerTable(jclass clazz, jmethodID method, jint *entryCountPtr, JVMDI_exception_handler_entry **tablePtr)
clazz
and method
,
return a table of exception handlers.
The size of the table is
returned via entryCountPtr
and the table itself is
returned via tablePtr
.
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
- Invalid pointer.
JVMDI_ERROR_INVALID_METHODID
- Invalid
method
.JVMDI_ERROR_INVALID_CLASS
- Invalid
clazz
.
For the method indicated byjvmdiError GetThrownExceptions(jclass clazz, jmethodID method, jint *exceptionCountPtr, jclass **exceptionsPtr)
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 withDeallocate
.
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
JVMDI_ERROR_INVALID_METHODID
- Invalid method.
JVMDI_ERROR_INVALID_CLASS
- Invalid class.
For the method indicated byjvmdiError GetBytecodes(jclass clazz, jmethodID method, jint *bytecodeCountPtr, jbyte **bytecodesPtr)
clazz
and method
,
return the byte codes that implement the method. The number of
bytecodes is returned via bytecodeCountPtr
. The byte codes
themselves are returned via bytecodesPtr
.
This is an optional feature which may not be implemented for all
virtual machines. Use GetCapabilities
to determine whether this and other features are supported in a
particular virtual machine.
Parameters:
- clazz
- the class to query
- method
- the method to query
- bytecodeCountPtr
- on return, points to the length of the byte code array
- bytecodesPtr
- on return, points to the pointer to the byte code array The JVMDI memory allocator provides memory for the byte code array. You must deallocate the table using
Deallocate()
.
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
JVMDI_ERROR_INVALID_CLASS
- Invalid
clazz
.JVMDI_ERROR_INVALID_METHODID
- Invalid
method
.JVMDI_ERROR_NOT_IMPLEMENTED
- Optional feature not present in this VM.
jvmdiError IsMethodNative(jclass clazz, jmethodID method, jboolean *isNativePtr)
For the method indicated by clazz
and method
, return a
value indicating whether the method is native via isNativePtr
Parameters:
- clazz
- the class to query
- method
- the method to query
- isNativePtr
- on return, points to the boolean result of this function.
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
JVMDI_ERROR_INVALID_METHODID
- Invalid
method
.JVMDI_ERROR_INVALID_CLASS
- Invalid
clazz
.
jvmdiError IsMethodSynthetic(jclass clazz, jmethodID method, jboolean *isSyntheticPtr)
For the method indicated by clazz
and method
, return a
value indicating whether the method is synthetic via isSyntheticPtr
.
Synthetic methods are generated by the compiler but not present in the
original source code.
This is an optional feature which may not be implemented for all
virtual machines. Use GetCapabilities
to determine whether this and other features are supported in a
particular virtual machine.
Parameters:
- clazz
- the class to query
- method
- the method to query
- isSyntheticPtr
- on return, points to the boolean result of this function.
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
JVMDI_ERROR_INVALID_METHODID
- Invalid
method
.JVMDI_ERROR_INVALID_CLASS
- Invalid
clazz
.JVMDI_ERROR_NOT_IMPLEMENTED
- Optional feature not present in this VM.
Create a raw monitor.jvmdiError CreateRawMonitor(char *name, JVMDI_RawMonitor *monitorPtr)
Parameters:
- name
- a name in UTF-8 to identify the monitor
- monitorPtr
- on return, points to the created monitor.
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
Destroy the raw monitor.jvmdiError DestroyRawMonitor(JVMDI_RawMonitor monitor)
Parameters:
- monitor
- the monitor
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
Gain exclusive ownership of a raw monitor.jvmdiError RawMonitorEnter(JVMDI_RawMonitor monitor)
Parameters:
- monitor
- the monitor
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_INVALID_MONITOR
- Invalid monitor.
Release exclusive ownership of a raw monitor.jvmdiError RawMonitorExit(JVMDI_RawMonitor monitor)
Parameters:
- monitor
- the monitor
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_INVALID_MONITOR
- Invalid monitor.
Wait for notification of the raw monitor.jvmdiError RawMonitorWait(JVMDI_RawMonitor monitor, jlong millis)
Parameters:
- monitor
- the monitor
- millis
- the timeout, in milliseconds
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_INVALID_MONITOR
- Invalid monitor.
JVMDI_ERROR_NOT_MONITOR_OWNER
JVMDI_ERROR_INTERRUPT
Notify a single thread waiting on the raw monitor.jvmdiError RawMonitorNotify(JVMDI_RawMonitor monitor)
Parameters:
- monitor
- the monitor
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_INVALID_MONITOR
- Invalid monitor.
JVMDI_ERROR_NOT_MONITOR_OWNER
Notify all threads waiting on the raw monitor.jvmdiError RawMonitorNotifyAll(JVMDI_RawMonitor monitor)
Parameters:
- monitor
- the monitor
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_INVALID_MONITOR
- Invalid monitor.
JVMDI_ERROR_NOT_MONITOR_OWNER
Set the function to be called on every event. Details on events are described later in this document.typedef void (*JVMDI_EventHook)(JNIEnv *env , JVMDI_Event *event); jvmdiError SetEventHook(JVMDI_EventHook hook)
Parameters:
- hook
- the new event hook, or NULL to remove the existing hook.
This function returns a universal error on error.
Control the generation of events. IfjvmdiError SetEventNotificationMode(jint mode, jint eventType, jthread thread, ...)
mode
is JVMDI_ENABLE,
the event eventType
is enabled; if mode
is
JVMDI_DISABLE, the event is disabled. If thread
is NULL,
the event is enabled or disabled globally; otherwise, it is
enabled or disabled for a particular thread.
An event is generated for
a particular thread if it is enabled either at the thread or global
levels.
Global and per-thread enabling of events is independent. For example, if MethodEntry is initially disabled both globally and on each thread, MethodEntry is still disabled per-thread when it is enabled globally. When an executing thread encounters a potential event condition, an event will be sent if either that event is globally enabled OR that event is enabled for the executing thread. Thus globally enabling an event applies to threads created after the call as well.
See below for information on specific events.
The following events cannot be controlled (enabled or disabled) at the thread level through this function.
The following event cannot be controlled (enabled or disabled) at the global level through this function.
Initially, no events are enabled at the thread level. All events except the following are enabled at the global level.
Parameters:
- mode
- JVMDI_ENABLE or JVMDI_DISABLE
- eventType
- the event to control
- thread
- the thread to control, or NULL for all threads
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_INVALID_THREAD
- If
thread
is invalid or the thread has not run.JVMDI_ERROR_INVALID_EVENT_TYPE
- If
eventType
is invalid value.JVMDI_ERROR_ILLEGAL_ARGUMENT
- If
thread
argument is specified with one of the following events:
- JVMDI_EVENT_VM_INIT
- JVMDI_EVENT_VM_DEATH
- JVMDI_EVENT_THREAD_START
- JVMDI_EVENT_CLASS_UNLOAD
jvmdiError GetLoadedClasses(jint *classCountPtr, jclass **classesPtr)
Return an array of all classes loaded in the virtual machine.
The number of classes in the array is returned via
classCountPtr
, and the array itself via
classesPtr
.
You must deallocate the array using
Deallocate()
.
Array classes of all types (including arrays of primitive types) are included in the returned list. Primitive classes (for example, java.lang.Integer.TYPE) are not included in this list.
Parameters:
- classCountPtr
- on return, points to the number of classes.
- classesPtr
- on return, points to an array of references, one for each class. Classes in the array are JNI global references and must be explicitly freed with the JNI function
DeleteGlobalRef
. The returned class array should be freed withDeallocate
.
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
jvmdiError GetClassLoaderClasses(jobject initiatingLoader, jint *classCountPtr, jclass **classesPtr)
Returns an array of all classes for which this class loader has been recorded as the initiating loader. Each class in the returned array was created by this class loader, either by defining it directly or by delegation to another class loader.
For JDK 1.1 implementations which don't
recognize the distinction between initiating and defining classloaders,
this function should return all classes loaded in the virtual machine.
The number of classes in the array is returned via
classCountPtr
, and the array itself via
classesPtr
.
You must deallocate the array using
Deallocate()
.
The initiatingLoader
argument must not be null. The set of
classes initiated by the system class loader is identical to the set of
classes defined by that loader. This set can be determined by calling
GetLoadedClasses and selecting those
classes with a null class loader.
Parameters:
- initiatingLoader
- the initiating class loader.
- classCountPtr
- on return, points to the number of classes.
- classesPtr
- on return, points to an array of references, one for each class. Classes in the array are JNI global references and must be explicitly freed with the JNI function
DeleteGlobalRef
. The returned class array should be freed withDeallocate
.
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
typedef struct { jclass clazz; /* Class to be redefined */ jint class_byte_count; /* number of bytes defining class (below) */ jbyte *class_bytes; /* bytes defining class */ /* (in Class File Format of JVM spec) */ } JVMDI_class_definition; jvmdiError RedefineClasses(jint classCount, JVMDI_class_definition *classDefs)
All classes given are redefined according to the definitions
supplied. If any redefined methods have active stack frames,
those active frames continue to run the bytecodes of the original
method. The redefined methods will be used on new invokes.
Any JVMDI function or event which returns a jmethodID
, will return
OBSOLETE_METHOD_ID
when referring to the original
method (for example, when examining a stack frame where the
original method is still executing)
unless it is equivalent to the redefined method (see below).
The original method ID refers to the redefined method.
Care should be taken thoughout a JVMDI client to handle
OBSOLETE_METHOD_ID
.
If reseting of stack frames is desired, use
PopFrame
to pop frames with OBSOLETE_METHOD_ID
s.
An original and a redefined method should be considered equivalent if:
This function does not cause any initialization except that which would occur under the customary JVM semantics. In other words, redefining a class does not cause its initializers to be run. The values of preexisting static variables will remain as they were prior to the call. However, completely uninitialized (new) static variables will be assigned their default value.
If a redefined class has instances then all those instances will have the fields defined by the redefined class at the completion of the call. Preexisting fields will retain their previous values. Any new fields will have their default values; no instance initializers or constructors are run.
Threads need not be suspended.
All breakpoints in the class are cleared.
All attributes are updated.
No JVMDI events are generated by this function.
This is an optional feature which may not be implemented for all
virtual machines. Examine
can_redefine_classes, can_add_method
and
can_unrestrictedly_redefine_classes
of
GetCapabilities
to determine whether this feature is supported in a
particular virtual machine.
Parameters:
This function returns either a universal error or one of the following errors:
- classCount
- the number of classes specified in
classDefs
- classDefs
- the array of new class definitions
JVMDI_ERROR_NULL_POINTER
- Invalid pointer: classDefs or one of class_bytes is NULL.
JVMDI_ERROR_INVALID_CLASS
- An element of classDefs is not a valid class.
JVMDI_ERROR_UNSUPPORTED_VERSION
- A new class file has a version number not supported by this VM.
JVMDI_ERROR_INVALID_CLASS_FORMAT
- A new class file is malformed (The VM would return a ClassFormatError).
JVMDI_ERROR_CIRCULAR_CLASS_DEFINITION
- The new class file definitions would lead to a circular definition (the VM would return a ClassCircularityError).
JVMDI_ERROR_FAILS_VERIFICATION
- The class bytes fail verification.
JVMDI_ERROR_NAMES_DONT_MATCH
- The class name defined in the new class file is different from the name in the old class object.
JVMDI_ERROR_NOT_IMPLEMENTED
- No aspect of this functionality is implemented (can_redefine_classes capability is false).
JVMDI_ERROR_ADD_METHOD_NOT_IMPLEMENTED
- A new class file would require adding a method, (and can_add_method capability is false).
JVMDI_ERROR_SCHEMA_CHANGE_NOT_IMPLEMENTED
- The new class version changes fields (and can_unrestrictedly_redefine_classes is false).
JVMDI_ERROR_HIERARCHY_CHANGE_NOT_IMPLEMENTED
- A direct superclass is different for the new class version, or the set of directly implemented interfaces is different (and can_unrestrictedly_redefine_classes is false).
JVMDI_ERROR_DELETE_METHOD_NOT_IMPLEMENTED
- The new class version does not declare a method declared in the old class version. (and can_unrestrictedly_redefine_classes is false).
JVMDI_ERROR_CLASS_MODIFIERS_CHANGE_NOT_IMPLEMENTED
- The new version of a class has different class modifiers (public, abstract, final, ...) then the old version (and can_unrestrictedly_redefine_classes is false).
JVMDI_ERROR_METHOD_MODIFIERS_CHANGE_NOT_IMPLEMENTED
- The new version of a class has a different method modifier (public, abstract, synchronized, ...) then the old version (and can_unrestrictedly_redefine_classes is false).
Return the JVMDI version viajvmdiError GetVersionNumber(jint *versionPtr)
versionPtr
The return value is the version identifier. The low-order 16 bits represent
the minor version number. The next 12 bits represent the major version
number. The high-order 4 bits are undefined.
Parameters:
- versionPtr
- on return, points to the JVMDI version.
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
Return viatypedef 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)
capabilitiesPtr
the optional JVMDI
features supported by this implementation. The capabilities
structure contains a number of boolean flags indicating whether
the named feature is supported.
Parameters:
- capabilitiesPtr
- on return, points to the JVMDI capabilities.
This function returns either a universal error or one of the following errors:
JVMDI_ERROR_NULL_POINTER
- Invalid pointer.
Every JVMDI function returns a jvmdiError
error code.
JVMDI_ERROR_NONE
JVMDI_ERROR_OUT_OF_MEMORY
JVMDI_ERROR_ACCESS_DENIED
JVMDI_ERROR_UNATTACHED_THREAD
JVMDI_ERROR_VM_DEAD
JVMDI_ERROR_INTERNAL
JVMDI_ERROR_INVALID_THREAD
JVMDI_ERROR_INVALID_FIELDID
JVMDI_ERROR_INVALID_METHODID
JVMDI_ERROR_INVALID_LOCATION
JVMDI_ERROR_INVALID_FRAMEID
jframeID
JVMDI_ERROR_NO_MORE_FRAMES
JVMDI_ERROR_OPAQUE_FRAME
JVMDI_ERROR_NOT_CURRENT_FRAME
JVMDI_ERROR_TYPE_MISMATCH
JVMDI_ERROR_INVALID_SLOT
JVMDI_ERROR_DUPLICATE
JVMDI_ERROR_THREAD_NOT_SUSPENDED
JVMDI_ERROR_THREAD_SUSPENDED
JVMDI_ERROR_INVALID_OBJECT
JVMDI_ERROR_INVALID_CLASS
JVMDI_ERROR_CLASS_NOT_PREPARED
JVMDI_ERROR_NULL_POINTER
JVMDI_ERROR_ABSENT_INFORMATION
JVMDI_ERROR_INVALID_EVENT_TYPE
JVMDI_ERROR_NOT_IMPLEMENTED
JVMDI_ERROR_INVALID_THREAD_GROUP
JVMDI_ERROR_INVALID_PRIORITY
JVMDI_ERROR_NOT_FOUND
JVMDI_ERROR_INVALID_MONITOR
JVMDI_ERROR_ILLEGAL_ARGUMENT
JVMDI_ERROR_NOT_MONITOR_OWNER
JVMDI_ERROR_ABSENT_INFORMATION
JVMDI_ERROR_INTERRUPT
JVMDI_ERROR_INVALID_TYPESTATE
JVMDI_ERROR_UNSUPPORTED_VERSION
JVMDI_ERROR_INVALID_CLASS_FORMAT
JVMDI_ERROR_CIRCULAR_CLASS_DEFINITION
JVMDI_ERROR_ADD_METHOD_NOT_IMPLEMENTED
JVMDI_ERROR_SCHEMA_CHANGE_NOT_IMPLEMENTED
JVMDI_ERROR_FAILS_VERIFICATION
JVMDI_ERROR_HIERARCHY_CHANGE_NOT_IMPLEMENTED
JVMDI_ERROR_DELETE_METHOD_NOT_IMPLEMENTED
JVMDI_ERROR_NAMES_DONT_MATCH
JVMDI_ERROR_CLASS_MODIFIERS_CHANGE_NOT_IMPLEMENTED
JVMDI_ERROR_METHOD_MODIFIERS_CHANGE_NOT_IMPLEMENTED
To handle Events, designate a hook function with
SetEventHook
. For each event
the hook function will be called with a JVMDI_Event
argument
describing the event type and, depending on the event, additional
information. The hook function is usually called from within application
threads and the JVMDI implementation does not queue events in any way. This means
that event hook functions must be written carefully. Here are some
general guidelines. See the individual event descriptions for further
suggestions.
Some JVMDI events identify objects with JNI references.
All such references are passed to the event hook function via
the JVMDI_Event
argument. All references
in JVMDI events are JNI local references and will become invalid
after the event hook returns.
The JVMDI_Event
data structure is allocated locally and deallocated
when the event hook function returns.
Events can be enabled and disabled with the function SetEventNotificationMode. Some events are enabled at application startup; others are not. Refer to the documentation for this function for details.
A thread that generates an event does not change its execution status. If an event should cause a thread to be suspended, then the event hook function is responsible for explicitly suspending the thread with SuspendThread.
The JVMDI_Event
contains the event kind and a union of
event-specific structures containing more information.
typedef struct { jint kind; /* the discriminant */ union { /* kind = JVMDI_EVENT_SINGLE_STEP */ JVMDI_single_step_event_data single_step; /* kind = JVMDI_EVENT_BREAKPOINT */ JVMDI_breakpoint_event_data breakpoint; /* kind = JVMDI_EVENT_FRAME_POP */ /* kind = JVMDI_EVENT_METHOD_ENTRY */ /* kind = JVMDI_EVENT_METHOD_EXIT */ JVMDI_frame_event_data frame; /* kind = JVMDI_EVENT_FIELD_ACCESS */ JVMDI_field_access_event_data field_access; /* kind = JVMDI_EVENT_FIELD_MODIFICATION */ JVMDI_field_modification_event_data field_modification; /* kind = JVMDI_EVENT_EXCEPTION */ JVMDI_exception_event_data exception; /* kind = JVMDI_EVENT_EXCEPTION_CATCH */ JVMDI_exception_catch_event_data exception_catch; /* kind = JVMDI_EVENT_USER_DEFINED */ JVMDI_user_event_data user; /* kind = JVMDI_EVENT_THREAD_END or */ /* JVMDI_EVENT_THREAD_START */ JVMDI_thread_change_event_data thread_change; /* kind = JVMDI_EVENT_CLASS_LOAD, */ /* JVMDI_EVENT_CLASS_UNLOAD, or */ /* JVMDI_EVENT_CLASS_PREPARE */ JVMDI_class_event_data class_event; /* kind = JVMDI_EVENT_VM_DEATH, JVMDI_EVENT_VM_INIT */ /* no additional fields */ } u; } JVMDI_Event;
More information on specific events is given in the sections below.
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
typedef struct { jthread thread; jclass clazz; jmethodID method; jlocation location; } JVMDI_breakpoint_event_data;
Breakpoint Events are generated whenever a thread reaches a location
designated as a breakpoint with SetBreakpoint.
The
clazz
, method
, and location
fields
of the event structure uniquely identify the current location and allow
the mapping to source file and line number when that information is
available.
Breakpoint reporting, in general, can be enabled or disabled by calling
SetEventNotificationMode
and are enabled by default. If they are disabled, set breakpoints are
ignored.
/* kind = JVMDI_EVENT_FIELD_ACCESS */ typedef struct { jthread thread; jclass clazz; jmethodID method; jlocation location; jclass field_clazz; jobject object; jfieldID field; } JVMDI_field_access_event_data; /* kind = JVMDI_EVENT_FIELD_MODIFICATION */ typedef struct { jthread thread; jclass clazz; jmethodID method; jlocation location; jclass field_clazz; jobject object; jfieldID field; char signature_type; jvalue new_value; } JVMDI_field_modification_event_data;
Field Events are generated whenever a thread accesses or modifies
a field
designated as a watchpoint
with SetFieldAccessWatch
or
with
SetFieldModificationWatch
.
The clazz
, method
, and location
fields
of the event structures uniquely identify the current location and allow
the mapping to source file and line number when that information is
available. The field_clazz
and field
fields
uniquely identify the field which is being accessed or modified. The
object
identifies the containing object if the field is
an instance field. It is NULL otherwise.
Field watchpoint reporting, in general, can be enabled or disabled by calling
SetEventNotificationMode
and are enabled by default. If they are disabled, set watches are
ignored.
typedef struct { jthread thread; jclass clazz; jmethodID method; jframeID frame; } JVMDI_frame_event_data;
Method entry events are generated upon entry of Java programming language or native methods.
Method exit events are generated upon exit from a Java programming language or native methods.
Frame pop events are generated upon exit from a single method
in a single frame as specified
in a call to NotifyFramePop
.
If a method terminates by throwing an exception to its caller, neither
a method exit event nor a frame pop event will be generated. JVMDI clients
can check for this occurrence by monitoring
exception catch events
The clazz
and method
fields uniquely identify the
method being entered or exited. The frame
field provides
access to the stack frame for the method. On method entry, the location
reported by
GetFrameLocation
identifies the initial executable location in
the method. On method exit or frame pop, the location
reported by
GetFrameLocation
identifies the
executable location in the returning method, immediately prior to the
return.
Method entry and exit are disabled by default and can be enabled by calling
SetEventNotificationMode
.
Frame pop events are enabled by default and can be disabled similarly.
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
.
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
.
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.
typedef struct { jthread thread; } JVMDI_thread_change_event_data;
Thread start events are generated by a new thread before its initial
method executes. Thread end events are generated by a terminating thread
after its initial method has finished execution. A thread may be
listed in the array returned by
GetAllThreads
before its thread start event is generated and after its thread end
event is generated. It is possible for other events to be generated
for a thread before its thread start event, but no events are generated
after its thread end event.
Thread events are enabled by default and can be disabled by calling
SetEventNotificationMode
.
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
.
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.
If the current location is at the entry point of a method, the
JVMDI_EVENT_METHOD_ENTRY
event is reported before
any other event at the current location in the same thread.
If an exception catch has been detected at the current location,
(either because it is the beginning of a catch clause or a native method
which cleared a pending exception has returned), the
JVMDI_EVENT_EXCEPTION_CATCH
event is reported before
any other event at the current location in the same thread.
If a JVMDI_EVENT_SINGLE_STEP
event or
JVMDI_EVENT_BREAKPOINT
event is triggered at the
current location, the event is defined to occur
immediately before the code at the current location is executed.
These events are reported before any events which are triggered
by the execution of code at the current location in the same
thread (specifically,
JVMDI_EVENT_EXCEPTION
,
JVMDI_EVENT_FIELD_ACCESS
, and
JVMDI_EVENT_FIELD_MODIFICATION
).
If both a step and breakpoint event are triggered for the same thread and
location, the step event is reported before the breakpoint event.
If the current location is the exit point of a method (that is, the last
location before returning to the caller), the
JVMDI_EVENT_METHOD_EXIT
event and
the JVMDI_EVENT_FRAME_POP
event (if requested)
are reported after all other events at the current location in the same
thread. There is no specified ordering of these two events
with respect to each other.
Co-located events can be triggered during the processing of some other
event by the JVMDI client at the same location in the same thread.
If such an event, of type y, is triggered during the processing of
an event of type x, and if x
precedes y in the ordering specified above, then the co-located event
y is reported for the current thread and location. If x does not precede
y, then y is not reported for the current thread and location.
For example, if a breakpoint is set at the current location
during the processing of JVMDI_EVENT_SINGLE_STEP
,
that breakpoint will be reported before the thread moves off the current
location.
The following events are never considered to be co-located with other events.
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
The initial loading of a JVMDI client at VM startup can vary from VM to VM. The following description applies to the Sun J2SE SDK 1.2 classic VM for Windows and Solaris.
The following command-line arguments are required on VM startup to properly load and run JVMDI clients.
This function will be called at startup by the VM. For example, if the optionJNIEXPORT jint JNICALL JVM_OnLoad(JavaVM *vm, char *options, void *reserved)
-Xrunfoo:opt1,opt2
is specified, the VM will attempt to
load the shared library foo.dll under Windows or libfoo.so under Solaris.
It will then attempt to find JVM_OnLoad
and call it with
"opt1,opt2" as the second argument. Since the VM is not initialized
at the time of this call, there is very little that can be done safely
inside JVM_OnLoad. It can safely process the options and set an
event hook with SetEventHook. Once that
event hook is called for the VM initialization event, the JVMDI client
can complete its initialization.
Copyright © 1996-2001
Sun Microsystems, Inc.
All Rights Reserved.
Send questions or comments to: java-debugger@sun.com. |
|