diff options
| author | 2015-06-02 13:40:12 -0700 | |
|---|---|---|
| committer | 2015-06-02 14:20:52 -0700 | |
| commit | 22c1caa6fad7846cdf7de30323c6c7dc860b9b03 (patch) | |
| tree | 7dd70494257ce55bbbd118cc9568cc96934a1a4e | |
| parent | ac3a02b0f1ed10ed236c87c71f50261c8d522f74 (diff) | |
Add more info for attempting to delete non-JNI local reference
Now we print the stack trace of the method which tried to remove the
non-JNI local reference.
Added test, example output:
Attempt to remove non-JNI local reference, dumping thread
"main" prio=5 tid=1 Runnable
| group="main" sCount=0 dsCount=0 obj=0x12c2b400 self=0xf878af28
| sysTid=32662 nice=0 cgrp=default sched=0/0 handle=0xf73df700
| state=R schedstat=( 154297228 636505 121 ) utm=5 stm=10 core=11 HZ=100
| stack=0xff6f2000-0xff6f4000 stackSize=7MB
| held mutexes= "mutator lock"(shared held)
native: #00 pc 00455a7f /out/host/linux-x86/lib/libartd.so (art::DumpNativeStack(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, int, char const*, art::ArtMethod*, void*)+191)
native: #01 pc 00425d79 /out/host/linux-x86/lib/libartd.so (art::Thread::DumpStack(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) const+473)
native: #02 pc 0028c555 /out/host/linux-x86/lib/libartd.so (art::IndirectReferenceTable::Remove(unsigned int, void*)+421)
native: #03 pc 003319c8 /out/host/linux-x86/lib/libartd.so (art::JNI::DeleteLocalRef(_JNIEnv*, _jobject*)+56)
native: #04 pc 0012db14 /out/host/linux-x86/lib/libartd.so (art::CheckJNI::DeleteRef(char const*, _JNIEnv*, _jobject*, art::IndirectRefKind)+292)
native: #05 pc 00122176 /out/host/linux-x86/lib/libartd.so (art::CheckJNI::DeleteLocalRef(_JNIEnv*, _jobject*)+54)
native: #06 pc 00005724 /out/host/linux-x86/lib/libarttest.so (Java_Main_removeLocalObject+36)
native: #07 pc 00004d6e /tmp/test-32506/dalvik-cache/x86/tmp@mathieuc@test-32506@004-JniTest.jar@classes.dex (void Main.removeLocalObject(java.lang.Object)+130)
at Main.removeLocalObject(Native method)
at Main.testRemoveLocalObject(Main.java:118)
at Main.main(Main.java:37)
(cherry picked from commit ff6d8cffb7c14eee56df16d1422b1fcc180decde)
Bug: 20683465
Change-Id: I56b99c77ae7020cabf1aaeb1d5317b1d5ba940e5
| -rw-r--r-- | runtime/indirect_reference_table.cc | 4 | ||||
| -rw-r--r-- | test/004-JniTest/jni_test.cc | 5 | ||||
| -rw-r--r-- | test/004-JniTest/src/Main.java | 7 |
3 files changed, 15 insertions, 1 deletions
diff --git a/runtime/indirect_reference_table.cc b/runtime/indirect_reference_table.cc index 0ef58ea067..20e42221bb 100644 --- a/runtime/indirect_reference_table.cc +++ b/runtime/indirect_reference_table.cc @@ -181,7 +181,9 @@ bool IndirectReferenceTable::Remove(uint32_t cookie, IndirectRef iref) { auto* env = self->GetJniEnv(); DCHECK(env != nullptr); if (env->check_jni) { - LOG(WARNING) << "Attempt to remove local handle scope entry from IRT, ignoring"; + ScopedObjectAccess soa(self); + LOG(WARNING) << "Attempt to remove non-JNI local reference, dumping thread"; + self->Dump(LOG(WARNING)); } return true; } diff --git a/test/004-JniTest/jni_test.cc b/test/004-JniTest/jni_test.cc index 71a2b2dddc..ca256ec034 100644 --- a/test/004-JniTest/jni_test.cc +++ b/test/004-JniTest/jni_test.cc @@ -258,6 +258,11 @@ extern "C" jchar JNICALL Java_Main_charMethod(JNIEnv*, jclass, jchar c1, jchar c return char_returns[c1]; } +extern "C" JNIEXPORT void JNICALL Java_Main_removeLocalObject(JNIEnv* env, jclass, jclass o) { + // Delete the arg to see if it crashes. + env->DeleteLocalRef(o); +} + extern "C" JNIEXPORT jboolean JNICALL Java_Main_nativeIsAssignableFrom(JNIEnv* env, jclass, jclass from, jclass to) { return env->IsAssignableFrom(from, to); diff --git a/test/004-JniTest/src/Main.java b/test/004-JniTest/src/Main.java index 584fae3a57..ac204175bf 100644 --- a/test/004-JniTest/src/Main.java +++ b/test/004-JniTest/src/Main.java @@ -34,6 +34,7 @@ public class Main { testShallowGetStackClass2(); testCallNonvirtual(); testNewStringObject(); + testRemoveLocalObject(); } private static native void testFindClassOnAttachedNativeThread(); @@ -111,6 +112,12 @@ public class Main { } } + private static native void removeLocalObject(Object o); + + private static void testRemoveLocalObject() { + removeLocalObject(new Object()); + } + private static native short shortMethod(short s1, short s2, short s3, short s4, short s5, short s6, short s7, short s8, short s9, short s10); |