1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.am; 18 19 import static android.os.Process.SYSTEM_UID; 20 21 import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 22 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR; 23 import static com.android.server.am.ActivityManagerService.MY_PID; 24 import static com.android.server.am.ProcessRecord.TAG; 25 import static com.android.server.stats.pull.ProcfsMemoryUtil.readMemorySnapshotFromProcfs; 26 27 import android.annotation.Nullable; 28 import android.app.ActivityManager; 29 import android.app.AnrController; 30 import android.app.ApplicationErrorReport; 31 import android.app.ApplicationExitInfo; 32 import android.content.ComponentName; 33 import android.content.ContentResolver; 34 import android.content.Context; 35 import android.content.pm.ApplicationInfo; 36 import android.content.pm.IncrementalStatesInfo; 37 import android.content.pm.PackageManagerInternal; 38 import android.os.IBinder; 39 import android.os.Message; 40 import android.os.Process; 41 import android.os.ServiceManager; 42 import android.os.SystemClock; 43 import android.os.incremental.IIncrementalService; 44 import android.os.incremental.IncrementalManager; 45 import android.os.incremental.IncrementalMetrics; 46 import android.provider.Settings; 47 import android.util.EventLog; 48 import android.util.Slog; 49 import android.util.SparseBooleanArray; 50 51 import com.android.internal.annotations.CompositeRWLock; 52 import com.android.internal.annotations.GuardedBy; 53 import com.android.internal.annotations.VisibleForTesting; 54 import com.android.internal.os.ProcessCpuTracker; 55 import com.android.internal.os.TimeoutRecord; 56 import com.android.internal.os.anr.AnrLatencyTracker; 57 import com.android.internal.util.FrameworkStatsLog; 58 import com.android.modules.expresslog.Counter; 59 import com.android.server.ResourcePressureUtil; 60 import com.android.server.criticalevents.CriticalEventLog; 61 import com.android.server.stats.pull.ProcfsMemoryUtil.MemorySnapshot; 62 import com.android.server.wm.WindowProcessController; 63 import com.android.server.utils.AnrTimer; 64 65 import java.io.File; 66 import java.io.PrintWriter; 67 import java.io.StringWriter; 68 import java.time.Instant; 69 import java.time.ZoneId; 70 import java.time.ZonedDateTime; 71 import java.util.ArrayList; 72 import java.util.UUID; 73 import java.util.concurrent.ExecutionException; 74 import java.util.concurrent.ExecutorService; 75 import java.util.concurrent.Future; 76 import java.util.concurrent.atomic.AtomicLong; 77 78 79 /** 80 * The error state of the process, such as if it's crashing/ANR etc. 81 */ 82 class ProcessErrorStateRecord { 83 final ProcessRecord mApp; 84 private final ActivityManagerService mService; 85 86 private final ActivityManagerGlobalLock mProcLock; 87 88 /** 89 * True if disabled in the bad process list. 90 */ 91 @CompositeRWLock({"mService", "mProcLock"}) 92 private boolean mBad; 93 94 /** 95 * Are we in the process of crashing? 96 */ 97 @CompositeRWLock({"mService", "mProcLock"}) 98 private boolean mCrashing; 99 100 /** 101 * Suppress normal auto-dismiss of crash dialog & report UI? 102 */ 103 @CompositeRWLock({"mService", "mProcLock"}) 104 private boolean mForceCrashReport; 105 106 /** 107 * Does the app have a not responding dialog? 108 */ 109 @CompositeRWLock({"mService", "mProcLock"}) 110 private boolean mNotResponding; 111 112 /** 113 * The report about crash of the app, generated & stored when an app gets into a crash. 114 * Will be "null" when all is OK. 115 */ 116 @CompositeRWLock({"mService", "mProcLock"}) 117 private ActivityManager.ProcessErrorStateInfo mCrashingReport; 118 119 /** 120 * The report about ANR of the app, generated & stored when an app gets into an ANR. 121 * Will be "null" when all is OK. 122 */ 123 @CompositeRWLock({"mService", "mProcLock"}) 124 private ActivityManager.ProcessErrorStateInfo mNotRespondingReport; 125 126 /** 127 * Controller for error dialogs. 128 */ 129 @CompositeRWLock({"mService", "mProcLock"}) 130 private final ErrorDialogController mDialogController; 131 132 /** 133 * Who will be notified of the error. This is usually an activity in the 134 * app that installed the package. 135 */ 136 @CompositeRWLock({"mService", "mProcLock"}) 137 private ComponentName mErrorReportReceiver; 138 139 /** 140 * ANR dialog data used to dismiss any visible ANR dialogs if the app becomes responsive. 141 */ 142 @CompositeRWLock({"mService", "mProcLock"}) 143 private AppNotRespondingDialog.Data mAnrData; 144 145 /** 146 * Annotation from process killed due to an ANR. 147 */ 148 @GuardedBy("mService") 149 private String mAnrAnnotation; 150 151 /** 152 * Optional local handler to be invoked in the process crash. 153 */ 154 @CompositeRWLock({"mService", "mProcLock"}) 155 private Runnable mCrashHandler; 156 157 @GuardedBy(anyOf = {"mService", "mProcLock"}) isBad()158 boolean isBad() { 159 return mBad; 160 } 161 162 @GuardedBy({"mService", "mProcLock"}) setBad(boolean bad)163 void setBad(boolean bad) { 164 mBad = bad; 165 } 166 167 @GuardedBy(anyOf = {"mService", "mProcLock"}) isCrashing()168 boolean isCrashing() { 169 return mCrashing; 170 } 171 172 @GuardedBy({"mService", "mProcLock"}) setCrashing(boolean crashing)173 void setCrashing(boolean crashing) { 174 mCrashing = crashing; 175 mApp.getWindowProcessController().setCrashing(crashing); 176 } 177 178 @GuardedBy(anyOf = {"mService", "mProcLock"}) isForceCrashReport()179 boolean isForceCrashReport() { 180 return mForceCrashReport; 181 } 182 183 @GuardedBy({"mService", "mProcLock"}) setForceCrashReport(boolean forceCrashReport)184 void setForceCrashReport(boolean forceCrashReport) { 185 mForceCrashReport = forceCrashReport; 186 } 187 188 @GuardedBy(anyOf = {"mService", "mProcLock"}) isNotResponding()189 boolean isNotResponding() { 190 return mNotResponding; 191 } 192 193 @GuardedBy({"mService", "mProcLock"}) setNotResponding(boolean notResponding)194 void setNotResponding(boolean notResponding) { 195 mNotResponding = notResponding; 196 mApp.getWindowProcessController().setNotResponding(notResponding); 197 } 198 199 @GuardedBy(anyOf = {"mService", "mProcLock"}) getCrashHandler()200 Runnable getCrashHandler() { 201 return mCrashHandler; 202 } 203 204 @GuardedBy({"mService", "mProcLock"}) setCrashHandler(Runnable crashHandler)205 void setCrashHandler(Runnable crashHandler) { 206 mCrashHandler = crashHandler; 207 } 208 209 @GuardedBy(anyOf = {"mService", "mProcLock"}) getCrashingReport()210 ActivityManager.ProcessErrorStateInfo getCrashingReport() { 211 return mCrashingReport; 212 } 213 214 @GuardedBy({"mService", "mProcLock"}) setCrashingReport(ActivityManager.ProcessErrorStateInfo crashingReport)215 void setCrashingReport(ActivityManager.ProcessErrorStateInfo crashingReport) { 216 mCrashingReport = crashingReport; 217 } 218 219 @GuardedBy("mService") getAnrAnnotation()220 String getAnrAnnotation() { 221 return mAnrAnnotation; 222 } 223 224 @GuardedBy("mService") setAnrAnnotation(String anrAnnotation)225 void setAnrAnnotation(String anrAnnotation) { 226 mAnrAnnotation = anrAnnotation; 227 } 228 229 @GuardedBy(anyOf = {"mService", "mProcLock"}) getNotRespondingReport()230 ActivityManager.ProcessErrorStateInfo getNotRespondingReport() { 231 return mNotRespondingReport; 232 } 233 234 @GuardedBy({"mService", "mProcLock"}) setNotRespondingReport(ActivityManager.ProcessErrorStateInfo notRespondingReport)235 void setNotRespondingReport(ActivityManager.ProcessErrorStateInfo notRespondingReport) { 236 mNotRespondingReport = notRespondingReport; 237 } 238 239 @GuardedBy(anyOf = {"mService", "mProcLock"}) getErrorReportReceiver()240 ComponentName getErrorReportReceiver() { 241 return mErrorReportReceiver; 242 } 243 244 @GuardedBy({"mService", "mProcLock"}) setErrorReportReceiver(ComponentName errorReportReceiver)245 void setErrorReportReceiver(ComponentName errorReportReceiver) { 246 mErrorReportReceiver = errorReportReceiver; 247 } 248 249 @GuardedBy(anyOf = {"mService", "mProcLock"}) getDialogController()250 ErrorDialogController getDialogController() { 251 return mDialogController; 252 } 253 254 @GuardedBy({"mService", "mProcLock"}) setAnrData(AppNotRespondingDialog.Data data)255 void setAnrData(AppNotRespondingDialog.Data data) { 256 mAnrData = data; 257 } 258 259 @GuardedBy(anyOf = {"mService", "mProcLock"}) getAnrData()260 AppNotRespondingDialog.Data getAnrData() { 261 return mAnrData; 262 } 263 ProcessErrorStateRecord(ProcessRecord app)264 ProcessErrorStateRecord(ProcessRecord app) { 265 mApp = app; 266 mService = app.mService; 267 mProcLock = mService.mProcLock; 268 mDialogController = new ErrorDialogController(app); 269 } 270 271 @GuardedBy("mService") skipAnrLocked(String annotation)272 boolean skipAnrLocked(String annotation) { 273 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 274 if (mService.mAtmInternal.isShuttingDown()) { 275 Slog.i(TAG, "During shutdown skipping ANR: " + this + " " + annotation); 276 return true; 277 } else if (isNotResponding()) { 278 Slog.i(TAG, "Skipping duplicate ANR: " + this + " " + annotation); 279 return true; 280 } else if (isCrashing()) { 281 Slog.i(TAG, "Crashing app skipping ANR: " + this + " " + annotation); 282 return true; 283 } else if (mApp.isKilledByAm()) { 284 Slog.i(TAG, "App already killed by AM skipping ANR: " + this + " " + annotation); 285 return true; 286 } else if (mApp.isKilled()) { 287 Slog.i(TAG, "Skipping died app ANR: " + this + " " + annotation); 288 return true; 289 } 290 return false; 291 } 292 appNotResponding(String activityShortComponentName, ApplicationInfo aInfo, String parentShortComponentName, WindowProcessController parentProcess, boolean aboveSystem, TimeoutRecord timeoutRecord, ExecutorService auxiliaryTaskExecutor, boolean onlyDumpSelf, boolean isContinuousAnr, Future<File> firstPidFilePromise)293 void appNotResponding(String activityShortComponentName, ApplicationInfo aInfo, 294 String parentShortComponentName, WindowProcessController parentProcess, 295 boolean aboveSystem, TimeoutRecord timeoutRecord, 296 ExecutorService auxiliaryTaskExecutor, boolean onlyDumpSelf, 297 boolean isContinuousAnr, Future<File> firstPidFilePromise) { 298 String annotation = timeoutRecord.mReason; 299 AnrLatencyTracker latencyTracker = timeoutRecord.mLatencyTracker; 300 Future<?> updateCpuStatsNowFirstCall = null; 301 302 ArrayList<Integer> firstPids = new ArrayList<>(5); 303 SparseBooleanArray lastPids = new SparseBooleanArray(20); 304 ActivityManagerService.VolatileDropboxEntryStates volatileDropboxEntriyStates = null; 305 306 // Release the expired timer preparatory to starting the dump or returning without dumping. 307 timeoutRecord.closeExpiredTimer(); 308 309 if (mApp.isDebugging()) { 310 Slog.i(TAG, "Skipping debugged app ANR: " + this + " " + annotation); 311 return; 312 } 313 314 mApp.getWindowProcessController().appEarlyNotResponding(annotation, () -> { 315 latencyTracker.waitingOnAMSLockStarted(); 316 synchronized (mService) { 317 latencyTracker.waitingOnAMSLockEnded(); 318 // Store annotation here as instance below races with this killLocked. 319 setAnrAnnotation(annotation); 320 mApp.killLocked("anr", ApplicationExitInfo.REASON_ANR, true); 321 } 322 }); 323 324 long anrTime = SystemClock.uptimeMillis(); 325 326 if (isMonitorCpuUsage()) { 327 updateCpuStatsNowFirstCall = auxiliaryTaskExecutor.submit( 328 () -> { 329 latencyTracker.updateCpuStatsNowCalled(); 330 mService.updateCpuStatsNow(); 331 latencyTracker.updateCpuStatsNowReturned(); 332 }); 333 334 } 335 336 final boolean isSilentAnr; 337 final int pid; 338 final UUID errorId; 339 latencyTracker.waitingOnAMSLockStarted(); 340 synchronized (mService) { 341 latencyTracker.waitingOnAMSLockEnded(); 342 // Get the process's pid after obtaining the global lock. 343 pid = mApp.getPid(); 344 // Store annotation here as instance above will not be hit on all paths. 345 setAnrAnnotation(annotation); 346 347 Counter.logIncrement("stability_anr.value_total_anrs"); 348 if (skipAnrLocked(annotation)) { 349 latencyTracker.anrSkippedProcessErrorStateRecordAppNotResponding(); 350 Counter.logIncrement("stability_anr.value_skipped_anrs"); 351 return; 352 } 353 // In case we come through here for the same app before completing 354 // this one, mark as anring now so we will bail out. 355 latencyTracker.waitingOnProcLockStarted(); 356 synchronized (mProcLock) { 357 latencyTracker.waitingOnProcLockEnded(); 358 setNotResponding(true); 359 360 ZonedDateTime timestamp = null; 361 if (timeoutRecord != null && timeoutRecord.mEndUptimeMillis > 0) { 362 long millisSinceEndUptimeMs = anrTime - timeoutRecord.mEndUptimeMillis; 363 timestamp = Instant.now().minusMillis(millisSinceEndUptimeMs) 364 .atZone(ZoneId.systemDefault()); 365 } 366 367 volatileDropboxEntriyStates = 368 ActivityManagerService.VolatileDropboxEntryStates 369 .withProcessFrozenStateAndTimestamp( 370 mApp.mOptRecord.isFrozen(), timestamp); 371 } 372 373 // Log the ANR to the event log. 374 EventLog.writeEvent(EventLogTags.AM_ANR, mApp.userId, pid, mApp.processName, 375 mApp.info.flags, annotation); 376 377 if (mService.mTraceErrorLogger != null 378 && mService.mTraceErrorLogger.isAddErrorIdEnabled()) { 379 errorId = mService.mTraceErrorLogger.generateErrorId(); 380 mService.mTraceErrorLogger.addProcessInfoAndErrorIdToTrace( 381 mApp.processName, pid, errorId); 382 mService.mTraceErrorLogger.addSubjectToTrace(annotation, errorId); 383 } else { 384 errorId = null; 385 } 386 387 // This atom is only logged with the purpose of triggering Perfetto and the logging 388 // needs to happen as close as possible to the time when the ANR is detected. 389 // Also, it needs to be logged after adding the error id to the trace, to make sure 390 // the error id is present in the trace when the Perfetto trace is captured. 391 FrameworkStatsLog.write(FrameworkStatsLog.ANR_OCCURRED_PROCESSING_STARTED, 392 mApp.processName); 393 394 // Dump thread traces as quickly as we can, starting with "interesting" processes. 395 firstPids.add(pid); 396 397 // Don't dump other PIDs if it's a background ANR or is requested to only dump self. 398 // Note that the primary pid is added here just in case, as it should normally be 399 // dumped on the early dump thread, and would only be dumped on the Anr consumer thread 400 // as a fallback. 401 isSilentAnr = isSilentAnr(); 402 if (!isSilentAnr && !onlyDumpSelf) { 403 int parentPid = pid; 404 if (parentProcess != null && parentProcess.getPid() > 0) { 405 parentPid = parentProcess.getPid(); 406 } 407 if (parentPid != pid) firstPids.add(parentPid); 408 409 if (MY_PID != pid && MY_PID != parentPid) firstPids.add(MY_PID); 410 411 final int ppid = parentPid; 412 mService.mProcessList.forEachLruProcessesLOSP(false, r -> { 413 if (r != null && r.getThread() != null) { 414 int myPid = r.getPid(); 415 if (myPid > 0 && myPid != pid && myPid != ppid && myPid != MY_PID) { 416 if (r.isPersistent()) { 417 firstPids.add(myPid); 418 if (DEBUG_ANR) Slog.i(TAG, "Adding persistent proc: " + r); 419 } else if (r.mServices.isTreatedLikeActivity()) { 420 firstPids.add(myPid); 421 if (DEBUG_ANR) Slog.i(TAG, "Adding likely IME: " + r); 422 } else { 423 lastPids.put(myPid, true); 424 if (DEBUG_ANR) Slog.i(TAG, "Adding ANR proc: " + r); 425 } 426 } 427 } 428 }); 429 } 430 } 431 // Build memory headers for the ANRing process. 432 String memoryHeaders = buildMemoryHeadersFor(pid); 433 434 // Get critical event log before logging the ANR so that it doesn't occur in the log. 435 latencyTracker.criticalEventLogStarted(); 436 final String criticalEventLog = 437 CriticalEventLog.getInstance().logLinesForTraceFile( 438 mApp.getProcessClassEnum(), mApp.processName, mApp.uid); 439 latencyTracker.criticalEventLogEnded(); 440 CriticalEventLog.getInstance().logAnr(annotation, mApp.getProcessClassEnum(), 441 mApp.processName, mApp.uid, mApp.mPid); 442 443 // Log the ANR to the main log. 444 StringBuilder info = new StringBuilder(); 445 info.setLength(0); 446 info.append("ANR in ").append(mApp.processName); 447 if (activityShortComponentName != null) { 448 info.append(" (").append(activityShortComponentName).append(")"); 449 } 450 info.append("\n"); 451 info.append("PID: ").append(pid).append("\n"); 452 if (annotation != null) { 453 info.append("Reason: ").append(annotation).append("\n"); 454 } 455 if (parentShortComponentName != null 456 && parentShortComponentName.equals(activityShortComponentName)) { 457 info.append("Parent: ").append(parentShortComponentName).append("\n"); 458 } 459 if (errorId != null) { 460 info.append("ErrorId: ").append(errorId.toString()).append("\n"); 461 } 462 info.append("Frozen: ").append(mApp.mOptRecord.isFrozen()).append("\n"); 463 464 // Retrieve controller with max ANR delay from AnrControllers 465 // Note that we retrieve the controller before dumping stacks because dumping stacks can 466 // take a few seconds, after which the cause of the ANR delay might have completed and 467 // there might no longer be a valid ANR controller to cancel the dialog in that case 468 AnrController anrController = mService.mActivityTaskManager.getAnrController(aInfo); 469 long anrDialogDelayMs = 0; 470 if (anrController != null) { 471 String packageName = aInfo.packageName; 472 int uid = aInfo.uid; 473 anrDialogDelayMs = anrController.getAnrDelayMillis(packageName, uid); 474 // Might execute an async binder call to a system app to show an interim 475 // ANR progress UI 476 anrController.onAnrDelayStarted(packageName, uid); 477 Slog.i(TAG, "ANR delay of " + anrDialogDelayMs + "ms started for " + packageName); 478 } 479 480 StringBuilder report = new StringBuilder(); 481 482 latencyTracker.currentPsiStateCalled(); 483 String currentPsiState = ResourcePressureUtil.currentPsiState(); 484 latencyTracker.currentPsiStateReturned(); 485 report.append(currentPsiState); 486 // The 'processCpuTracker' variable is a shared resource that might be initialized and 487 // updated in a different thread. In order to prevent thread visibility issues, which 488 // can occur when one thread does not immediately see the changes made to 489 // 'processCpuTracker' by another thread, it is necessary to use synchronization whenever 490 // 'processCpuTracker' is accessed or modified. 491 ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 492 493 // We push the native pids collection task to the helper thread through 494 // the Anr auxiliary task executor, and wait on it later after dumping the first pids 495 Future<ArrayList<Integer>> nativePidsFuture = 496 auxiliaryTaskExecutor.submit( 497 () -> { 498 latencyTracker.nativePidCollectionStarted(); 499 // don't dump native PIDs for background ANRs unless 500 // it is the process of interest 501 String[] nativeProcs = null; 502 boolean isSystemApp = mApp.info.isSystemApp() || mApp.info.isSystemExt(); 503 // Do not collect system daemons dumps as this is not likely to be useful 504 // for non-system apps. 505 if (!isSystemApp || isSilentAnr || onlyDumpSelf) { 506 for (int i = 0; i < NATIVE_STACKS_OF_INTEREST.length; i++) { 507 if (NATIVE_STACKS_OF_INTEREST[i].equals(mApp.processName)) { 508 nativeProcs = new String[] { mApp.processName }; 509 break; 510 } 511 } 512 } else { 513 nativeProcs = NATIVE_STACKS_OF_INTEREST; 514 } 515 516 int[] pids = nativeProcs == null 517 ? null : Process.getPidsForCommands(nativeProcs); 518 ArrayList<Integer> nativePids = null; 519 520 if (pids != null) { 521 nativePids = new ArrayList<>(pids.length); 522 for (int i : pids) { 523 nativePids.add(i); 524 } 525 } 526 latencyTracker.nativePidCollectionEnded(); 527 return nativePids; 528 }); 529 530 // For background ANRs, don't pass the ProcessCpuTracker to 531 // avoid spending 1/2 second collecting stats to rank lastPids. 532 StringWriter tracesFileException = new StringWriter(); 533 // To hold the start and end offset to the ANR trace file respectively. 534 final AtomicLong firstPidEndOffset = new AtomicLong(-1); 535 File tracesFile = StackTracesDumpHelper.dumpStackTraces(firstPids, 536 isSilentAnr ? null : processCpuTracker, isSilentAnr ? null : lastPids, 537 nativePidsFuture, tracesFileException, firstPidEndOffset, annotation, 538 criticalEventLog, memoryHeaders, auxiliaryTaskExecutor, firstPidFilePromise, 539 latencyTracker); 540 541 if (isMonitorCpuUsage()) { 542 // Wait for the first call to finish 543 try { 544 updateCpuStatsNowFirstCall.get(); 545 } catch (ExecutionException e) { 546 Slog.w(TAG, "Failed to update the CPU stats", e.getCause()); 547 } catch (InterruptedException e) { 548 Slog.w(TAG, "Interrupted while updating the CPU stats", e); 549 } 550 mService.updateCpuStatsNow(); 551 mService.mAppProfiler.printCurrentCpuState(report, anrTime); 552 synchronized (processCpuTracker) { 553 info.append(processCpuTracker.printCurrentLoad()); 554 } 555 info.append(report); 556 } 557 report.append(tracesFileException.getBuffer()); 558 559 synchronized (processCpuTracker) { 560 info.append(processCpuTracker.printCurrentState(anrTime)); 561 } 562 563 Slog.e(TAG, info.toString()); 564 if (tracesFile == null) { 565 // There is no trace file, so dump (only) the alleged culprit's threads to the log 566 Process.sendSignal(pid, Process.SIGNAL_QUIT); 567 } else if (firstPidEndOffset.get() > 0) { 568 // We've dumped into the trace file successfully 569 // We pass the start and end offsets of the first section of 570 // the ANR file (the headers and first process dump) 571 final long startOffset = 0L; 572 final long endOffset = firstPidEndOffset.get(); 573 mService.mProcessList.mAppExitInfoTracker.scheduleLogAnrTrace( 574 pid, mApp.uid, mApp.getPackageList(), tracesFile, startOffset, endOffset); 575 } 576 577 // Check if package is still being loaded 578 float loadingProgress = 1; 579 IncrementalMetrics incrementalMetrics = null; 580 final PackageManagerInternal packageManagerInternal = mService.getPackageManagerInternal(); 581 if (mApp.info != null && mApp.info.packageName != null && packageManagerInternal != null) { 582 IncrementalStatesInfo incrementalStatesInfo = 583 packageManagerInternal.getIncrementalStatesInfo( 584 mApp.info.packageName, SYSTEM_UID, mApp.userId); 585 if (incrementalStatesInfo != null) { 586 loadingProgress = incrementalStatesInfo.getProgress(); 587 } 588 final String codePath = mApp.info.getCodePath(); 589 if (codePath != null && !codePath.isEmpty() 590 && IncrementalManager.isIncrementalPath(codePath)) { 591 // Report in the main log that the incremental package is still loading 592 Slog.e(TAG, "App ANR on incremental package " + mApp.info.packageName 593 + " which is " + ((int) (loadingProgress * 100)) + "% loaded."); 594 final IBinder incrementalService = ServiceManager.getService( 595 Context.INCREMENTAL_SERVICE); 596 if (incrementalService != null) { 597 final IncrementalManager incrementalManager = new IncrementalManager( 598 IIncrementalService.Stub.asInterface(incrementalService)); 599 incrementalMetrics = incrementalManager.getMetrics(codePath); 600 } 601 } 602 } 603 if (incrementalMetrics != null) { 604 // Report in the main log about the incremental package 605 info.append("Package is ").append((int) (loadingProgress * 100)).append("% loaded.\n"); 606 } 607 608 FrameworkStatsLog.write(FrameworkStatsLog.ANR_OCCURRED, mApp.uid, mApp.processName, 609 activityShortComponentName == null ? "unknown" : activityShortComponentName, 610 annotation, 611 (mApp.info != null) ? (mApp.info.isInstantApp() 612 ? FrameworkStatsLog.ANROCCURRED__IS_INSTANT_APP__TRUE 613 : FrameworkStatsLog.ANROCCURRED__IS_INSTANT_APP__FALSE) 614 : FrameworkStatsLog.ANROCCURRED__IS_INSTANT_APP__UNAVAILABLE, 615 mApp.isInterestingToUserLocked() 616 ? FrameworkStatsLog.ANROCCURRED__FOREGROUND_STATE__FOREGROUND 617 : FrameworkStatsLog.ANROCCURRED__FOREGROUND_STATE__BACKGROUND, 618 mApp.getProcessClassEnum(), 619 (mApp.info != null) ? mApp.info.packageName : "", 620 incrementalMetrics != null /* isIncremental */, loadingProgress, 621 incrementalMetrics != null ? incrementalMetrics.getMillisSinceOldestPendingRead() 622 : -1, 623 incrementalMetrics != null ? incrementalMetrics.getStorageHealthStatusCode() 624 : -1, 625 incrementalMetrics != null ? incrementalMetrics.getDataLoaderStatusCode() 626 : -1, 627 incrementalMetrics != null && incrementalMetrics.getReadLogsEnabled(), 628 incrementalMetrics != null ? incrementalMetrics.getMillisSinceLastDataLoaderBind() 629 : -1, 630 incrementalMetrics != null ? incrementalMetrics.getDataLoaderBindDelayMillis() 631 : -1, 632 incrementalMetrics != null ? incrementalMetrics.getTotalDelayedReads() 633 : -1, 634 incrementalMetrics != null ? incrementalMetrics.getTotalFailedReads() 635 : -1, 636 incrementalMetrics != null ? incrementalMetrics.getLastReadErrorUid() 637 : -1, 638 incrementalMetrics != null ? incrementalMetrics.getMillisSinceLastReadError() 639 : -1, 640 incrementalMetrics != null ? incrementalMetrics.getLastReadErrorNumber() 641 : 0, 642 incrementalMetrics != null ? incrementalMetrics.getTotalDelayedReadsDurationMillis() 643 : -1); 644 final ProcessRecord parentPr = parentProcess != null 645 ? (ProcessRecord) parentProcess.mOwner : null; 646 mService.addErrorToDropBox("anr", mApp, mApp.processName, activityShortComponentName, 647 parentShortComponentName, parentPr, null, report.toString(), tracesFile, 648 null, new Float(loadingProgress), incrementalMetrics, errorId, 649 volatileDropboxEntriyStates); 650 651 if (mApp.getWindowProcessController().appNotResponding(info.toString(), 652 () -> { 653 synchronized (mService) { 654 mApp.killLocked("anr", ApplicationExitInfo.REASON_ANR, true); 655 } 656 }, 657 () -> { 658 synchronized (mService) { 659 mService.mServices.scheduleServiceTimeoutLocked(mApp); 660 } 661 })) { 662 return; 663 } 664 665 synchronized (mService) { 666 // mBatteryStatsService can be null if the AMS is constructed with injector only. This 667 // will only happen in tests. 668 if (mService.mBatteryStatsService != null) { 669 mService.mBatteryStatsService.noteProcessAnr(mApp.processName, mApp.uid); 670 } 671 672 if (isSilentAnr() && !mApp.isDebugging()) { 673 mApp.killLocked("bg anr", ApplicationExitInfo.REASON_ANR, true); 674 return; 675 } 676 677 synchronized (mProcLock) { 678 // Set the app's notResponding state, and look up the errorReportReceiver 679 makeAppNotRespondingLSP(activityShortComponentName, 680 annotation != null ? "ANR " + annotation : "ANR", info.toString()); 681 mDialogController.setAnrController(anrController); 682 } 683 684 // mUiHandler can be null if the AMS is constructed with injector only. This will only 685 // happen in tests. 686 if (mService.mUiHandler != null) { 687 // Bring up the infamous App Not Responding dialog 688 Message msg = Message.obtain(); 689 msg.what = ActivityManagerService.SHOW_NOT_RESPONDING_UI_MSG; 690 msg.obj = new AppNotRespondingDialog.Data(mApp, aInfo, aboveSystem, 691 isContinuousAnr); 692 693 mService.mUiHandler.sendMessageDelayed(msg, anrDialogDelayMs); 694 } 695 } 696 } 697 698 @GuardedBy({"mService", "mProcLock"}) makeAppNotRespondingLSP(String activity, String shortMsg, String longMsg)699 private void makeAppNotRespondingLSP(String activity, String shortMsg, String longMsg) { 700 setNotResponding(true); 701 // mAppErrors can be null if the AMS is constructed with injector only. This will only 702 // happen in tests. 703 if (mService.mAppErrors != null) { 704 mNotRespondingReport = mService.mAppErrors.generateProcessError(mApp, 705 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 706 activity, shortMsg, longMsg, null); 707 } 708 startAppProblemLSP(); 709 mApp.getWindowProcessController().stopFreezingActivities(); 710 } 711 712 @GuardedBy({"mService", "mProcLock"}) startAppProblemLSP()713 void startAppProblemLSP() { 714 // If this app is not running under the current user, then we can't give it a report button 715 // because that would require launching the report UI under a different user. 716 mErrorReportReceiver = null; 717 718 for (int userId : mService.mUserController.getCurrentProfileIds()) { 719 if (mApp.userId == userId) { 720 mErrorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 721 mService.mContext, mApp.info.packageName, mApp.info.flags); 722 } 723 } 724 mService.getBroadcastQueue().onApplicationProblemLocked(mApp); 725 } 726 727 @GuardedBy("mService") isInterestingForBackgroundTraces()728 private boolean isInterestingForBackgroundTraces() { 729 // The system_server is always considered interesting. 730 if (mApp.getPid() == MY_PID) { 731 return true; 732 } 733 734 // A package is considered interesting if any of the following is true : 735 // 736 // - It's displaying an activity. 737 // - It's the SystemUI. 738 // - It has an overlay or a top UI visible. 739 // 740 // NOTE: The check whether a given ProcessRecord belongs to the systemui 741 // process is a bit of a kludge, but the same pattern seems repeated at 742 // several places in the system server. 743 return mApp.isInterestingToUserLocked() 744 || (mApp.info != null && "com.android.systemui".equals(mApp.info.packageName)) 745 || (mApp.mState.hasTopUi() || mApp.mState.hasOverlayUi()); 746 } 747 getShowBackground()748 private boolean getShowBackground() { 749 final ContentResolver resolver = mService.mContext.getContentResolver(); 750 return Settings.Secure.getIntForUser(resolver, 751 Settings.Secure.ANR_SHOW_BACKGROUND, 752 0, 753 resolver.getUserId()) != 0; 754 } 755 buildMemoryHeadersFor(int pid)756 private @Nullable String buildMemoryHeadersFor(int pid) { 757 if (pid <= 0) { 758 Slog.i(TAG, "Memory header requested with invalid pid: " + pid); 759 return null; 760 } 761 MemorySnapshot snapshot = readMemorySnapshotFromProcfs(pid); 762 if (snapshot == null) { 763 Slog.i(TAG, "Failed to get memory snapshot for pid:" + pid); 764 return null; 765 } 766 767 StringBuilder memoryHeaders = new StringBuilder(); 768 memoryHeaders.append("RssHwmKb: ") 769 .append(snapshot.rssHighWaterMarkInKilobytes) 770 .append("\n"); 771 memoryHeaders.append("RssKb: ").append(snapshot.rssInKilobytes).append("\n"); 772 memoryHeaders.append("RssAnonKb: ").append(snapshot.anonRssInKilobytes).append("\n"); 773 memoryHeaders.append("RssShmemKb: ").append(snapshot.rssShmemKilobytes).append("\n"); 774 memoryHeaders.append("VmSwapKb: ").append(snapshot.swapInKilobytes).append("\n"); 775 return memoryHeaders.toString(); 776 } 777 /** 778 * Unless configured otherwise, swallow ANRs in background processes & kill the process. 779 * Non-private access is for tests only. 780 */ 781 @VisibleForTesting 782 @GuardedBy("mService") isSilentAnr()783 boolean isSilentAnr() { 784 return !getShowBackground() && !isInterestingForBackgroundTraces(); 785 } 786 787 /** Non-private access is for tests only. */ 788 @VisibleForTesting isMonitorCpuUsage()789 boolean isMonitorCpuUsage() { 790 return mService.mAppProfiler.MONITOR_CPU_USAGE; 791 } 792 793 @GuardedBy({"mService", "mProcLock"}) onCleanupApplicationRecordLSP()794 void onCleanupApplicationRecordLSP() { 795 // Dismiss any open dialogs. 796 getDialogController().clearAllErrorDialogs(); 797 798 setCrashing(false); 799 setNotResponding(false); 800 } 801 dump(PrintWriter pw, String prefix, long nowUptime)802 void dump(PrintWriter pw, String prefix, long nowUptime) { 803 synchronized (mProcLock) { 804 if (mCrashing || mDialogController.hasCrashDialogs() || mNotResponding 805 || mDialogController.hasAnrDialogs() || mBad) { 806 pw.print(prefix); 807 pw.print(" mCrashing=" + mCrashing); 808 pw.print(" " + mDialogController.getCrashDialogs()); 809 pw.print(" mNotResponding=" + mNotResponding); 810 pw.print(" " + mDialogController.getAnrDialogs()); 811 pw.print(" bad=" + mBad); 812 813 // mCrashing or mNotResponding is always set before errorReportReceiver 814 if (mErrorReportReceiver != null) { 815 pw.print(" errorReportReceiver="); 816 pw.print(mErrorReportReceiver.flattenToShortString()); 817 } 818 pw.println(); 819 } 820 } 821 } 822 } 823