< prev index next >

src/jdk.jdwp.agent/share/native/libjdwp/util.c

Print this page

        

*** 176,219 **** --- 176,231 ---- { WITH_LOCAL_REFS(env, 6) { jvmtiError error; jclass localClassClass; + jclass localFiberClass; jclass localThreadClass; jclass localThreadGroupClass; jclass localClassLoaderClass; jclass localStringClass; jclass localSystemClass; + jclass localInnocuousThreadClass; jclass localPropertiesClass; jclass localVMSupportClass; jobject localAgentProperties; jmethodID getAgentProperties; jint groupCount; jthreadGroup *groups; jthreadGroup localSystemThreadGroup; + gdata->ignoreEvents = JNI_FALSE; + /* Find some standard classes */ localClassClass = findClass(env,"java/lang/Class"); + localFiberClass = findClass(env,"java/lang/Fiber"); localThreadClass = findClass(env,"java/lang/Thread"); localThreadGroupClass = findClass(env,"java/lang/ThreadGroup"); localClassLoaderClass = findClass(env,"java/lang/ClassLoader"); localStringClass = findClass(env,"java/lang/String"); localSystemClass = findClass(env,"java/lang/System"); localPropertiesClass = findClass(env,"java/util/Properties"); + localInnocuousThreadClass = findClass(env, "jdk/internal/misc/InnocuousThread"); /* Save references */ saveGlobalRef(env, localClassClass, &(gdata->classClass)); + saveGlobalRef(env, localFiberClass, &(gdata->fiberClass)); saveGlobalRef(env, localThreadClass, &(gdata->threadClass)); saveGlobalRef(env, localThreadGroupClass, &(gdata->threadGroupClass)); saveGlobalRef(env, localClassLoaderClass, &(gdata->classLoaderClass)); saveGlobalRef(env, localStringClass, &(gdata->stringClass)); saveGlobalRef(env, localSystemClass, &(gdata->systemClass)); + saveGlobalRef(env, localInnocuousThreadClass, &(gdata->innocuousThreadClass)); /* Find some standard methods */ + gdata->fiberToString = + getMethod(env, gdata->fiberClass, "toString", "()Ljava/lang/String;"); + gdata->fiberTryMountAndSuspend = + getMethod(env, gdata->fiberClass, "tryMountAndSuspend", "()Ljava/lang/Thread;"); gdata->threadConstructor = getMethod(env, gdata->threadClass, "<init>", "(Ljava/lang/ThreadGroup;Ljava/lang/String;)V"); gdata->threadSetDaemon = getMethod(env, gdata->threadClass, "setDaemon", "(Z)V");
*** 305,314 **** --- 317,332 ---- { if (object == NULL) { return JDWP_TAG(OBJECT); } else if (JNI_FUNC_PTR(env,IsInstanceOf)(env, object, gdata->stringClass)) { return JDWP_TAG(STRING); + } else if (JNI_FUNC_PTR(env,IsInstanceOf)(env, object, gdata->fiberClass)) { + /* We don't really need to check if it's an instance of a Fiber class since + * that would get detected below, but this is a bit faster. At one point + * it was thought that we would need to return THREAD here instead of OBJECT, + * but that's not the case. */ + return JDWP_TAG(OBJECT); } else if (JNI_FUNC_PTR(env,IsInstanceOf)(env, object, gdata->threadClass)) { return JDWP_TAG(THREAD); } else if (JNI_FUNC_PTR(env,IsInstanceOf)(env, object, gdata->threadGroupClass)) { return JDWP_TAG(THREAD_GROUP); } else if (JNI_FUNC_PTR(env,IsInstanceOf)(env, object, gdata->classLoaderClass)) {
*** 599,616 **** 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); } --- 617,642 ---- jvmtiDeallocate(arguments); } return JNI_TRUE; } ! /* Don't try this with unmounted fibers. */ ! if (isFiber(thread)) { ! thread = getFiberThread(thread); ! } ! if (thread == NULL) { ! error = JVMTI_ERROR_THREAD_NOT_SUSPENDED; ! } else { ! /* ! * 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); }
*** 822,831 **** --- 848,918 ---- jvmtiDeallocate(generic_signature); } return error; } + /** + * Return fiber that is running on specified thread (must be inside a WITH_LOCAL_REFS) + */ + jthread + getThreadFiber(jthread thread) + { + jthread fiber; + jvmtiError error; + + JDI_ASSERT(gdata->fibersSupported); + if ( thread == NULL ) { + return NULL; + } + error = JVMTI_FUNC_PTR(gdata->jvmti,GetThreadFiber) + (gdata->jvmti, thread, &fiber); + if (error == JVMTI_ERROR_THREAD_NOT_ALIVE) { + /* fiber fixme: get rid of this once we get rid of helperThreads. It should never happen then. */ + return NULL; + } else if ( error != JVMTI_ERROR_NONE ) { + EXIT_ERROR(error,"Error calling GetThreadFiber()"); + return JNI_FALSE; + } + return fiber; + } + + /** + * Return thread that specified fiber is running on (must be inside a WITH_LOCAL_REFS) + */ + jthread + getFiberThread(jthread fiber) + { + jthread thread; + jvmtiError error; + + JDI_ASSERT(gdata->fibersSupported); + if ( fiber == NULL ) { + return NULL; + } + error = JVMTI_FUNC_PTR(gdata->jvmti,GetFiberThread) + (gdata->jvmti, fiber, &thread); + if ( error != JVMTI_ERROR_NONE ) { + EXIT_ERROR(error,"Error calling GetFiberThread()"); + return JNI_FALSE; + } + return thread; + } + + jint + getThreadFrameCount(jthread thread) + { + jint count = 0; + jvmtiError error; + + error = JVMTI_FUNC_PTR(gdata->jvmti,GetFrameCount) + (gdata->jvmti, thread, &count); + if (error != JVMTI_ERROR_NONE) { + EXIT_ERROR(error, "getting frame count"); + } + return count; + } + JNIEnv * getEnv(void) { JNIEnv *env = NULL; jint rc;
*** 1584,1593 **** --- 1671,1687 ---- JNIEnv *env = getEnv(); return JNI_FUNC_PTR(env,IsInstanceOf)(env, object, gdata->classClass); } jboolean + isFiber(jobject object) + { + JNIEnv *env = getEnv(); + return JNI_FUNC_PTR(env,IsInstanceOf)(env, object, gdata->fiberClass); + } + + jboolean isThread(jobject object) { JNIEnv *env = getEnv(); return JNI_FUNC_PTR(env,IsInstanceOf)(env, object, gdata->threadClass); }
*** 1963,1972 **** --- 2057,2072 ---- index2jvmti[EI_MONITOR_CONTENDED_ENTERED -EI_min] = JVMTI_EVENT_MONITOR_CONTENDED_ENTERED; index2jvmti[EI_MONITOR_WAIT -EI_min] = JVMTI_EVENT_MONITOR_WAIT; index2jvmti[EI_MONITOR_WAITED -EI_min] = JVMTI_EVENT_MONITOR_WAITED; index2jvmti[EI_VM_INIT -EI_min] = JVMTI_EVENT_VM_INIT; index2jvmti[EI_VM_DEATH -EI_min] = JVMTI_EVENT_VM_DEATH; + index2jvmti[EI_FIBER_SCHEDULED -EI_min] = JVMTI_EVENT_FIBER_SCHEDULED; + index2jvmti[EI_FIBER_TERMINATED -EI_min] = JVMTI_EVENT_FIBER_TERMINATED; + index2jvmti[EI_FIBER_MOUNT -EI_min] = JVMTI_EVENT_FIBER_MOUNT; + index2jvmti[EI_FIBER_UNMOUNT -EI_min] = JVMTI_EVENT_FIBER_UNMOUNT; + index2jvmti[EI_CONTINUATION_RUN -EI_min] = JVMTI_EVENT_CONTINUATION_RUN; + index2jvmti[EI_CONTINUATION_YIELD -EI_min] = JVMTI_EVENT_CONTINUATION_YIELD; index2jdwp[EI_SINGLE_STEP -EI_min] = JDWP_EVENT(SINGLE_STEP); index2jdwp[EI_BREAKPOINT -EI_min] = JDWP_EVENT(BREAKPOINT); index2jdwp[EI_FRAME_POP -EI_min] = JDWP_EVENT(FRAME_POP); index2jdwp[EI_EXCEPTION -EI_min] = JDWP_EVENT(EXCEPTION);
*** 1984,1993 **** --- 2084,2102 ---- index2jdwp[EI_MONITOR_CONTENDED_ENTERED -EI_min] = JDWP_EVENT(MONITOR_CONTENDED_ENTERED); index2jdwp[EI_MONITOR_WAIT -EI_min] = JDWP_EVENT(MONITOR_WAIT); index2jdwp[EI_MONITOR_WAITED -EI_min] = JDWP_EVENT(MONITOR_WAITED); index2jdwp[EI_VM_INIT -EI_min] = JDWP_EVENT(VM_INIT); index2jdwp[EI_VM_DEATH -EI_min] = JDWP_EVENT(VM_DEATH); + /* Just map FIBER_SCHEDULED/TERMINATED to THREAD_START/END. */ + index2jdwp[EI_FIBER_SCHEDULED -EI_min] = JDWP_EVENT(THREAD_START); + index2jdwp[EI_FIBER_TERMINATED -EI_min] = JDWP_EVENT(THREAD_END); + /* fiber fixme: these don't actually map to anything in JDWP. Need a way to make them + * produce an error if referenced. */ + index2jdwp[EI_FIBER_MOUNT -EI_min] = -1; + index2jdwp[EI_FIBER_UNMOUNT -EI_min] = -1; + index2jdwp[EI_CONTINUATION_RUN -EI_min] = -1; + index2jdwp[EI_CONTINUATION_YIELD -EI_min] = -1; } jdwpEvent eventIndex2jdwp(EventIndex i) {
*** 2004,2013 **** --- 2113,2185 ---- EXIT_ERROR(AGENT_ERROR_INVALID_INDEX,"bad EventIndex"); } return index2jvmti[i-EI_min]; } + + 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_GC_FINISH: + return "EI_GC_FINISH"; + 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_FIBER_SCHEDULED: + return "EI_FIBER_SCHEDULED"; + case EI_FIBER_TERMINATED: + return "EI_FIBER_TERMINATED"; + case EI_FIBER_MOUNT: + return "EI_FIBER_MOUNT"; + case EI_FIBER_UNMOUNT: + return "EI_FIBER_UNMOUNT"; + case EI_CONTINUATION_RUN: + return "EI_CONTINUATION_RUN"; + case EI_CONTINUATION_YIELD: + return "EI_CONTINUATION_YIELD"; + default: + JDI_ASSERT(JNI_FALSE); + return "Bad EI"; + } + } + EventIndex jdwp2EventIndex(jdwpEvent eventType) { switch ( eventType ) { case JDWP_EVENT(SINGLE_STEP):
*** 2109,2118 **** --- 2281,2305 ---- return EI_MONITOR_WAITED; case JVMTI_EVENT_VM_INIT: return EI_VM_INIT; case JVMTI_EVENT_VM_DEATH: return EI_VM_DEATH; + /* fiber events */ + case JVMTI_EVENT_FIBER_SCHEDULED: + return EI_FIBER_SCHEDULED; + case JVMTI_EVENT_FIBER_TERMINATED: + return EI_FIBER_TERMINATED; + case JVMTI_EVENT_FIBER_MOUNT: + return EI_FIBER_MOUNT; + case JVMTI_EVENT_FIBER_UNMOUNT: + return EI_FIBER_UNMOUNT; + /* continuation events */ + case JVMTI_EVENT_CONTINUATION_RUN: + return EI_CONTINUATION_RUN; + case JVMTI_EVENT_CONTINUATION_YIELD: + return EI_CONTINUATION_YIELD; + default: EXIT_ERROR(AGENT_ERROR_INVALID_INDEX,"JVMTI to EventIndex mapping"); break; } return (EventIndex)0;
< prev index next >