summaryrefslogtreecommitdiffstats
path: root/core/jni/android_util_Binder.cpp
diff options
context:
space:
mode:
authorJeff Brown <jeffbrown@google.com>2010-03-24 18:56:57 -0700
committerJeff Brown <jeffbrown@google.com>2010-03-24 19:44:50 -0700
commit582763ae4e2910b4059dccdfd30a447e9fc974d5 (patch)
tree8bfca3952a09ef40d5da2fe490fe36e827c0e6e8 /core/jni/android_util_Binder.cpp
parentff21e3776d588b04abee2b65e35d4daa8d112f21 (diff)
downloadframeworks_base-582763ae4e2910b4059dccdfd30a447e9fc974d5.zip
frameworks_base-582763ae4e2910b4059dccdfd30a447e9fc974d5.tar.gz
frameworks_base-582763ae4e2910b4059dccdfd30a447e9fc974d5.tar.bz2
Ensure Binder finalizer handles partially initialized instances.
If the Binder is allocated but its constructor does not run for some reason, then Binder.init() will not be called. Since the object was allocated, it is still eligible for finalization. Eventually when the finalizer runs and calls Binder.destroy(), it will have a NULL binder holder pointer. Previously this would cause Binder.destroy() to attempt to decrement a reference count on a NULL pointer. Now we check and ignore the binder if it does not have a valid holder pointer. Bug: b/2533956 Change-Id: Ifc2729b2f2abe8bceea5a0645ae0a4c1575b7846
Diffstat (limited to 'core/jni/android_util_Binder.cpp')
-rw-r--r--core/jni/android_util_Binder.cpp16
1 files changed, 13 insertions, 3 deletions
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index 627fcbf..5182a77 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -590,9 +590,19 @@ static void android_os_Binder_destroy(JNIEnv* env, jobject clazz)
{
JavaBBinderHolder* jbh = (JavaBBinderHolder*)
env->GetIntField(clazz, gBinderOffsets.mObject);
- env->SetIntField(clazz, gBinderOffsets.mObject, 0);
- LOGV("Java Binder %p: removing ref on holder %p", clazz, jbh);
- jbh->decStrong(clazz);
+ if (jbh != NULL) {
+ env->SetIntField(clazz, gBinderOffsets.mObject, 0);
+ LOGV("Java Binder %p: removing ref on holder %p", clazz, jbh);
+ jbh->decStrong(clazz);
+ } else {
+ // Encountering an uninitialized binder is harmless. All it means is that
+ // the Binder was only partially initialized when its finalizer ran and called
+ // destroy(). The Binder could be partially initialized for several reasons.
+ // For example, a Binder subclass constructor might have thrown an exception before
+ // it could delegate to its superclass's constructor. Consequently init() would
+ // not have been called and the holder pointer would remain NULL.
+ LOGV("Java Binder %p: ignoring uninitialized binder", clazz);
+ }
}
// ----------------------------------------------------------------------------