Fix FindFieldID to use class's classloader to find field type.

Also includes a test case, though the test case does not recreate
this exact issue because the attached native thread would need to
have a null context classloader.

Bug: 11737351
Change-Id: Ieb7536702a556485d667361124cd7985b712b093
diff --git a/runtime/jni_internal.cc b/runtime/jni_internal.cc
index 466edeb..736e305 100644
--- a/runtime/jni_internal.cc
+++ b/runtime/jni_internal.cc
@@ -293,7 +293,7 @@
   Class* field_type;
   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
   if (sig[1] != '\0') {
-    SirtRef<mirror::ClassLoader> class_loader(soa.Self(), GetClassLoader(soa));
+    SirtRef<mirror::ClassLoader> class_loader(soa.Self(), c->GetClassLoader());
     field_type = class_linker->FindClass(sig, class_loader);
   } else {
     field_type = class_linker->FindPrimitiveClass(*sig);
diff --git a/test/JniTest/JniTest.java b/test/JniTest/JniTest.java
index a1b1f0c..9194da5 100644
--- a/test/JniTest/JniTest.java
+++ b/test/JniTest/JniTest.java
@@ -20,12 +20,24 @@
     public static void main(String[] args) {
         System.loadLibrary("arttest");
         testFindClassOnAttachedNativeThread();
+        testFindFieldOnAttachedNativeThread();
         testCallStaticVoidMethodOnSubClass();
         testGetMirandaMethod();
     }
 
     private static native void testFindClassOnAttachedNativeThread();
 
+    private static boolean testFindFieldOnAttachedNativeThreadField;
+
+    private static void testFindFieldOnAttachedNativeThread() {
+      testFindFieldOnAttachedNativeThreadNative();
+      if (!testFindFieldOnAttachedNativeThreadField) {
+            throw new AssertionError();
+        }
+    }
+
+    private static native void testFindFieldOnAttachedNativeThreadNative();
+
     private static void testCallStaticVoidMethodOnSubClass() {
         testCallStaticVoidMethodOnSubClassNative();
         if (!testCallStaticVoidMethodOnSubClass_SuperClass.executed) {
diff --git a/test/JniTest/jni_test.cc b/test/JniTest/jni_test.cc
index cfcbb64..d15e180 100644
--- a/test/JniTest/jni_test.cc
+++ b/test/JniTest/jni_test.cc
@@ -67,6 +67,42 @@
   assert(pthread_join_result == 0);
 }
 
+static void* testFindFieldOnAttachedNativeThread(void*) {
+  assert(jvm != NULL);
+
+  JNIEnv* env = NULL;
+  JavaVMAttachArgs args = { JNI_VERSION_1_6, __FUNCTION__, NULL };
+  int attach_result = jvm->AttachCurrentThread(&env, &args);
+  assert(attach_result == 0);
+
+  jclass clazz = env->FindClass("JniTest");
+  assert(clazz != NULL);
+  assert(!env->ExceptionCheck());
+
+  jfieldID field = env->GetStaticFieldID(clazz, "testFindFieldOnAttachedNativeThreadField", "Z");
+  assert(field != NULL);
+  assert(!env->ExceptionCheck());
+
+  env->SetStaticBooleanField(clazz, field, JNI_TRUE);
+
+  int detach_result = jvm->DetachCurrentThread();
+  assert(detach_result == 0);
+  return NULL;
+}
+
+extern "C" JNIEXPORT void JNICALL Java_JniTest_testFindFieldOnAttachedNativeThreadNative(JNIEnv*,
+                                                                                         jclass) {
+  pthread_t pthread;
+  int pthread_create_result = pthread_create(&pthread,
+                                             NULL,
+                                             testFindFieldOnAttachedNativeThread,
+                                             NULL);
+  assert(pthread_create_result == 0);
+  int pthread_join_result = pthread_join(pthread, NULL);
+  assert(pthread_join_result == 0);
+}
+
+
 // http://b/11243757
 extern "C" JNIEXPORT void JNICALL Java_JniTest_testCallStaticVoidMethodOnSubClassNative(JNIEnv* env,
                                                                                         jclass) {