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