diff options
| author | 2011-08-26 16:17:50 -0700 | |
|---|---|---|
| committer | 2011-08-26 16:17:50 -0700 | |
| commit | 97c06141f0ee4013076dc63af3337535c1df7e61 (patch) | |
| tree | 329f0895f52a8b5c4c72990c4b8a88560c551f79 | |
| parent | 03b1fecd53e299f7473c6a947059638dfe76866e (diff) | |
| parent | ac5e350e567c7a257ced37dd4e8ca0f4c95f7e81 (diff) | |
Merge "Warn if we're tearing down "live" DeathRecipient content [take 2]"
| -rw-r--r-- | core/jni/android_util_Binder.cpp | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp index b8f2d6f2e068..4cf4afabec14 100644 --- a/core/jni/android_util_Binder.cpp +++ b/core/jni/android_util_Binder.cpp @@ -39,6 +39,9 @@ #include <binder/IServiceManager.h> #include <utils/threads.h> +#include <ScopedUtfChars.h> +#include <ScopedLocalRef.h> + #include <android_runtime/AndroidRuntime.h> //#undef LOGV @@ -444,6 +447,30 @@ public: return result; } + void warnIfStillLive() { + 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. + JNIEnv* env = javavm_to_jnienv(mVM); + ScopedLocalRef<jclass> classRef(env, env->GetObjectClass(mObject)); + jmethodID getnameMethod = env->GetMethodID(classRef.get(), + "getName", "()Ljava/lang/String;"); + if (getnameMethod) { + ScopedLocalRef<jstring> nameRef(env, + (jstring) env->CallObjectMethod(classRef.get(), getnameMethod)); + ScopedUtfChars nameUtf(env, nameRef.get()); + if (nameUtf.c_str() != NULL) { + 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()); + } else { + LOGW("BinderProxy being destroyed; unable to get DR object name"); + env->ExceptionClear(); + } + } else LOGW("BinderProxy being destroyed; unable to find DR class getName"); + } + } + protected: virtual ~JavaDeathRecipient() { @@ -478,7 +505,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(); + } } } |