diff options
| author | Martijn Coenen <maco@google.com> | 2021-02-05 11:32:44 +0100 |
|---|---|---|
| committer | Martijn Coenen <maco@google.com> | 2021-04-15 06:56:32 +0000 |
| commit | 0110dc4836eb75717b96cf2a8fa7bc4a2f298c8e (patch) | |
| tree | 76ec3a7fa3ef0d735867d7cbcc554e30c4a49fea /core/java/android/os/BinderProxy.java | |
| parent | a14d76517afb93780dd26cfe1eef627672954002 (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.java | 55 |
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); |
