< prev index next >

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

Print this page

        

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2019, 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

@@ -47,28 +47,55 @@
     if (threadControl_isDebugThread(thread)) {
         outStream_setError(out, JDWP_ERROR(INVALID_THREAD));
         return JNI_TRUE;
     }
 
-    WITH_LOCAL_REFS(env, 1) {
-
-        jvmtiThreadInfo info;
-        jvmtiError error;
-
-        (void)memset(&info, 0, sizeof(info));
-
-        error = JVMTI_FUNC_PTR(gdata->jvmti,GetThreadInfo)
-                                (gdata->jvmti, thread, &info);
+    WITH_LOCAL_REFS(env, 3) {
+        jboolean is_fiber = isFiber(thread);
+        if (!is_fiber) {
+            /* Get the thread name */
+            jvmtiThreadInfo info;
+            jvmtiError error;
+
+            (void)memset(&info, 0, sizeof(info));
+            error = JVMTI_FUNC_PTR(gdata->jvmti,GetThreadInfo)
+                (gdata->jvmti, thread, &info);
+
+            if (error != JVMTI_ERROR_NONE) {
+                outStream_setError(out, map2jdwpError(error));
+            } else {
+                (void)outStream_writeString(out, info.name);
+            }
 
-        if (error != JVMTI_ERROR_NONE) {
-            outStream_setError(out, map2jdwpError(error));
+            if ( info.name != NULL ) {
+                threadControl_setName(thread, info.name);
+                jvmtiDeallocate(info.name);
+            }
         } else {
-            (void)outStream_writeString(out, info.name);
-        }
+            /* Use Fiber.toString() instead of the Thread name. */
+            jstring fiberName = JNI_FUNC_PTR(env,CallObjectMethod)
+                (env, thread, gdata->fiberToString);
+            if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) {
+                JNI_FUNC_PTR(env,ExceptionClear)(env);
+                fiberName = NULL;
+            }
 
-        if ( info.name != NULL )
-            jvmtiDeallocate(info.name);
+            if (fiberName == NULL) {
+                (void)outStream_writeString(out, "<UNKNOWN FIBER>");
+            } else {
+                const char *utf;
+                /* Get the UTF8 encoding for this fiberName string. */
+                utf = JNI_FUNC_PTR(env,GetStringUTFChars)(env, fiberName, NULL);
+                if (!(*env)->ExceptionCheck(env)) {
+                    (void)outStream_writeString(out, (char*)utf);
+                    threadControl_setName(thread, utf);
+                    JNI_FUNC_PTR(env,ReleaseStringUTFChars)(env, fiberName, utf);
+                } else {
+                    (void)outStream_writeString(out, "<UNKNOWN FIBER>");
+                }
+            }
+        }
 
     } END_WITH_LOCAL_REFS(env);
 
     return JNI_TRUE;
 }

@@ -168,48 +195,68 @@
 
     WITH_LOCAL_REFS(env, 1) {
 
         jvmtiThreadInfo info;
         jvmtiError error;
-
-        (void)memset(&info, 0, sizeof(info));
-
-        error = JVMTI_FUNC_PTR(gdata->jvmti,GetThreadInfo)
-                                (gdata->jvmti, thread, &info);
-
-        if (error != JVMTI_ERROR_NONE) {
-            outStream_setError(out, map2jdwpError(error));
+        jboolean is_fiber = isFiber(thread);
+        
+        if (is_fiber) {
+            /* If it's a fiber, use the well known thread group for Fibers. */
+            JDI_ASSERT(gdata->fiberThreadGroup != NULL);
+            (void)outStream_writeObjectRef(env, out, gdata->fiberThreadGroup);
         } else {
-            (void)outStream_writeObjectRef(env, out, info.thread_group);
-        }
+            (void)memset(&info, 0, sizeof(info));
+            error = JVMTI_FUNC_PTR(gdata->jvmti,GetThreadInfo)
+                                      (gdata->jvmti, thread, &info);
+
+            if (error != JVMTI_ERROR_NONE) {
+                outStream_setError(out, map2jdwpError(error));
+            } else {
+                (void)outStream_writeObjectRef(env, out, info.thread_group);
+            }
 
-        if ( info.name!=NULL )
-            jvmtiDeallocate(info.name);
+            if ( info.name!=NULL )
+                jvmtiDeallocate(info.name);
+        }
 
     } END_WITH_LOCAL_REFS(env);
 
     return JNI_TRUE;
 }
 
-static jboolean
+/*
+ * Validate that the thread or fiber is suspended, and returns a thread that can
+ * be used for stack operations, even for unmounted fibers.
+ */
+static jthread
 validateSuspendedThread(PacketOutputStream *out, jthread thread)
 {
     jvmtiError error;
     jint count;
+    jthread result = thread;
 
     error = threadControl_suspendCount(thread, &count);
     if (error != JVMTI_ERROR_NONE) {
         outStream_setError(out, map2jdwpError(error));
-        return JNI_FALSE;
+        return NULL;
     }
 
     if (count == 0) {
         outStream_setError(out, JDWP_ERROR(THREAD_NOT_SUSPENDED));
-        return JNI_FALSE;
+        return NULL;
     }
 
-    return JNI_TRUE;
+    if (isFiber(thread)) {
+        /* Make sure the Fiber is mounted on a thread that we can do stack operations on. */
+        result = threadControl_getFiberCarrierOrHelperThread(thread);
+        if (result == NULL) {
+            /* fiber fixme: this should never happen once we get proper unmounted fiber supported. */
+            (void)outStream_writeInt(out, 0);
+        }
+    }
+
+    return result;
 }
 
 static jboolean
 frames(PacketInputStream *in, PacketOutputStream *out)
 {

@@ -220,14 +267,16 @@
     JNIEnv *env;
     jthread thread;
     jint startIndex;
     jint length;
     jvmtiFrameInfo* frames;
+    jthread originalThread;
 
     env = getEnv();
 
     thread = inStream_readThreadRef(env, in);
+    originalThread = thread;
     if (inStream_error(in)) {
         return JNI_TRUE;
     }
     startIndex = inStream_readInt(in);
     if (inStream_error(in)) {

@@ -241,11 +290,12 @@
     if (threadControl_isDebugThread(thread)) {
         outStream_setError(out, JDWP_ERROR(INVALID_THREAD));
         return JNI_TRUE;
     }
 
-    if (!validateSuspendedThread(out, thread)) {
+    thread = validateSuspendedThread(out, thread);
+    if (thread == NULL) {
         return JNI_TRUE;
     }
 
     error = JVMTI_FUNC_PTR(gdata->jvmti,GetFrameCount)
                         (gdata->jvmti, thread, &count);

@@ -295,11 +345,11 @@
         WITH_LOCAL_REFS(env, 1) {
             jclass clazz;
             error = methodClass(frames[index].method, &clazz);
 
             if (error == JVMTI_ERROR_NONE) {
-                FrameID frame = createFrameID(thread, index + startIndex);
+                FrameID frame = createFrameID(originalThread, index + startIndex);
                 outStream_writeFrameID(out, frame);
                 writeCodeLocation(out, clazz, frames[index].method,
                                   frames[index].location);
             }
         } END_WITH_LOCAL_REFS(env);

@@ -328,11 +378,12 @@
     if (threadControl_isDebugThread(thread)) {
         outStream_setError(out, JDWP_ERROR(INVALID_THREAD));
         return JNI_TRUE;
     }
 
-    if (!validateSuspendedThread(out, thread)) {
+    thread = validateSuspendedThread(out, thread);
+    if (thread == NULL) {
         return JNI_TRUE;
     }
 
     error = JVMTI_FUNC_PTR(gdata->jvmti,GetFrameCount)
                         (gdata->jvmti, thread, &count);

@@ -361,11 +412,12 @@
     if (threadControl_isDebugThread(thread)) {
         outStream_setError(out, JDWP_ERROR(INVALID_THREAD));
         return JNI_TRUE;
     }
 
-    if (!validateSuspendedThread(out, thread)) {
+    thread = validateSuspendedThread(out, thread);
+    if (thread == NULL) {
         return JNI_TRUE;
     }
 
     WITH_LOCAL_REFS(env, 1) {
 

@@ -410,11 +462,12 @@
     if (thread == NULL || threadControl_isDebugThread(thread)) {
         outStream_setError(out, JDWP_ERROR(INVALID_THREAD));
         return JNI_TRUE;
     }
 
-    if (!validateSuspendedThread(out, thread)) {
+    thread = validateSuspendedThread(out, thread);
+    if (thread == NULL) {
         return JNI_TRUE;
     }
 
     WITH_LOCAL_REFS(env, 1) {
 

@@ -457,10 +510,16 @@
     if (threadControl_isDebugThread(thread)) {
         outStream_setError(out, JDWP_ERROR(INVALID_THREAD));
         return JNI_TRUE;
     }
 
+    /* fiber fixme: add fiber support */
+    if (isFiber(thread)) {
+        outStream_setError(out, JDWP_ERROR(INVALID_THREAD));
+        return JNI_TRUE;
+    }
+
     error = threadControl_stop(thread, throwable);
     if (error != JVMTI_ERROR_NONE) {
         outStream_setError(out, map2jdwpError(error));
     }
     return JNI_TRUE;

@@ -480,10 +539,16 @@
     if (threadControl_isDebugThread(thread)) {
         outStream_setError(out, JDWP_ERROR(INVALID_THREAD));
         return JNI_TRUE;
     }
 
+    /* fiber fixme: add fiber support */
+    if (isFiber(thread)) {
+        outStream_setError(out, JDWP_ERROR(INVALID_THREAD));
+        return JNI_TRUE;
+    }
+
     error = threadControl_interrupt(thread);
     if (error != JVMTI_ERROR_NONE) {
         outStream_setError(out, map2jdwpError(error));
     }
     return JNI_TRUE;

@@ -530,11 +595,12 @@
     if (thread == NULL || threadControl_isDebugThread(thread)) {
         outStream_setError(out, JDWP_ERROR(INVALID_THREAD));
         return JNI_TRUE;
     }
 
-    if (!validateSuspendedThread(out, thread)) {
+    thread = validateSuspendedThread(out, thread);
+    if (thread == NULL) {
         return JNI_TRUE;
     }
 
     env = getEnv();
 

@@ -586,10 +652,16 @@
     if (threadControl_isDebugThread(thread)) {
         outStream_setError(out, JDWP_ERROR(INVALID_THREAD));
         return JNI_TRUE;
     }
 
+    /* fiber fixme: add fiber support */
+    if (isFiber(thread)) {
+        outStream_setError(out, JDWP_ERROR(INVALID_THREAD));
+        return JNI_TRUE;
+    }
+
     typeKey = inStream_readByte(in);
     if (inStream_error(in)) {
         return JNI_TRUE;
     }
 
< prev index next >