summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/os/Binder.java28
-rw-r--r--core/jni/android_util_Binder.cpp21
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java1
3 files changed, 36 insertions, 14 deletions
diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java
index 3d76c2501440..8e8565c3574c 100644
--- a/core/java/android/os/Binder.java
+++ b/core/java/android/os/Binder.java
@@ -138,15 +138,6 @@ public class Binder implements IBinder {
}
/**
- * Dump proxy debug information.
- *
- * @hide
- */
- public static void dumpProxyDebugInfo() {
- BinderProxy.dumpProxyDebugInfo();
- }
-
- /**
* Check if binder transaction tracing is enabled.
*
* @hide
@@ -950,7 +941,8 @@ final class BinderProxy implements IBinder {
// about to crash.
final int totalUnclearedSize = unclearedSize();
if (totalUnclearedSize >= CRASH_AT_SIZE) {
- dumpProxyDebugInfo();
+ dumpProxyInterfaceCounts();
+ dumpPerUidProxyCounts();
Runtime.getRuntime().gc();
throw new AssertionError("Binder ProxyMap has too many entries: "
+ totalSize + " (total), " + totalUnclearedSize + " (uncleared), "
@@ -1035,11 +1027,21 @@ final class BinderProxy implements IBinder {
private static ProxyMap sProxyMap = new ProxyMap();
/**
+ * Dump proxy debug information.
+ *
+ * Note: this method is not thread-safe; callers must serialize with other
+ * accesses to sProxyMap, in particular {@link #getInstance(long, long)}.
+ *
* @hide
*/
- public static void dumpProxyDebugInfo() {
- sProxyMap.dumpProxyInterfaceCounts();
- sProxyMap.dumpPerUidProxyCounts();
+ private static void dumpProxyDebugInfo() {
+ if (Build.IS_DEBUGGABLE) {
+ sProxyMap.dumpProxyInterfaceCounts();
+ // Note that we don't call dumpPerUidProxyCounts(); this is because this
+ // method may be called as part of the uid limit being hit, and calling
+ // back into the UID tracking code would cause us to try to acquire a mutex
+ // that is held during that callback.
+ }
}
/**
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index 1b206fd8abdd..c3ba9ba82826 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -108,6 +108,7 @@ static struct binderproxy_offsets_t
jclass mClass;
jmethodID mGetInstance;
jmethodID mSendDeathNotice;
+ jmethodID mDumpProxyDebugInfo;
// Object state.
jfieldID mNativeData; // Field holds native pointer to BinderProxyNativeData.
@@ -1006,9 +1007,27 @@ static void android_os_BinderInternal_handleGc(JNIEnv* env, jobject clazz)
static void android_os_BinderInternal_proxyLimitcallback(int uid)
{
JNIEnv *env = AndroidRuntime::getJNIEnv();
+ {
+ // Calls into BinderProxy must be serialized
+ AutoMutex _l(gProxyLock);
+ env->CallStaticObjectMethod(gBinderProxyOffsets.mClass,
+ gBinderProxyOffsets.mDumpProxyDebugInfo);
+ }
+ if (env->ExceptionCheck()) {
+ ScopedLocalRef<jthrowable> excep(env, env->ExceptionOccurred());
+ report_exception(env, excep.get(),
+ "*** Uncaught exception in dumpProxyDebugInfo");
+ }
+
env->CallStaticVoidMethod(gBinderInternalOffsets.mClass,
gBinderInternalOffsets.mProxyLimitCallback,
uid);
+
+ if (env->ExceptionCheck()) {
+ ScopedLocalRef<jthrowable> excep(env, env->ExceptionOccurred());
+ report_exception(env, excep.get(),
+ "*** Uncaught exception in binderProxyLimitCallbackFromNative");
+ }
}
static void android_os_BinderInternal_setBinderProxyCountEnabled(JNIEnv* env, jobject clazz,
@@ -1389,6 +1408,8 @@ static int int_register_android_os_BinderProxy(JNIEnv* env)
"(JJ)Landroid/os/BinderProxy;");
gBinderProxyOffsets.mSendDeathNotice = GetStaticMethodIDOrDie(env, clazz, "sendDeathNotice",
"(Landroid/os/IBinder$DeathRecipient;)V");
+ gBinderProxyOffsets.mDumpProxyDebugInfo = GetStaticMethodIDOrDie(env, clazz, "dumpProxyDebugInfo",
+ "()V");
gBinderProxyOffsets.mNativeData = GetFieldIDOrDie(env, clazz, "mNativeData", "J");
clazz = FindClassOrDie(env, "java/lang/Class");
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 07d26546a7ad..3430bcd2191b 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -15187,7 +15187,6 @@ public class ActivityManagerService extends IActivityManager.Stub
public void onLimitReached(int uid) {
Slog.wtf(TAG, "Uid " + uid + " sent too many Binders to uid "
+ Process.myUid());
- Binder.dumpProxyDebugInfo();
if (uid == Process.SYSTEM_UID) {
Slog.i(TAG, "Skipping kill (uid is SYSTEM)");
} else {