/* * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions.
*/
/* * For primitive types, the type key is bounced back as is.
*/
(void)outStream_writeByte(out, typeKey); switch (typeKey) { case JDWP_TAG(BYTE):
(void)outStream_writeByte(out,
JNI_FUNC_PTR(env,GetStaticByteField)(env, clazz, field)); break;
case JDWP_TAG(CHAR):
(void)outStream_writeChar(out,
JNI_FUNC_PTR(env,GetStaticCharField)(env, clazz, field)); break;
case JDWP_TAG(FLOAT):
(void)outStream_writeFloat(out,
JNI_FUNC_PTR(env,GetStaticFloatField)(env, clazz, field)); break;
case JDWP_TAG(DOUBLE):
(void)outStream_writeDouble(out,
JNI_FUNC_PTR(env,GetStaticDoubleField)(env, clazz, field)); break;
case JDWP_TAG(INT):
(void)outStream_writeInt(out,
JNI_FUNC_PTR(env,GetStaticIntField)(env, clazz, field)); break;
case JDWP_TAG(LONG):
(void)outStream_writeLong(out,
JNI_FUNC_PTR(env,GetStaticLongField)(env, clazz, field)); break;
case JDWP_TAG(SHORT):
(void)outStream_writeShort(out,
JNI_FUNC_PTR(env,GetStaticShortField)(env, clazz, field)); break;
case JDWP_TAG(BOOLEAN):
(void)outStream_writeBoolean(out,
JNI_FUNC_PTR(env,GetStaticBooleanField)(env, clazz, field)); break;
}
}
/* * Instance methods start with the instance, thread and class, * and statics and constructors start with the class and then the * thread.
*/
env = getEnv(); if (inStream_command(in) == JDWP_COMMAND(ObjectReference, InvokeMethod)) {
instance = inStream_readObjectRef(env, in);
thread = inStream_readThreadRef(env, in);
clazz = inStream_readClassRef(env, in);
} else { /* static method or constructor */
instance = NULL;
clazz = inStream_readClassRef(env, in);
thread = inStream_readThreadRef(env, in);
}
/* * ... and the rest of the packet is identical for all commands
*/
method = inStream_readMethodID(in);
argumentCount = inStream_readInt(in); if (inStream_error(in)) { return JNI_TRUE;
}
/* If count == 0, don't try and allocate 0 bytes, you'll get NULL */ if ( argumentCount > 0 ) { int i; /*LINTED*/
arguments = jvmtiAllocate(argumentCount * (jint)sizeof(*arguments)); if (arguments == NULL) {
outStream_setError(out, JDWP_ERROR(OUT_OF_MEMORY)); return JNI_TRUE;
} for (i = 0; (i < argumentCount) && !inStream_error(in); i++) {
arguments[i] = inStream_readValue(in);
} if (inStream_error(in)) { return JNI_TRUE;
}
}
options = inStream_readInt(in); if (inStream_error(in)) { if ( arguments != NULL ) {
jvmtiDeallocate(arguments);
} return JNI_TRUE;
}
/* * Request the invoke. If there are no errors in the request, * the interrupting thread will actually do the invoke and a * reply will be generated subsequently, so we don't reply here.
*/
error = invoker_requestInvoke(invokeType, (jbyte)options, inStream_id(in),
thread, clazz, method,
instance, arguments, argumentCount); if (error != JVMTI_ERROR_NONE) {
outStream_setError(out, map2jdwpError(error)); if ( arguments != NULL ) {
jvmtiDeallocate(arguments);
} return JNI_TRUE;
}
int
filterDebugThreads(jthread *threads, int count)
{ int i; int current;
/* Squish out all of the debugger-spawned threads */ for (i = 0, current = 0; i < count; i++) {
jthread thread = threads[i]; if (!threadControl_isDebugThread(thread)) { if (i > current) {
threads[current] = thread;
}
current++;
}
} return current;
}
jbyte
referenceTypeTag(jclass clazz)
{
jbyte tag;
if (isInterface(clazz)) {
tag = JDWP_TYPE_TAG(INTERFACE);
} elseif (isArrayClass(clazz)) {
tag = JDWP_TYPE_TAG(ARRAY);
} else {
tag = JDWP_TYPE_TAG(CLASS);
}
return tag;
}
/** * Get field modifiers
*/
jvmtiError
fieldModifiers(jclass clazz, jfieldID field, jint *pmodifiers)
{
jvmtiError error;
/* Returns the start and end locations of the specified method. */
jvmtiError
methodLocation(jmethodID method, jlocation *ploc1, jlocation *ploc2)
{
jvmtiError error;
/* * Get the return type key of the method * V or B C D F I J S Z L [
*/
jvmtiError
methodReturnType(jmethodID method, char *typeKey)
{ char *signature;
jvmtiError error;
/* * Make the debugger thread a daemon
*/
JNI_FUNC_PTR(env,CallVoidMethod)
(env, thread, gdata->threadSetDaemon, JNI_TRUE); if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) {
JNI_FUNC_PTR(env,ExceptionClear)(env);
error = AGENT_ERROR_JNI_EXCEPTION; goto err;
}
error = threadControl_addDebugThread(thread); if (error == JVMTI_ERROR_NONE) { /* * Debugger threads need cycles in all sorts of strange * situations (e.g. infinite cpu-bound loops), so give the * thread a high priority. Note that if the VM has an application * thread running at the max priority, there is still a chance * that debugger threads will be starved. (There needs to be * a way to give debugger threads a priority higher than any * application thread).
*/
error = JVMTI_FUNC_PTR(gdata->jvmti,RunAgentThread)
(gdata->jvmti, thread, func, arg,
JVMTI_THREAD_MAX_PRIORITY);
}
err: ;
} END_WITH_LOCAL_REFS(env);
return error;
}
jvmtiError
jvmtiGetCapabilities(jvmtiCapabilities *caps)
{ if ( gdata->vmDead ) { return AGENT_ERROR_VM_DEAD;
} if (!gdata->haveCachedJvmtiCapabilities) {
jvmtiError error;
staticvoid
handleInterrupt(void)
{ /* * An interrupt is handled: * * 1) for running application threads by deferring the interrupt * until the current event handler has concluded. * * 2) for debugger threads by ignoring the interrupt; this is the * most robust solution since debugger threads don't use interrupts * to signal any condition. * * 3) for application threads that have not started or already * ended by ignoring the interrupt. In the former case, the application * is relying on timing to determine whether or not the thread sees * the interrupt; in the latter case, the interrupt is meaningless.
*/
jthread thread = threadControl_currentThread(); if ((thread != NULL) && (!threadControl_isDebugThread(thread))) {
threadControl_setPendingInterrupt(thread);
}
}
static jvmtiError
ignore_vm_death(jvmtiError error)
{ if (error == JVMTI_ERROR_WRONG_PHASE) {
LOG_MISC(("VM_DEAD, in debugMonitor*()?")); return JVMTI_ERROR_NONE; /* JVMTI does this, not JVMDI? */
} return error;
}
/* * According to the JLS (17.8), here we have * either : * a- been notified * b- gotten a spurious wakeup * c- been interrupted * If both a and c have happened, the VM must choose * which way to return - a or c. If it chooses c * then the notify is gone - either to some other * thread that is also waiting, or it is dropped * on the floor. * * a is what we expect. b won't hurt us any - * callers should be programmed to handle * spurious wakeups. In case of c, * then the interrupt has been cleared, but * we don't want to consume it. It came from * user code and is intended for user code, not us. * So, we will remember that the interrupt has * occurred and re-activate it when this thread * goes back into user code. * That being said, what do we do here? Since * we could have been notified too, here we will * just pretend that we have been. It won't hurt * anything to return in the same way as if * we were notified since callers have to be able to * handle spurious wakeups anyway.
*/ if (error == JVMTI_ERROR_INTERRUPT) {
handleInterrupt();
error = JVMTI_ERROR_NONE;
}
error = ignore_vm_death(error); if (error != JVMTI_ERROR_NONE) {
EXIT_ERROR(error, "on raw monitor wait");
}
}
error = JVMTI_FUNC_PTR(gdata->jvmti,DestroyRawMonitor)
(gdata->jvmti, monitor);
error = ignore_vm_death(error); if (error != JVMTI_ERROR_NONE) {
EXIT_ERROR(error, "on destruction of raw monitor");
}
}
/** * Return array of all threads (must be inside a WITH_LOCAL_REFS)
*/
jthread *
allThreads(jint *count)
{
jthread *threads;
jvmtiError error;
*count = 0;
threads = NULL;
error = JVMTI_FUNC_PTR(gdata->jvmti,GetAllThreads)
(gdata->jvmti, count, &threads); if (error == AGENT_ERROR_OUT_OF_MEMORY) { return NULL; /* Let caller deal with no memory? */
} if (error != JVMTI_ERROR_NONE) {
EXIT_ERROR(error, "getting all threads");
} return threads;
}
/** * Fill the passed in structure with thread group info. * name field is JVMTI allocated. parent is global ref.
*/ void
threadGroupInfo(jthreadGroup group, jvmtiThreadGroupInfo *info)
{
jvmtiError error;
error = JVMTI_FUNC_PTR(gdata->jvmti,GetThreadGroupInfo)
(gdata->jvmti, group, info); if (error != JVMTI_ERROR_NONE) {
EXIT_ERROR(error, "on getting thread group info");
}
}
error = JVMTI_FUNC_PTR(gdata->jvmti,IsFieldSynthetic)
(gdata->jvmti, clazz, field, psynthetic); if ( error == JVMTI_ERROR_MUST_POSSESS_CAPABILITY ) { /* If the query is not supported, we assume it is not synthetic. */
*psynthetic = JNI_FALSE; return JVMTI_ERROR_NONE;
} return error;
}
error = JVMTI_FUNC_PTR(gdata->jvmti,IsMethodSynthetic)
(gdata->jvmti, method, psynthetic); if ( error == JVMTI_ERROR_MUST_POSSESS_CAPABILITY ) { /* If the query is not supported, we assume it is not synthetic. */
*psynthetic = JNI_FALSE; return JVMTI_ERROR_NONE;
} return error;
}
/* Get all loaded classes for a loader (must be inside a WITH_LOCAL_REFS) */
jvmtiError
allClassLoaderClasses(jobject loader, jclass **ppclasses, jint *pcount)
{
jvmtiError error;
static jboolean
is_a_nested_class(char *outer_sig, int outer_sig_len, char *sig, int sep)
{ char *inner;
/* Assumed outer class signature is "LOUTERCLASSNAME;" * inner class signature is "LOUTERCLASSNAME$INNERNAME;" * * INNERNAME can take the form: * [0-9][1-9]* anonymous class somewhere in the file * [0-9][1-9]*NAME local class somewhere in the OUTER class * NAME nested class in OUTER * * If NAME itself contains a $ (sep) then classname is further nested * inside another class. *
*/
/* Check prefix first */ if ( strncmp(sig, outer_sig, outer_sig_len-1) != 0 ) { return JNI_FALSE;
}
/* Prefix must be followed by a $ (sep) */ if ( sig[outer_sig_len-1] != sep ) { return JNI_FALSE; /* No sep follows the match, must not be nested. */
}
/* Walk past any digits, if we reach the end, must be pure anonymous */
inner = sig + outer_sig_len; #if 1 /* We want to return local classes */ while ( *inner && isdigit(*inner) ) {
inner++;
} /* But anonymous class names can't be trusted. */ if ( *inner == ';' ) { return JNI_FALSE; /* A pure anonymous class */
} #else if ( *inner && isdigit(*inner) ) { return JNI_FALSE; /* A pure anonymous or local class */
} #endif
/* Nested deeper? */ if ( strchr(inner, sep) != NULL ) { return JNI_FALSE; /* Nested deeper than we want? */
} return JNI_TRUE;
}
/* Get all nested classes for a class (must be inside a WITH_LOCAL_REFS) */
jvmtiError
allNestedClasses(jclass parent_clazz, jclass **ppnested, jint *pcount)
{
jvmtiError error;
jobject parent_loader;
jclass *classes; char *signature;
size_t len;
jint count;
jint ncount; int i;
void
createLocalRefSpace(JNIEnv *env, jint capacity)
{ /* * Save current exception since it might get overwritten by * the calls below. Note we must depend on space in the existing * frame because asking for a new frame may generate an exception.
*/
jobject throwable = JNI_FUNC_PTR(env,ExceptionOccurred)(env);
/* * Use the current frame if necessary; otherwise create a new one
*/ if (JNI_FUNC_PTR(env,PushLocalFrame)(env, capacity) < 0) {
EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY,"PushLocalFrame: Unable to push JNI frame");
}
/* * TO DO: This could be more efficient if it used EnsureLocalCapacity, * but that would not work if two functions on the call stack * use this function. We would need to either track reserved * references on a per-thread basis or come up with a convention * that would prevent two functions from depending on this function * at the same time.
*/
/* * Restore exception state from before call
*/ if (throwable != NULL) {
JNI_FUNC_PTR(env,Throw)(env, throwable);
} else {
JNI_FUNC_PTR(env,ExceptionClear)(env);
}
}
/** * Return property value as jstring
*/ static jstring
getPropertyValue(JNIEnv *env, char *propertyName)
{
jstring valueString;
jstring nameString;
valueString = NULL;
/* Create new String object to hold the property name */
nameString = JNI_FUNC_PTR(env,NewStringUTF)(env, propertyName); if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) {
JNI_FUNC_PTR(env,ExceptionClear)(env); /* NULL will be returned below */
} else { /* Call valueString = System.getProperty(nameString) */
valueString = JNI_FUNC_PTR(env,CallStaticObjectMethod)
(env, gdata->systemClass, gdata->systemGetProperty, nameString); if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) {
JNI_FUNC_PTR(env,ExceptionClear)(env);
valueString = NULL;
}
} return valueString;
}
/** * Set an agent property
*/ void
setAgentPropertyValue(JNIEnv *env, char *propertyName, char* propertyValue)
{
jstring nameString;
jstring valueString;
if (gdata->agent_properties == NULL) { /* VMSupport doesn't exist; so ignore */ return;
}
/* Create jstrings for property name and value */
nameString = JNI_FUNC_PTR(env,NewStringUTF)(env, propertyName); if (nameString != NULL) { /* convert the value to UTF8 */ int len; char *utf8value; int utf8maxSize;
len = (int)strlen(propertyValue);
utf8maxSize = len * 4 + 1;
utf8value = (char *)jvmtiAllocate(utf8maxSize); if (utf8value != NULL) {
utf8FromPlatform(propertyValue, len, (jbyte *)utf8value, utf8maxSize);
valueString = JNI_FUNC_PTR(env, NewStringUTF)(env, utf8value);
jvmtiDeallocate(utf8value);
/** * Return property value as JDWP allocated string in UTF8 encoding
*/ staticchar *
getPropertyUTF8(JNIEnv *env, char *propertyName)
{
jvmtiError error; char *value;
value = NULL;
error = JVMTI_FUNC_PTR(gdata->jvmti,GetSystemProperty)
(gdata->jvmti, (constchar *)propertyName, &value); if (error != JVMTI_ERROR_NONE) {
jstring valueString;
value = NULL;
valueString = getPropertyValue(env, propertyName);
if (valueString != NULL) { constchar *utf;
/* Get the UTF8 encoding for this property value string */
utf = JNI_FUNC_PTR(env,GetStringUTFChars)(env, valueString, NULL); /* Make a copy for returning, release the JNI copy */
value = jvmtiAllocate((int)strlen(utf) + 1); if (value != NULL) {
(void)strcpy(value, utf);
}
JNI_FUNC_PTR(env,ReleaseStringUTFChars)(env, valueString, utf);
}
} if ( value == NULL ) {
ERROR_MESSAGE(("JDWP Can't get property value for %s", propertyName));
EXIT_ERROR(AGENT_ERROR_NULL_POINTER,NULL);
} return value;
}
/* Rarely needed, transport library uses JDWP errors, only use? */
jvmtiError
map2jvmtiError(jdwpError error)
{ switch ( error ) { case JDWP_ERROR(NONE): return JVMTI_ERROR_NONE; case JDWP_ERROR(INVALID_THREAD): return JVMTI_ERROR_INVALID_THREAD; case JDWP_ERROR(INVALID_THREAD_GROUP): return JVMTI_ERROR_INVALID_THREAD_GROUP; case JDWP_ERROR(INVALID_PRIORITY): return JVMTI_ERROR_INVALID_PRIORITY; case JDWP_ERROR(THREAD_NOT_SUSPENDED): return JVMTI_ERROR_THREAD_NOT_SUSPENDED; case JDWP_ERROR(THREAD_SUSPENDED): return JVMTI_ERROR_THREAD_SUSPENDED; case JDWP_ERROR(INVALID_OBJECT): return JVMTI_ERROR_INVALID_OBJECT; case JDWP_ERROR(INVALID_CLASS): return JVMTI_ERROR_INVALID_CLASS; case JDWP_ERROR(CLASS_NOT_PREPARED): return JVMTI_ERROR_CLASS_NOT_PREPARED; case JDWP_ERROR(INVALID_METHODID): return JVMTI_ERROR_INVALID_METHODID; case JDWP_ERROR(INVALID_LOCATION): return JVMTI_ERROR_INVALID_LOCATION; case JDWP_ERROR(INVALID_FIELDID): return JVMTI_ERROR_INVALID_FIELDID; case JDWP_ERROR(INVALID_FRAMEID): return AGENT_ERROR_INVALID_FRAMEID; case JDWP_ERROR(NO_MORE_FRAMES): return JVMTI_ERROR_NO_MORE_FRAMES; case JDWP_ERROR(OPAQUE_FRAME): return JVMTI_ERROR_OPAQUE_FRAME; case JDWP_ERROR(NOT_CURRENT_FRAME): return AGENT_ERROR_NOT_CURRENT_FRAME; case JDWP_ERROR(TYPE_MISMATCH): return JVMTI_ERROR_TYPE_MISMATCH; case JDWP_ERROR(INVALID_SLOT): return JVMTI_ERROR_INVALID_SLOT; case JDWP_ERROR(DUPLICATE): return JVMTI_ERROR_DUPLICATE; case JDWP_ERROR(NOT_FOUND): return JVMTI_ERROR_NOT_FOUND; case JDWP_ERROR(INVALID_MONITOR): return JVMTI_ERROR_INVALID_MONITOR; case JDWP_ERROR(NOT_MONITOR_OWNER): return JVMTI_ERROR_NOT_MONITOR_OWNER; case JDWP_ERROR(INTERRUPT): return JVMTI_ERROR_INTERRUPT; case JDWP_ERROR(INVALID_CLASS_FORMAT): return JVMTI_ERROR_INVALID_CLASS_FORMAT; case JDWP_ERROR(CIRCULAR_CLASS_DEFINITION): return JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION; case JDWP_ERROR(FAILS_VERIFICATION): return JVMTI_ERROR_FAILS_VERIFICATION; case JDWP_ERROR(ADD_METHOD_NOT_IMPLEMENTED): return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED; case JDWP_ERROR(SCHEMA_CHANGE_NOT_IMPLEMENTED): return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED; case JDWP_ERROR(INVALID_TYPESTATE): return JVMTI_ERROR_INVALID_TYPESTATE; case JDWP_ERROR(HIERARCHY_CHANGE_NOT_IMPLEMENTED): return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED; case JDWP_ERROR(DELETE_METHOD_NOT_IMPLEMENTED): return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED; case JDWP_ERROR(UNSUPPORTED_VERSION): return JVMTI_ERROR_UNSUPPORTED_VERSION; case JDWP_ERROR(NAMES_DONT_MATCH): return JVMTI_ERROR_NAMES_DONT_MATCH; case JDWP_ERROR(CLASS_MODIFIERS_CHANGE_NOT_IMPLEMENTED): return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED; case JDWP_ERROR(METHOD_MODIFIERS_CHANGE_NOT_IMPLEMENTED): return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED; case JDWP_ERROR(CLASS_ATTRIBUTE_CHANGE_NOT_IMPLEMENTED): return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_ATTRIBUTE_CHANGED; case JDWP_ERROR(NOT_IMPLEMENTED): return JVMTI_ERROR_NOT_AVAILABLE; case JDWP_ERROR(NULL_POINTER): return JVMTI_ERROR_NULL_POINTER; case JDWP_ERROR(ABSENT_INFORMATION): return JVMTI_ERROR_ABSENT_INFORMATION; case JDWP_ERROR(INVALID_EVENT_TYPE): return JVMTI_ERROR_INVALID_EVENT_TYPE; case JDWP_ERROR(ILLEGAL_ARGUMENT): return JVMTI_ERROR_ILLEGAL_ARGUMENT; case JDWP_ERROR(OUT_OF_MEMORY): return JVMTI_ERROR_OUT_OF_MEMORY; case JDWP_ERROR(ACCESS_DENIED): return JVMTI_ERROR_ACCESS_DENIED; case JDWP_ERROR(VM_DEAD): return JVMTI_ERROR_WRONG_PHASE; case JDWP_ERROR(UNATTACHED_THREAD): return JVMTI_ERROR_UNATTACHED_THREAD; case JDWP_ERROR(INVALID_TAG): return AGENT_ERROR_INVALID_TAG; case JDWP_ERROR(ALREADY_INVOKING): return AGENT_ERROR_ALREADY_INVOKING; case JDWP_ERROR(INVALID_INDEX): return AGENT_ERROR_INVALID_INDEX; case JDWP_ERROR(INVALID_LENGTH): return AGENT_ERROR_INVALID_LENGTH; case JDWP_ERROR(INVALID_STRING): return AGENT_ERROR_INVALID_STRING; case JDWP_ERROR(INVALID_CLASS_LOADER): return AGENT_ERROR_INVALID_CLASS_LOADER; case JDWP_ERROR(INVALID_ARRAY): return AGENT_ERROR_INVALID_ARRAY; case JDWP_ERROR(TRANSPORT_LOAD): return AGENT_ERROR_TRANSPORT_LOAD; case JDWP_ERROR(TRANSPORT_INIT): return AGENT_ERROR_TRANSPORT_INIT; case JDWP_ERROR(NATIVE_METHOD): return AGENT_ERROR_NATIVE_METHOD; case JDWP_ERROR(INVALID_COUNT): return AGENT_ERROR_INVALID_COUNT; case JDWP_ERROR(INTERNAL): return AGENT_ERROR_JDWP_INTERNAL;
} return AGENT_ERROR_INTERNAL;
}
char*
eventIndex2EventName(EventIndex ei)
{ switch ( ei ) { case EI_SINGLE_STEP: return"EI_SINGLE_STEP"; case EI_BREAKPOINT: return"EI_BREAKPOINT"; case EI_FRAME_POP: return"EI_FRAME_POP"; case EI_EXCEPTION: return"EI_EXCEPTION"; case EI_THREAD_START: return"EI_THREAD_START"; case EI_THREAD_END: return"EI_THREAD_END"; case EI_CLASS_PREPARE: return"EI_CLASS_PREPARE"; case EI_CLASS_UNLOAD: return"EI_CLASS_UNLOAD"; case EI_CLASS_LOAD: return"EI_CLASS_LOAD"; case EI_FIELD_ACCESS: return"EI_FIELD_ACCESS"; case EI_FIELD_MODIFICATION: return"EI_FIELD_MODIFICATION"; case EI_EXCEPTION_CATCH: return"EI_EXCEPTION_CATCH"; case EI_METHOD_ENTRY: return"EI_METHOD_ENTRY"; case EI_METHOD_EXIT: return"EI_METHOD_EXIT"; case EI_MONITOR_CONTENDED_ENTER: return"EI_MONITOR_CONTENDED_ENTER"; case EI_MONITOR_CONTENDED_ENTERED: return"EI_MONITOR_CONTENDED_ENTERED"; case EI_MONITOR_WAIT: return"EI_MONITOR_WAIT"; case EI_MONITOR_WAITED: return"EI_MONITOR_WAITED"; case EI_VM_INIT: return"EI_VM_INIT"; case EI_VM_DEATH: return"EI_VM_DEATH"; case EI_VIRTUAL_THREAD_START: return"EI_VIRTUAL_THREAD_START"; case EI_VIRTUAL_THREAD_END: return"EI_VIRTUAL_THREAD_END"; default:
JDI_ASSERT(JNI_FALSE); return"Bad EI";
}
}
#endif
EventIndex
jdwp2EventIndex(jdwpEvent eventType)
{ switch ( eventType ) { case JDWP_EVENT(SINGLE_STEP): return EI_SINGLE_STEP; case JDWP_EVENT(BREAKPOINT): return EI_BREAKPOINT; case JDWP_EVENT(FRAME_POP): return EI_FRAME_POP; case JDWP_EVENT(EXCEPTION): return EI_EXCEPTION; case JDWP_EVENT(THREAD_START): return EI_THREAD_START; case JDWP_EVENT(THREAD_END): return EI_THREAD_END; case JDWP_EVENT(CLASS_PREPARE): return EI_CLASS_PREPARE; case JDWP_EVENT(CLASS_UNLOAD): return EI_CLASS_UNLOAD; case JDWP_EVENT(CLASS_LOAD): return EI_CLASS_LOAD; case JDWP_EVENT(FIELD_ACCESS): return EI_FIELD_ACCESS; case JDWP_EVENT(FIELD_MODIFICATION): return EI_FIELD_MODIFICATION; case JDWP_EVENT(EXCEPTION_CATCH): return EI_EXCEPTION_CATCH; case JDWP_EVENT(METHOD_ENTRY): return EI_METHOD_ENTRY; case JDWP_EVENT(METHOD_EXIT): return EI_METHOD_EXIT; case JDWP_EVENT(METHOD_EXIT_WITH_RETURN_VALUE): return EI_METHOD_EXIT; case JDWP_EVENT(MONITOR_CONTENDED_ENTER): return EI_MONITOR_CONTENDED_ENTER; case JDWP_EVENT(MONITOR_CONTENDED_ENTERED): return EI_MONITOR_CONTENDED_ENTERED; case JDWP_EVENT(MONITOR_WAIT): return EI_MONITOR_WAIT; case JDWP_EVENT(MONITOR_WAITED): return EI_MONITOR_WAITED; case JDWP_EVENT(VM_INIT): return EI_VM_INIT; case JDWP_EVENT(VM_DEATH): return EI_VM_DEATH; default: break;
}
/* * Event type not recognized - don't exit with error as caller * may wish to return error to debugger.
*/ return (EventIndex)0;
}
EventIndex
jvmti2EventIndex(jvmtiEvent kind)
{ switch ( kind ) { case JVMTI_EVENT_SINGLE_STEP: return EI_SINGLE_STEP; case JVMTI_EVENT_BREAKPOINT: return EI_BREAKPOINT; case JVMTI_EVENT_FRAME_POP: return EI_FRAME_POP; case JVMTI_EVENT_EXCEPTION: return EI_EXCEPTION; case JVMTI_EVENT_THREAD_START:
--> --------------------
--> maximum size reached
--> --------------------
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.67Bemerkung:
Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.