The JavaTM Virtual Machine Debug
Interface (JVMDI) is a programming interface used by debuggers and other
programming tools. It provides a way both to inspect the state and
to control the execution of applications running in the
JavaTM Virtual Machine.
JVMDI is a two-way interface. The JVMDI client can be notified of
interesting occurrences through events. The JVMDI
can query and control the application through many different
functions, either in response to events or
independent of them.
JVMDI clients run
in the same virtual machine as the application being debugged and access
JVMDI through a native interface. The native, in-process interface allows
maximal control with minimal intrusion on the part of a debugging tool.
Typically, JVMDI clients are relatively compact. They can be controlled
by a separate process which implements the bulk of a debugger's
function without interfering with the target application's normal execution.
JVMDI is one 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 many debugger tools.
See the
JPDA Homepage
for more information on Java Platform Debugger Architecture.
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 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.
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.
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.
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:
on return, points to the current status of the thread.
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 one or more of the following bit flags.
JVMDI_SUSPEND_STATUS_SUSPENDED
Thread suspended.
(java.lang.Thread.suspend() or
or SuspendThread has been called.) If this bit
is set, the status returned via statusPtr refers to the thread
status before suspension.
JVMDI_SUSPEND_STATUS_BREAK
Thread has hit a breakpoint. This bit is only set 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:
Get all running threads known to the virtual machine. Native threads which
are not attached to the VM are not included in the returned list.
Parameters:
threadsCountPtr
on return, points to the number of running threads.
threadsPtr
on return, points to an array of references, one
for each running thread.
Threads in the array are JNI global references and must be explicitly
freed with the JNI function DeleteGlobalRef.
The returned thread array should be freed with
Deallocate.
This function returns either a universal error or one of the following errors:
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:
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 explictly freed with the JNI
function DeleteGlobalRef.
The returned thread name string should be freed with
Deallocate
For JDK 1.1 implementations which don't
recognize context class loaders,
the context_class_loader field should be NULL.
This function returns either a universal error or one of the following errors:
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 explictly freed with the JNI function DeleteGlobalRef.
The owned_monitors buffer containing the array should be
freed with Deallocate
This function returns either a universal error or one of the following errors:
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 explictly freed
with the JNI function DeleteGlobalRef.
This function returns either a universal error or one of the following errors:
Starts the execution of a debugger thread. with the specifed 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 communiction 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 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:
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 explictly freed with the JNI function
DeleteGlobalRef.
The group array array buffer should be
freed with Deallocate
This function returns one of the following error codes:
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 explictly freed with the JNI
function DeleteGlobalRef.
The returned thread group name string should be freed with
Deallocate
This function returns one of the following error codes:
Get the threads and thread groups created within the given thread group.
Parameters:
group
the group to query.
threadCountPtr
on return, points to the number of owned threads
threadsPtr
on return, refers to a pointer to the owned thread array.
Returned thread array contains
global references which must be explictly freed with the JNI function
DeleteGlobalRef.
The thread array buffer should be
freed with Deallocate
groupCountPtr
on return, points to the number of child thread groups
groupsPtr
on return, refers to a pointer to the child thread group array.
Returned group array contains
global references which must be explictly freed with the JNI function
DeleteGlobalRef.
The group array array buffer should be
freed with Deallocate
This function returns one of the following error codes:
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 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:
For a Java 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:
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:
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:
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 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:
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 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:
For the class indicated by clazz, return the class signature
via sigPtr. The return value is a UTF-8 string.
The returned signature for primitive classes (for example, java.lang.Integer.TYPE)
is the signature of the corresponding primitive type (for example, "I").
Parameters:
clazz
the class to query
sigPtr
on return, refers to a pointer to the class's signature (UTF-8).
The returned signature string should be freed with
Deallocate
This function returns either a universal error or one of the following errors:
For the class indicated by clazz, return the source file
name via sourceNamePtr. The returned UTF-8 string
is a file name only and never contains a directory name.
For primitive classes (for example, java.lang.Integer.TYPE)
and for arrays this function returns
JVMDI_ERROR_ABSENT_INFORMATION.
Parameters:
clazz
the class to query
sourceNamePtr
on return, refers to a pointer to the class's source
file name (UTF-8).
The returned file name string should be freed with
Deallocate
This function returns either a universal error or one of the following errors:
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 modifers are always false.
If the class is an array class or a primitive class then its final
modifier is always true and its interface modifer 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:
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:
For the class indicated by clazz, return a count of fields
via fieldCountPtr and a list of field IDs via
fieldsPtr.
Only directly declared fields are returned (not inherited fields).
Fields are returned in the order they occur in the class file.
An empty field list is returned for array classes and primitive classes
(for example, java.lang.Integer.TYPE).
Use JNI to determine the length of an array.
Parameters:
clazz
the class to query
fieldCountPtr
on return, points to the number of fields dclared 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:
Return the direct superinterfaces of this class. For a class, this
function returns the interfaces declared in its implements
clause. For an interface, this function returns the interfaces declared in
its extends clause.
An empty interface list is returned for array classes and primitive classes
(for example, java.lang.Integer.TYPE).
Parameters:
clazz
the class to query
interfaceCountPtr
on return, points to the number of interfaces.
interfacesPtr
on return, points to the interface array.
Interfaces in the array are JNI global references and must be explicitly
freed with the JNI function DeleteGlobalRef.
The returned interface array should be freed with
Deallocate.
This function returns either a universal error or one of the following errors:
Determines whether a class object reference represents an interface.
The jboolean result is
JNI_TRUE if the "class" is actually an interface,
JNI_FALSE otherwise.
Parameters:
clazz
the class to query
isInterfacePtr
on return, points to the boolean result of this function.
This function returns either a universal error or one of the following errors:
For the class indicated by clazz, return via
classloaderPtr a reference to the class loader for the
class. If the class was not created by a class loader,
classloaderPtr points to NULL.
Parameters:
clazz
the class to query
classloaderPtr
on return, points to the class loader that loaded
this class or interface, or NULL if there it has no class loader. The
returned classloader
is a JNI global reference and
must be explicitly freed with the JNI function
DeleteGlobalRef.
This function returns either a universal error or one of the following errors:
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:
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 explictly freed with the JNI
function DeleteGlobalRef.
The returned waiter array buffer should be freed with
Deallocate
This function returns either a universal error or one of the following errors:
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:
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:
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:
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:
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:
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:
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:
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:
For the method indicated by clazz and method,
return the beginning and ending addresses through
startLocationPtr and endLocationPtr. In a
conventional byte code indexing scheme, these values are always zero
and the byte code count minus one.
Parameters:
clazz
the class to query
method
the method to query
startLocationPtr
on return, points to the first location, or
-1 if location information is not available.
endLocationPtr
on return, points to the last location,
or -1 if location information is not available.
This function returns either a universal error or one of the following errors:
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; /* upto 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 tableis 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:
For the method indicated by clazz and method,
return a table of exception handlers.
The size of the table is
returned via entryCountPtr and the table itself is
returned via tablePtr.
A table entry has this structure:
typedef struct {
jlocation start_location;
jlocation end_location;
jlocation handler_location;
jclass exception; /* if null, all exceptions */
} JVMDI_exception_handler_entry;
A call to this function may trigger class loading for the thrown exception
classes that have not yet been loaded. It should not be called while
threads are suspended.
Parameters:
clazz
the class to query
method
the method to query
entryCountPtr
on return, points to the number of entries in the table
tablePtr
on return, points to the exception handler table pointer.
The JVMDI allocator provides space
for the table. You must deallocate the table using
Deallocate().
The classes returned in the "exception" field of JVMDI_exception_handler_entry are global
references and must be explicitly freed
with the JNI function
Deallocate
This function returns either a universal error or one of the following errors:
For the method indicated by clazz and method,
return an array of exception classes the method might throw.
The number of exceptions is returned via exceptionCountPtr.
The exceptions array is returned via exceptionsPtr.
A call to this function may trigger class loading for the thrown exception
classes that have not yet been loaded. It should not be called while
threads are suspended.
Parameters:
clazz
the class to query
method
the method to query
exceptionCountPtr
on return, points to the number of running threads.
exceptionsPtr
on return, points to an array of references, one
for each thrown exception.
Exception classes in the array are JNI global references and must be explicitly
freed with the JNI function DeleteGlobalRef.
The returned exception array should be freed with
Deallocate.
This function returns either a universal error or one of the following errors:
For the method indicated by clazz and method,
return the byte codes that implement the method. The number of
bytecodes is returned via bytecodeCountPtr. The byte codes
themselves are returned via bytecodesPtr.
This is an optional feature which may not be implemented for all
virtual machines. Use GetCapabilities
to determine whether this and other features are supported in a
particular virtual machine.
Parameters:
clazz
the class to query
method
the method to query
bytecodeCountPtr
on return, points to the length of the byte code array
bytecodesPtr
on return, points to the pointer to the byte code array
The JVMDI memory
allocator provides memory for the byte code array.
You must deallocate the table using
Deallocate().
This function returns either a universal error or one of the following errors:
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:
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.
Return an array of all classes loaded in the virtual machine.
The number of classes in the array is returned via
classCountPtr, and the array itself via
classesPtr.
You must deallocate the array using
Deallocate().
Array classes of all types (including arrays of primitive types) are
included in the returned list. Primitive classes (for example,
java.lang.Integer.TYPE) are not included in this list.
Parameters:
classCountPtr
on return, points to the number of classes.
classesPtr
on return, points to an array of references, one
for each class.
Classes in the array are JNI global references and must be explicitly
freed with the JNI function DeleteGlobalRef.
The returned class array should be freed with
Deallocate.
This function returns either a universal error or one of the following errors:
Returns an array of all classes for which this class loader has
been recorded as the initiating loader. Each
class in the returned array was created by this class loader,
either by defining it directly or by delegation to another class loader.
For JDK 1.1 implementations which don't
recognize the distinction between initiating and defining classloaders,
this function should return all classes loaded in the virtual machine.
The number of classes in the array is returned via
classCountPtr, and the array itself via
classesPtr.
You must deallocate the array using
Deallocate().
The initiatingLoader argument must not be null. The set of
classes initiated by the system class loader is identical to the set of
classes defined by that loader. This set can be determined by calling
GetLoadedClasses and selecting those
classes with a null class loader.
Parameters:
initiatingLoader
the initiating class loader.
classCountPtr
on return, points to the number of classes.
classesPtr
on return, points to an array of references, one
for each class.
Classes in the array are JNI global references and must be explicitly
freed with the JNI function DeleteGlobalRef.
The returned class array should be freed with
Deallocate.
This function returns either a universal error or one of the following errors:
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:
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;
} 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:
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 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 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 clients can be informed of many events that occur in application
programs.
To handle Events, designate a hook function with
SetEventHook. For each event
the hook function will be called with a JVMDI_Event argument
describing the event type and, depending on the event, additional
information. The hook function is usually called from within application
threads and the JVMDI implementation does not queue events in any way. This means
that event hook functions must be written carefully. Here are some
general guidelines. See the individual event descriptions for further
suggestions.
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 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.
Single step events allow the JVMDI client to trace thread execution
at the finest granularity allowed by the VM. A single step event is
generated whenever a thread reaches a new location.
Typically, single step events represent the completion of one VM
instruction as defined the VM Specification; however, some implementations
may define location differently. In any case the
clazz, method, and location fields
of the event structure uniquely identify the current location and allow
the mapping to source file and line number when that information is
available.
No single step events are generated from within native methods.
Single step events are disabled by default and can be enabled for a
thread by calling
SetEventNotificationMode
Breakpoint Events are generated whenever a thread reaches a location
designated as a breakpoint with SetBreakpoint.
The
clazz, method, and location fields
of the event structure uniquely identify the current location and allow
the mapping to source file and line number when that information is
available.
Breakpoint reporting, in general, can be enabled or disabled by calling
SetEventNotificationMode
and are enabled by default. If they are disabled, set breakpoints are
ignored.
Field Events (JVMDI_EVENT_FIELD_ACCESS, JVMDI_EVENT_FIELD_MODIFICATION)
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.
Method entry events are generated upon entry of Java or native methods.
Method exit events are generated upon exit from a Java 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
identifes the
executable location in the returning method, immediately prior to the
return.
Method entry and exit are disabled by default and can be enabled by calling
SetEventNotificationMode.
Frame pop events are enabled by default and can be disabled similarly.
Exception events are generated whenever an exception is first detected
in a Java method. The exception may have been thrown by a Java or native
method, but in the case of native methods, the event is not generated
until the exception is first seen by a Java method. If an exception is
set and cleared in a native method (and thus is never visible to Java code),
no exception event is generated.
The
clazz, method, and location fields
of the event structure uniquely identify the current location
(where the exception was detected) and allow
the mapping to source file and line number when that information is
available. The exception field identifies the thrown
exception object. The catch_clazz, catch_method,
and catch_location identify the location of the catch clause,
if any, that handles thrown exception. If there is no such catch clause,
each field is set to 0. There is no guarantee that the thread will ever
reach this catch clause. If there are native methods on the call stack
between the throw location and the catch clause, the exception may
be reset by one of those native methods.
JVMDI clients
can check for this occurrence by monitoring exception
catch events
Exception events are enabled by default and can be disabled by calling
SetEventNotificationMode.
Exception catch events are generated whenever a thrown exception is caught.
If the exception is caught in a Java 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
method. Exception catch events are generated for any exception for which
a throw was detected in a Java 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 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.
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.
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.
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.
In many situations it is possible for multiple events to occur
at the same location in one thread. When this happens, all of the events
are reported through the event hook in the order specified in the
following paragraphs.
If the current location is at the entry point of a method, the
JVMDI_EVENT_METHOD_ENTRY event is reported before
any other event at the current location in the same thread.
If an exception catch has been detected at the current location,
(either because it is the beginning of a catch clause or a native method
which cleared a pending exception has returned), the
JVMDI_EVENT_EXCEPTION_CATCH event is reported before
any other event at the current location in the same thread.
If a JVMDI_EVENT_SINGLE_STEP event or
JVMDI_EVENT_BREAKPOINT event is triggered at the
current location, the event is defined to occur
immediately before the code at the current location is executed.
These events are reported before any events which are triggered
by the execution of code at the current location in the same
thread (specifically,
JVMDI_EVENT_EXCEPTION,
JVMDI_EVENT_FIELD_ACCESS, and
JVMDI_EVENT_FIELD_MODIFICATION).
If both a step and breakpoint event are triggered for the same thread and
location, the step event is reported before the breakpoint event.
If the current location is the exit point of a method (that is, the last
location before returning to the caller), the
JVMDI_EVENT_METHOD_EXIT event and
the JVMDI_EVENT_FRAME_POP event (if requested)
are reported after all other events at the current location in the same
thread. There is no specified ordering of these two events
with respect to each other.
Co-located events can be triggered during the processing of some other
event by the JVMDI client at the same location in the same thread.
If such an event, of type y, is triggered during the processing of
an event of type x, and if x
precedes y in the ordering specified above, then the co-located event
y is reported for the current thread and location. If x does not precede
y, then y is not reported for the current thread and location.
For example, if a breakpoint is set at the current location
during the processing of JVMDI_EVENT_SINGLE_STEP,
that breakpoint will be reported before the thread moves off the current
location.
The following events are never considered to be co-located with
other events.
The initial loading of a JVMDI client at VM startup can vary from VM
to VM. The following description applies to the Sun 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.
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.