Merge "Move dumpAnrStateLocked off the critical ANR path" into udc-dev

This commit is contained in:
Mohamad Mahmoud
2023-05-11 15:34:34 +00:00
committed by Android (Google) Code Review
2 changed files with 42 additions and 13 deletions

View File

@@ -118,6 +118,9 @@ public class AnrLatencyTracker implements AutoCloseable {
private boolean mIsSkipped = false; private boolean mIsSkipped = false;
private boolean mCopyingFirstPidSucceeded = false; private boolean mCopyingFirstPidSucceeded = false;
private long mPreDumpIfLockTooSlowStartUptime;
private long mPreDumpIfLockTooSlowDuration = 0;
private final int mAnrRecordPlacedOnQueueCookie = private final int mAnrRecordPlacedOnQueueCookie =
sNextAnrRecordPlacedOnQueueCookieGenerator.incrementAndGet(); sNextAnrRecordPlacedOnQueueCookieGenerator.incrementAndGet();
@@ -401,6 +404,17 @@ public class AnrLatencyTracker implements AutoCloseable {
Trace.traceCounter(TRACE_TAG_ACTIVITY_MANAGER, "anrRecordsQueueSize", queueSize); Trace.traceCounter(TRACE_TAG_ACTIVITY_MANAGER, "anrRecordsQueueSize", queueSize);
} }
/** Records the start of AnrController#preDumpIfLockTooSlow. */
public void preDumpIfLockTooSlowStarted() {
mPreDumpIfLockTooSlowStartUptime = getUptimeMillis();
}
/** Records the end of AnrController#preDumpIfLockTooSlow. */
public void preDumpIfLockTooSlowEnded() {
mPreDumpIfLockTooSlowDuration +=
getUptimeMillis() - mPreDumpIfLockTooSlowStartUptime;
}
/** Records a skipped ANR in ProcessErrorStateRecord#appNotResponding. */ /** Records a skipped ANR in ProcessErrorStateRecord#appNotResponding. */
public void anrSkippedProcessErrorStateRecordAppNotResponding() { public void anrSkippedProcessErrorStateRecordAppNotResponding() {
anrSkipped("appNotResponding"); anrSkipped("appNotResponding");
@@ -415,7 +429,7 @@ public class AnrLatencyTracker implements AutoCloseable {
* Returns latency data as a comma separated value string for inclusion in ANR report. * Returns latency data as a comma separated value string for inclusion in ANR report.
*/ */
public String dumpAsCommaSeparatedArrayWithHeader() { public String dumpAsCommaSeparatedArrayWithHeader() {
return "DurationsV3: " + mAnrTriggerUptime return "DurationsV4: " + mAnrTriggerUptime
/* triggering_to_app_not_responding_duration = */ /* triggering_to_app_not_responding_duration = */
+ "," + (mAppNotRespondingStartUptime - mAnrTriggerUptime) + "," + (mAppNotRespondingStartUptime - mAnrTriggerUptime)
/* app_not_responding_duration = */ /* app_not_responding_duration = */
@@ -464,6 +478,8 @@ public class AnrLatencyTracker implements AutoCloseable {
+ "," + mEarlyDumpStatus + "," + mEarlyDumpStatus
/* copying_first_pid_succeeded = */ /* copying_first_pid_succeeded = */
+ "," + (mCopyingFirstPidSucceeded ? 1 : 0) + "," + (mCopyingFirstPidSucceeded ? 1 : 0)
/* preDumpIfLockTooSlow_duration = */
+ "," + mPreDumpIfLockTooSlowDuration
+ "\n\n"; + "\n\n";
} }

View File

@@ -34,6 +34,7 @@ import android.util.SparseArray;
import android.view.InputApplicationHandle; import android.view.InputApplicationHandle;
import com.android.internal.os.TimeoutRecord; import com.android.internal.os.TimeoutRecord;
import com.android.server.FgThread;
import com.android.server.am.StackTracesDumpHelper; import com.android.server.am.StackTracesDumpHelper;
import com.android.server.criticalevents.CriticalEventLog; import com.android.server.criticalevents.CriticalEventLog;
@@ -68,7 +69,9 @@ class AnrController {
TimeoutRecord timeoutRecord) { TimeoutRecord timeoutRecord) {
try { try {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "notifyAppUnresponsive()"); Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "notifyAppUnresponsive()");
timeoutRecord.mLatencyTracker.preDumpIfLockTooSlowStarted();
preDumpIfLockTooSlow(); preDumpIfLockTooSlow();
timeoutRecord.mLatencyTracker.preDumpIfLockTooSlowEnded();
final ActivityRecord activity; final ActivityRecord activity;
timeoutRecord.mLatencyTracker.waitingOnGlobalLockStarted(); timeoutRecord.mLatencyTracker.waitingOnGlobalLockStarted();
boolean blamePendingFocusRequest = false; boolean blamePendingFocusRequest = false;
@@ -108,7 +111,7 @@ class AnrController {
if (!blamePendingFocusRequest) { if (!blamePendingFocusRequest) {
Slog.i(TAG_WM, "ANR in " + activity.getName() + ". Reason: " Slog.i(TAG_WM, "ANR in " + activity.getName() + ". Reason: "
+ timeoutRecord.mReason); + timeoutRecord.mReason);
dumpAnrStateLocked(activity, null /* windowState */, timeoutRecord.mReason); dumpAnrStateAsync(activity, null /* windowState */, timeoutRecord.mReason);
mUnresponsiveAppByDisplay.put(activity.getDisplayId(), activity); mUnresponsiveAppByDisplay.put(activity.getDisplayId(), activity);
} }
} }
@@ -159,7 +162,9 @@ class AnrController {
*/ */
private boolean notifyWindowUnresponsive(@NonNull IBinder inputToken, private boolean notifyWindowUnresponsive(@NonNull IBinder inputToken,
TimeoutRecord timeoutRecord) { TimeoutRecord timeoutRecord) {
timeoutRecord.mLatencyTracker.preDumpIfLockTooSlowStarted();
preDumpIfLockTooSlow(); preDumpIfLockTooSlow();
timeoutRecord.mLatencyTracker.preDumpIfLockTooSlowEnded();
final int pid; final int pid;
final boolean aboveSystem; final boolean aboveSystem;
final ActivityRecord activity; final ActivityRecord activity;
@@ -178,7 +183,7 @@ class AnrController {
? windowState.mActivityRecord : null; ? windowState.mActivityRecord : null;
Slog.i(TAG_WM, "ANR in " + target + ". Reason:" + timeoutRecord.mReason); Slog.i(TAG_WM, "ANR in " + target + ". Reason:" + timeoutRecord.mReason);
aboveSystem = isWindowAboveSystem(windowState); aboveSystem = isWindowAboveSystem(windowState);
dumpAnrStateLocked(activity, windowState, timeoutRecord.mReason); dumpAnrStateAsync(activity, windowState, timeoutRecord.mReason);
} }
if (activity != null) { if (activity != null) {
activity.inputDispatchingTimedOut(timeoutRecord, pid); activity.inputDispatchingTimedOut(timeoutRecord, pid);
@@ -197,7 +202,7 @@ class AnrController {
timeoutRecord.mLatencyTracker.waitingOnGlobalLockStarted(); timeoutRecord.mLatencyTracker.waitingOnGlobalLockStarted();
synchronized (mService.mGlobalLock) { synchronized (mService.mGlobalLock) {
timeoutRecord.mLatencyTracker.waitingOnGlobalLockEnded(); timeoutRecord.mLatencyTracker.waitingOnGlobalLockEnded();
dumpAnrStateLocked(null /* activity */, null /* windowState */, timeoutRecord.mReason); dumpAnrStateAsync(null /* activity */, null /* windowState */, timeoutRecord.mReason);
} }
// We cannot determine the z-order of the window, so place the anr dialog as high // We cannot determine the z-order of the window, so place the anr dialog as high
@@ -351,15 +356,23 @@ class AnrController {
} }
private void dumpAnrStateLocked(ActivityRecord activity, WindowState windowState, /**
* Executes asynchronously on the fg thread not to block the stack dump for
* the ANRing processes.
*/
private void dumpAnrStateAsync(ActivityRecord activity, WindowState windowState,
String reason) { String reason) {
FgThread.getExecutor().execute(() -> {
try { try {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "dumpAnrStateLocked()"); Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "dumpAnrStateLocked()");
synchronized (mService.mGlobalLock) {
mService.saveANRStateLocked(activity, windowState, reason); mService.saveANRStateLocked(activity, windowState, reason);
mService.mAtmService.saveANRState(reason); mService.mAtmService.saveANRState(reason);
}
} finally { } finally {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} }
});
} }
private boolean isWindowAboveSystem(@NonNull WindowState windowState) { private boolean isWindowAboveSystem(@NonNull WindowState windowState) {