summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Martijn Coenen <maco@google.com> 2024-08-06 10:55:18 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2024-08-06 10:55:18 +0000
commita2ad8245a7bec06c694ab07f5892c1981ce14367 (patch)
tree66904d7d5386ec3c41bc83ae96ebe5a81b0d5cb3
parent2caf6f9fc74ba4274ad6325cea2fec1403668255 (diff)
Revert^2 "trace-ipc: Don't hold procLock while calling out."
This reverts commit 2caf6f9fc74ba4274ad6325cea2fec1403668255. Dumping IPC transactions can be a long running operation; instead of holding the procLock for all of it, make a copy of the list of processes, and iterate over those instead. Bug: 306025653 Change-Id: I4affb7e63c6c597823694a91db6678e358960dc4 Flag: EXEMPT bugfix Test: adb shell am trace-ipc start / stop
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java70
1 files changed, 41 insertions, 29 deletions
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 1b59c1829d4c..dffbaad2a209 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -18333,43 +18333,55 @@ public class ActivityManagerService extends IActivityManager.Stub
boolean closeFd = true;
try {
- synchronized (mProcLock) {
- if (fd == null) {
- throw new IllegalArgumentException("null fd");
- }
- mBinderTransactionTrackingEnabled = false;
+ Objects.requireNonNull(fd);
+
+ record ProcessToDump(String processName, IApplicationThread thread) { }
- PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
- pw.println("Binder transaction traces for all processes.\n");
- mProcessList.forEachLruProcessesLOSP(true, process -> {
+ PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
+ pw.println("Binder transaction traces for all processes.\n");
+ final ArrayList<ProcessToDump> processes = new ArrayList<>();
+ synchronized (mProcLock) {
+ // Since dumping binder transactions is a long-running operation, we can't do it
+ // with mProcLock held. Do the initial verification here, and save the processes
+ // to dump later outside the lock.
+ final ArrayList<ProcessRecord> unverifiedProcesses =
+ new ArrayList<>(mProcessList.getLruProcessesLOSP());
+ for (int i = 0, size = unverifiedProcesses.size(); i < size; i++) {
+ ProcessRecord process = unverifiedProcesses.get(i);
final IApplicationThread thread = process.getThread();
if (!processSanityChecksLPr(process, thread)) {
- return;
+ continue;
}
+ processes.add(new ProcessToDump(process.processName, process.getThread()));
+ }
+ mBinderTransactionTrackingEnabled = false;
+ }
+ for (int i = 0, size = processes.size(); i < size; i++) {
+ final String processName = processes.get(i).processName();
+ final IApplicationThread thread = processes.get(i).thread();
- pw.println("Traces for process: " + process.processName);
- pw.flush();
+ pw.println("Traces for process: " + processName);
+ pw.flush();
+ try {
+ TransferPipe tp = new TransferPipe();
try {
- TransferPipe tp = new TransferPipe();
- try {
- thread.stopBinderTrackingAndDump(tp.getWriteFd());
- tp.go(fd.getFileDescriptor());
- } finally {
- tp.kill();
- }
- } catch (IOException e) {
- pw.println("Failure while dumping IPC traces from " + process +
- ". Exception: " + e);
- pw.flush();
- } catch (RemoteException e) {
- pw.println("Got a RemoteException while dumping IPC traces from " +
- process + ". Exception: " + e);
- pw.flush();
+ thread.stopBinderTrackingAndDump(tp.getWriteFd());
+ tp.go(fd.getFileDescriptor());
+ } finally {
+ tp.kill();
}
- });
- closeFd = false;
- return true;
+ } catch (IOException e) {
+ pw.println("Failure while dumping IPC traces from " + processName +
+ ". Exception: " + e);
+ pw.flush();
+ } catch (RemoteException e) {
+ pw.println("Got a RemoteException while dumping IPC traces from " +
+ processName + ". Exception: " + e);
+ pw.flush();
+ }
}
+ closeFd = false;
+ return true;
} finally {
if (fd != null && closeFd) {
try {