OSDN Git Service

ART: Fix another potential N-th visitor issue
authorAndreas Gampe <agampe@google.com>
Thu, 14 Aug 2014 06:05:38 +0000 (23:05 -0700)
committerAndreas Gampe <agampe@google.com>
Thu, 14 Aug 2014 06:05:38 +0000 (23:05 -0700)
Bug: 16867274
Change-Id: I5466af563032041ef4a547894f40f303871302c6

runtime/native/dalvik_system_VMStack.cc
test/004-JniTest/jni_test.cc
test/004-JniTest/src/Main.java

index 047e9f6..b079229 100644 (file)
@@ -117,6 +117,10 @@ static jclass VMStack_getStackClass2(JNIEnv* env, jclass) {
   ScopedFastNativeObjectAccess soa(env);
   NthCallerVisitor visitor(soa.Self(), 3);
   visitor.WalkStack();
+  if (UNLIKELY(visitor.caller == nullptr)) {
+    // The caller is an attached native thread.
+    return nullptr;
+  }
   return soa.AddLocalReference<jclass>(visitor.caller->GetDeclaringClass());
 }
 
index 9a2fbdf..f5a1d65 100644 (file)
@@ -316,3 +316,40 @@ extern "C" JNIEXPORT void JNICALL Java_Main_nativeTestShallowGetCallingClassLoad
                                                                                    jclass) {
   PthreadHelper(&testShallowGetCallingClassLoader);
 }
+
+static void testShallowGetStackClass2(JNIEnv* env) {
+  jclass vmstack_clazz = env->FindClass("dalvik/system/VMStack");
+  assert(vmstack_clazz != nullptr);
+  assert(!env->ExceptionCheck());
+
+  // Test direct call.
+  {
+    jmethodID getStackClass2MethodId = env->GetStaticMethodID(vmstack_clazz, "getStackClass2",
+                                                              "()Ljava/lang/Class;");
+    assert(getStackClass2MethodId != nullptr);
+    assert(!env->ExceptionCheck());
+
+    jobject caller_class = env->CallStaticObjectMethod(vmstack_clazz, getStackClass2MethodId);
+    assert(caller_class == nullptr);
+    assert(!env->ExceptionCheck());
+  }
+
+  // Test one-level call. Use VMStack.getStackClass1().
+  {
+    jmethodID getStackClass1MethodId = env->GetStaticMethodID(vmstack_clazz, "getStackClass1",
+                                                              "()Ljava/lang/Class;");
+    assert(getStackClass1MethodId != nullptr);
+    assert(!env->ExceptionCheck());
+
+    jobject caller_class = env->CallStaticObjectMethod(vmstack_clazz, getStackClass1MethodId);
+    assert(caller_class == nullptr);
+    assert(!env->ExceptionCheck());
+  }
+
+  // For better testing we would need to compile against libcore and have a two-deep stack
+  // ourselves.
+}
+
+extern "C" JNIEXPORT void JNICALL Java_Main_nativeTestShallowGetStackClass2(JNIEnv* env, jclass) {
+  PthreadHelper(&testShallowGetStackClass2);
+}
index 6d7d647..5884bc0 100644 (file)
@@ -31,6 +31,7 @@ public class Main {
         testCharMethod();
         testIsAssignableFromOnPrimitiveTypes();
         testShallowGetCallingClassLoader();
+        testShallowGetStackClass2();
     }
 
     private static native void testFindClassOnAttachedNativeThread();
@@ -174,4 +175,10 @@ public class Main {
     }
 
     native static void nativeTestShallowGetCallingClassLoader();
+
+    static void testShallowGetStackClass2() {
+        nativeTestShallowGetStackClass2();
+    }
+
+    native static void nativeTestShallowGetStackClass2();
 }