summaryrefslogtreecommitdiff
path: root/core/java/android/os/BinderProxy.java
diff options
context:
space:
mode:
authorMartijn Coenen <maco@google.com>2021-02-05 11:32:44 +0100
committerMartijn Coenen <maco@google.com>2021-04-15 06:56:32 +0000
commit0110dc4836eb75717b96cf2a8fa7bc4a2f298c8e (patch)
tree76ec3a7fa3ef0d735867d7cbcc554e30c4a49fea /core/java/android/os/BinderProxy.java
parenta14d76517afb93780dd26cfe1eef627672954002 (diff)
Dump binder proxies interface descriptors on a separate thread.
There are apparently some processes that block getInterfaceDescriptor() from completing, thus locking up the thread doing the binder proxy dump. This can cause the watchdog to restart system_server. Move the calls to a separate thread and give it some time to complete! Bug: 174722615 Bug: 183676249 Test: adb shell am dump binder-proxies Change-Id: Ifa79e53524197bf1d785210b7504e7f6c6ddc9b7 Merged-In: Ifa79e53524197bf1d785210b7504e7f6c6ddc9b7 (cherry picked from commit f1a22a35e85d589a4f2ba915a1997b641c81e352)
Diffstat (limited to 'core/java/android/os/BinderProxy.java')
-rw-r--r--core/java/android/os/BinderProxy.java55
1 files changed, 38 insertions, 17 deletions
diff --git a/core/java/android/os/BinderProxy.java b/core/java/android/os/BinderProxy.java
index 16d041ac60f2..d026e959905c 100644
--- a/core/java/android/os/BinderProxy.java
+++ b/core/java/android/os/BinderProxy.java
@@ -34,6 +34,9 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
/**
* Java proxy for a native IBinder object.
@@ -262,27 +265,45 @@ public final class BinderProxy implements IBinder {
Log.e(Binder.TAG, "RemoteException while disabling app freezer");
}
- for (WeakReference<BinderProxy> weakRef : proxiesToQuery) {
- BinderProxy bp = weakRef.get();
- String key;
- if (bp == null) {
- key = "<cleared weak-ref>";
- } else {
- try {
- key = bp.getInterfaceDescriptor();
- if ((key == null || key.isEmpty()) && !bp.isBinderAlive()) {
- key = "<proxy to dead node>";
+ // We run the dump on a separate thread, because there are known cases where
+ // a process overrides getInterfaceDescriptor() and somehow blocks on it, causing
+ // the calling thread (usually AMS) to hit the watchdog.
+ // Do the dumping on a separate thread instead, and give up after a while.
+ ExecutorService executorService = Executors.newSingleThreadExecutor();
+ executorService.submit(() -> {
+ for (WeakReference<BinderProxy> weakRef : proxiesToQuery) {
+ BinderProxy bp = weakRef.get();
+ String key;
+ if (bp == null) {
+ key = "<cleared weak-ref>";
+ } else {
+ try {
+ key = bp.getInterfaceDescriptor();
+ if ((key == null || key.isEmpty()) && !bp.isBinderAlive()) {
+ key = "<proxy to dead node>";
+ }
+ } catch (Throwable t) {
+ key = "<exception during getDescriptor>";
}
- } catch (Throwable t) {
- key = "<exception during getDescriptor>";
+ }
+ Integer i = counts.get(key);
+ if (i == null) {
+ counts.put(key, 1);
+ } else {
+ counts.put(key, i + 1);
}
}
- Integer i = counts.get(key);
- if (i == null) {
- counts.put(key, 1);
- } else {
- counts.put(key, i + 1);
+ });
+
+ try {
+ executorService.shutdown();
+ boolean dumpDone = executorService.awaitTermination(20, TimeUnit.SECONDS);
+ if (!dumpDone) {
+ Log.e(Binder.TAG, "Failed to complete binder proxy dump,"
+ + " dumping what we have so far.");
}
+ } catch (InterruptedException e) {
+ // Ignore
}
try {
ActivityManager.getService().enableAppFreezer(true);