diff options
| -rw-r--r-- | core/jni/android_util_Binder.cpp | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp index b8f2d6f2e068..6b5ca50a9270 100644 --- a/core/jni/android_util_Binder.cpp +++ b/core/jni/android_util_Binder.cpp @@ -39,6 +39,8 @@ #include <binder/IServiceManager.h> #include <utils/threads.h> +#include <ScopedUtfChars.h> + #include <android_runtime/AndroidRuntime.h> //#undef LOGV @@ -444,6 +446,25 @@ public: return result; } + void warnIfStillLive() { + JNIEnv* env = javavm_to_jnienv(mVM); + if (mObject != NULL) { + // Okay, something is wrong -- we have a hard reference to a live death + // recipient on the VM side, but the list is being torn down. + jclass clazz = env->GetObjectClass(mObject); + jmethodID getnameMethod = env->GetMethodID(clazz, "getName", NULL); + jstring nameString = (jstring) env->CallObjectMethod(clazz, getnameMethod); + if (nameString) { + ScopedUtfChars nameUtf(env, nameString); + LOGW("BinderProxy is being destroyed but the application did not call " + "unlinkToDeath to unlink all of its death recipients beforehand. " + "Releasing leaked death recipient: %s", nameUtf.c_str()); + env->DeleteLocalRef(nameString); + } + env->DeleteLocalRef(clazz); + } + } + protected: virtual ~JavaDeathRecipient() { @@ -478,7 +499,10 @@ DeathRecipientList::~DeathRecipientList() { // to the list are holding references on the list object. Only when they are torn // down can the list header be destroyed. if (mList.size() > 0) { - LOGE("Retiring DRL %p with extant death recipients\n", this); + List< sp<JavaDeathRecipient> >::iterator iter; + for (iter = mList.begin(); iter != mList.end(); iter++) { + (*iter)->warnIfStillLive(); + } } } |