AppErrors.java revision fa3991aae02676d5c619c86adf514def09802d78
1/* 2 * Copyright (C) 2016 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 17package com.android.server.am; 18 19import com.android.internal.app.ProcessMap; 20import com.android.internal.logging.MetricsLogger; 21import com.android.internal.logging.MetricsProto; 22import com.android.internal.os.ProcessCpuTracker; 23import com.android.server.Watchdog; 24 25import android.app.Activity; 26import android.app.ActivityManager; 27import android.app.ActivityOptions; 28import android.app.ActivityThread; 29import android.app.AppOpsManager; 30import android.app.ApplicationErrorReport; 31import android.app.Dialog; 32import android.content.ActivityNotFoundException; 33import android.content.Context; 34import android.content.Intent; 35import android.content.pm.ApplicationInfo; 36import android.content.pm.IPackageDataObserver; 37import android.content.pm.PackageManager; 38import android.os.Binder; 39import android.os.Bundle; 40import android.os.Message; 41import android.os.Process; 42import android.os.RemoteException; 43import android.os.SystemClock; 44import android.os.SystemProperties; 45import android.os.UserHandle; 46import android.provider.Settings; 47import android.util.ArrayMap; 48import android.util.ArraySet; 49import android.util.EventLog; 50import android.util.Log; 51import android.util.Slog; 52import android.util.SparseArray; 53import android.util.TimeUtils; 54 55import java.io.File; 56import java.io.FileDescriptor; 57import java.io.PrintWriter; 58import java.util.ArrayList; 59import java.util.Collections; 60import java.util.HashMap; 61import java.util.concurrent.Semaphore; 62 63import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 64import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR; 65import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; 66import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; 67import static com.android.server.am.ActivityManagerService.MY_PID; 68import static com.android.server.am.ActivityManagerService.SYSTEM_DEBUGGABLE; 69 70/** 71 * Controls error conditions in applications. 72 */ 73class AppErrors { 74 75 private static final String TAG = TAG_WITH_CLASS_NAME ? "AppErrors" : TAG_AM; 76 77 private final ActivityManagerService mService; 78 private final Context mContext; 79 80 private ArraySet<String> mAppsNotReportingCrashes; 81 82 /** 83 * The last time that various processes have crashed since they were last explicitly started. 84 */ 85 private final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<>(); 86 87 /** 88 * The last time that various processes have crashed (not reset even when explicitly started). 89 */ 90 private final ProcessMap<Long> mProcessCrashTimesPersistent = new ProcessMap<>(); 91 92 /** 93 * Set of applications that we consider to be bad, and will reject 94 * incoming broadcasts from (which the user has no control over). 95 * Processes are added to this set when they have crashed twice within 96 * a minimum amount of time; they are removed from it when they are 97 * later restarted (hopefully due to some user action). The value is the 98 * time it was added to the list. 99 */ 100 private final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<>(); 101 102 103 AppErrors(Context context, ActivityManagerService service) { 104 mService = service; 105 mContext = context; 106 } 107 108 boolean dumpLocked(FileDescriptor fd, PrintWriter pw, boolean needSep, 109 String dumpPackage) { 110 if (!mProcessCrashTimes.getMap().isEmpty()) { 111 boolean printed = false; 112 final long now = SystemClock.uptimeMillis(); 113 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 114 final int processCount = pmap.size(); 115 for (int ip = 0; ip < processCount; ip++) { 116 final String pname = pmap.keyAt(ip); 117 final SparseArray<Long> uids = pmap.valueAt(ip); 118 final int uidCount = uids.size(); 119 for (int i = 0; i < uidCount; i++) { 120 final int puid = uids.keyAt(i); 121 final ProcessRecord r = mService.mProcessNames.get(pname, puid); 122 if (dumpPackage != null && (r == null 123 || !r.pkgList.containsKey(dumpPackage))) { 124 continue; 125 } 126 if (!printed) { 127 if (needSep) pw.println(); 128 needSep = true; 129 pw.println(" Time since processes crashed:"); 130 printed = true; 131 } 132 pw.print(" Process "); pw.print(pname); 133 pw.print(" uid "); pw.print(puid); 134 pw.print(": last crashed "); 135 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 136 pw.println(" ago"); 137 } 138 } 139 } 140 141 if (!mBadProcesses.getMap().isEmpty()) { 142 boolean printed = false; 143 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 144 final int processCount = pmap.size(); 145 for (int ip = 0; ip < processCount; ip++) { 146 final String pname = pmap.keyAt(ip); 147 final SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 148 final int uidCount = uids.size(); 149 for (int i = 0; i < uidCount; i++) { 150 final int puid = uids.keyAt(i); 151 final ProcessRecord r = mService.mProcessNames.get(pname, puid); 152 if (dumpPackage != null && (r == null 153 || !r.pkgList.containsKey(dumpPackage))) { 154 continue; 155 } 156 if (!printed) { 157 if (needSep) pw.println(); 158 needSep = true; 159 pw.println(" Bad processes:"); 160 printed = true; 161 } 162 final BadProcessInfo info = uids.valueAt(i); 163 pw.print(" Bad process "); pw.print(pname); 164 pw.print(" uid "); pw.print(puid); 165 pw.print(": crashed at time "); pw.println(info.time); 166 if (info.shortMsg != null) { 167 pw.print(" Short msg: "); pw.println(info.shortMsg); 168 } 169 if (info.longMsg != null) { 170 pw.print(" Long msg: "); pw.println(info.longMsg); 171 } 172 if (info.stack != null) { 173 pw.println(" Stack:"); 174 int lastPos = 0; 175 for (int pos = 0; pos < info.stack.length(); pos++) { 176 if (info.stack.charAt(pos) == '\n') { 177 pw.print(" "); 178 pw.write(info.stack, lastPos, pos-lastPos); 179 pw.println(); 180 lastPos = pos+1; 181 } 182 } 183 if (lastPos < info.stack.length()) { 184 pw.print(" "); 185 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 186 pw.println(); 187 } 188 } 189 } 190 } 191 } 192 return needSep; 193 } 194 195 boolean isBadProcessLocked(ApplicationInfo info) { 196 return mBadProcesses.get(info.processName, info.uid) != null; 197 } 198 199 void clearBadProcessLocked(ApplicationInfo info) { 200 mBadProcesses.remove(info.processName, info.uid); 201 } 202 203 void resetProcessCrashTimeLocked(ApplicationInfo info) { 204 mProcessCrashTimes.remove(info.processName, info.uid); 205 } 206 207 void resetProcessCrashTimeLocked(boolean resetEntireUser, int appId, int userId) { 208 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 209 for (int ip = pmap.size() - 1; ip >= 0; ip--) { 210 SparseArray<Long> ba = pmap.valueAt(ip); 211 for (int i = ba.size() - 1; i >= 0; i--) { 212 boolean remove = false; 213 final int entUid = ba.keyAt(i); 214 if (!resetEntireUser) { 215 if (userId == UserHandle.USER_ALL) { 216 if (UserHandle.getAppId(entUid) == appId) { 217 remove = true; 218 } 219 } else { 220 if (entUid == UserHandle.getUid(userId, appId)) { 221 remove = true; 222 } 223 } 224 } else if (UserHandle.getUserId(entUid) == userId) { 225 remove = true; 226 } 227 if (remove) { 228 ba.removeAt(i); 229 } 230 } 231 if (ba.size() == 0) { 232 pmap.removeAt(ip); 233 } 234 } 235 } 236 237 void loadAppsNotReportingCrashesFromConfigLocked(String appsNotReportingCrashesConfig) { 238 if (appsNotReportingCrashesConfig != null) { 239 final String[] split = appsNotReportingCrashesConfig.split(","); 240 if (split.length > 0) { 241 mAppsNotReportingCrashes = new ArraySet<>(); 242 Collections.addAll(mAppsNotReportingCrashes, split); 243 } 244 } 245 } 246 247 void killAppAtUserRequestLocked(ProcessRecord app, Dialog fromDialog) { 248 app.crashing = false; 249 app.crashingReport = null; 250 app.notResponding = false; 251 app.notRespondingReport = null; 252 if (app.anrDialog == fromDialog) { 253 app.anrDialog = null; 254 } 255 if (app.waitDialog == fromDialog) { 256 app.waitDialog = null; 257 } 258 if (app.pid > 0 && app.pid != MY_PID) { 259 handleAppCrashLocked(app, "user-terminated" /*reason*/, 260 null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/, null /*data*/); 261 app.kill("user request after error", true); 262 } 263 } 264 265 void scheduleAppCrashLocked(int uid, int initialPid, String packageName, 266 String message) { 267 ProcessRecord proc = null; 268 269 // Figure out which process to kill. We don't trust that initialPid 270 // still has any relation to current pids, so must scan through the 271 // list. 272 273 synchronized (mService.mPidsSelfLocked) { 274 for (int i=0; i<mService.mPidsSelfLocked.size(); i++) { 275 ProcessRecord p = mService.mPidsSelfLocked.valueAt(i); 276 if (p.uid != uid) { 277 continue; 278 } 279 if (p.pid == initialPid) { 280 proc = p; 281 break; 282 } 283 if (p.pkgList.containsKey(packageName)) { 284 proc = p; 285 } 286 } 287 } 288 289 if (proc == null) { 290 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 291 + " initialPid=" + initialPid 292 + " packageName=" + packageName); 293 return; 294 } 295 296 proc.scheduleCrash(message); 297 } 298 299 /** 300 * Bring up the "unexpected error" dialog box for a crashing app. 301 * Deal with edge cases (intercepts from instrumented applications, 302 * ActivityController, error intent receivers, that sort of thing). 303 * @param r the application crashing 304 * @param crashInfo describing the failure 305 */ 306 void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 307 final long origId = Binder.clearCallingIdentity(); 308 try { 309 crashApplicationInner(r, crashInfo); 310 } finally { 311 Binder.restoreCallingIdentity(origId); 312 } 313 } 314 315 void crashApplicationInner(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 316 long timeMillis = System.currentTimeMillis(); 317 String shortMsg = crashInfo.exceptionClassName; 318 String longMsg = crashInfo.exceptionMessage; 319 String stackTrace = crashInfo.stackTrace; 320 if (shortMsg != null && longMsg != null) { 321 longMsg = shortMsg + ": " + longMsg; 322 } else if (shortMsg != null) { 323 longMsg = shortMsg; 324 } 325 326 AppErrorResult result = new AppErrorResult(); 327 TaskRecord task; 328 synchronized (mService) { 329 /** 330 * If crash is handled by instance of {@link android.app.IActivityController}, 331 * finish now and don't show the app error dialog. 332 */ 333 if (handleAppCrashInActivityController(r, crashInfo, shortMsg, longMsg, stackTrace, 334 timeMillis)) { 335 return; 336 } 337 338 /** 339 * If this process was running instrumentation, finish now - it will be handled in 340 * {@link ActivityManagerService#handleAppDiedLocked}. 341 */ 342 if (r != null && r.instrumentationClass != null) { 343 return; 344 } 345 346 // Log crash in battery stats. 347 if (r != null) { 348 mService.mBatteryStatsService.noteProcessCrash(r.processName, r.uid); 349 } 350 351 AppErrorDialog.Data data = new AppErrorDialog.Data(); 352 data.result = result; 353 data.proc = r; 354 355 // If we can't identify the process or it's already exceeded its crash quota, 356 // quit right away without showing a crash dialog. 357 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace, data)) { 358 return; 359 } 360 361 Message msg = Message.obtain(); 362 msg.what = ActivityManagerService.SHOW_ERROR_UI_MSG; 363 364 task = data.task; 365 msg.obj = data; 366 mService.mUiHandler.sendMessage(msg); 367 } 368 369 int res = result.get(); 370 371 Intent appErrorIntent = null; 372 MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_CRASH, res); 373 if (res == AppErrorDialog.TIMEOUT) { 374 res = AppErrorDialog.FORCE_QUIT; 375 } 376 if (res == AppErrorDialog.RESET) { 377 String[] packageList = r.getPackageList(); 378 if (packageList != null) { 379 PackageManager pm = mContext.getPackageManager(); 380 final Semaphore s = new Semaphore(0); 381 for (int i = 0; i < packageList.length; i++) { 382 if (i < packageList.length - 1) { 383 pm.deleteApplicationCacheFiles(packageList[i], null); 384 } else { 385 pm.deleteApplicationCacheFiles(packageList[i], 386 new IPackageDataObserver.Stub() { 387 @Override 388 public void onRemoveCompleted(String packageName, 389 boolean succeeded) { 390 s.release(); 391 } 392 }); 393 394 // Wait until cache has been cleared before we restart. 395 try { 396 s.acquire(); 397 } catch (InterruptedException e) { 398 } 399 } 400 } 401 } 402 // If there was nothing to reset, just restart; 403 res = AppErrorDialog.RESTART; 404 } 405 synchronized (mService) { 406 if (res == AppErrorDialog.MUTE) { 407 stopReportingCrashesLocked(r); 408 } 409 if (res == AppErrorDialog.RESTART) { 410 mService.removeProcessLocked(r, false, true, "crash"); 411 if (task != null) { 412 try { 413 mService.startActivityFromRecents(task.taskId, 414 ActivityOptions.makeBasic().toBundle()); 415 } catch (IllegalArgumentException e) { 416 // Hmm, that didn't work, app might have crashed before creating a 417 // recents entry. Let's see if we have a safe-to-restart intent. 418 if (task.intent.getCategories().contains( 419 Intent.CATEGORY_LAUNCHER)) { 420 mService.startActivityInPackage(task.mCallingUid, 421 task.mCallingPackage, task.intent, 422 null, null, null, 0, 0, 423 ActivityOptions.makeBasic().toBundle(), 424 task.userId, null, null); 425 } 426 } 427 } 428 } 429 if (res == AppErrorDialog.FORCE_QUIT) { 430 long orig = Binder.clearCallingIdentity(); 431 try { 432 // Kill it with fire! 433 mService.mStackSupervisor.handleAppCrashLocked(r); 434 if (!r.persistent) { 435 mService.removeProcessLocked(r, false, false, "crash"); 436 mService.mStackSupervisor.resumeFocusedStackTopActivityLocked(); 437 } 438 } finally { 439 Binder.restoreCallingIdentity(orig); 440 } 441 } 442 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 443 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 444 } 445 if (r != null && !r.isolated && res != AppErrorDialog.RESTART) { 446 // XXX Can't keep track of crash time for isolated processes, 447 // since they don't have a persistent identity. 448 mProcessCrashTimes.put(r.info.processName, r.uid, 449 SystemClock.uptimeMillis()); 450 } 451 } 452 453 if (appErrorIntent != null) { 454 try { 455 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 456 } catch (ActivityNotFoundException e) { 457 Slog.w(TAG, "bug report receiver dissappeared", e); 458 } 459 } 460 } 461 462 private boolean handleAppCrashInActivityController(ProcessRecord r, 463 ApplicationErrorReport.CrashInfo crashInfo, 464 String shortMsg, String longMsg, 465 String stackTrace, long timeMillis) { 466 if (mService.mController == null) { 467 return false; 468 } 469 470 try { 471 String name = r != null ? r.processName : null; 472 int pid = r != null ? r.pid : Binder.getCallingPid(); 473 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 474 if (!mService.mController.appCrashed(name, pid, 475 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 476 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 477 && "Native crash".equals(crashInfo.exceptionClassName)) { 478 Slog.w(TAG, "Skip killing native crashed app " + name 479 + "(" + pid + ") during testing"); 480 } else { 481 Slog.w(TAG, "Force-killing crashed app " + name 482 + " at watcher's request"); 483 if (r != null) { 484 if (!makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace, null)) 485 { 486 r.kill("crash", true); 487 } 488 } else { 489 // Huh. 490 Process.killProcess(pid); 491 ActivityManagerService.killProcessGroup(uid, pid); 492 } 493 } 494 return true; 495 } 496 } catch (RemoteException e) { 497 mService.mController = null; 498 Watchdog.getInstance().setActivityController(null); 499 } 500 return false; 501 } 502 503 private boolean makeAppCrashingLocked(ProcessRecord app, 504 String shortMsg, String longMsg, String stackTrace, AppErrorDialog.Data data) { 505 app.crashing = true; 506 app.crashingReport = generateProcessError(app, 507 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 508 startAppProblemLocked(app); 509 app.stopFreezingAllLocked(); 510 return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace, 511 data); 512 } 513 514 void startAppProblemLocked(ProcessRecord app) { 515 // If this app is not running under the current user, then we 516 // can't give it a report button because that would require 517 // launching the report UI under a different user. 518 app.errorReportReceiver = null; 519 520 for (int userId : mService.mUserController.getCurrentProfileIdsLocked()) { 521 if (app.userId == userId) { 522 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 523 mContext, app.info.packageName, app.info.flags); 524 } 525 } 526 mService.skipCurrentReceiverLocked(app); 527 } 528 529 /** 530 * Generate a process error record, suitable for attachment to a ProcessRecord. 531 * 532 * @param app The ProcessRecord in which the error occurred. 533 * @param condition Crashing, Application Not Responding, etc. Values are defined in 534 * ActivityManager.AppErrorStateInfo 535 * @param activity The activity associated with the crash, if known. 536 * @param shortMsg Short message describing the crash. 537 * @param longMsg Long message describing the crash. 538 * @param stackTrace Full crash stack trace, may be null. 539 * 540 * @return Returns a fully-formed AppErrorStateInfo record. 541 */ 542 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 543 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 544 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 545 546 report.condition = condition; 547 report.processName = app.processName; 548 report.pid = app.pid; 549 report.uid = app.info.uid; 550 report.tag = activity; 551 report.shortMsg = shortMsg; 552 report.longMsg = longMsg; 553 report.stackTrace = stackTrace; 554 555 return report; 556 } 557 558 Intent createAppErrorIntentLocked(ProcessRecord r, 559 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 560 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 561 if (report == null) { 562 return null; 563 } 564 Intent result = new Intent(Intent.ACTION_APP_ERROR); 565 result.setComponent(r.errorReportReceiver); 566 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 567 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 568 return result; 569 } 570 571 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 572 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 573 if (r.errorReportReceiver == null) { 574 return null; 575 } 576 577 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 578 return null; 579 } 580 581 ApplicationErrorReport report = new ApplicationErrorReport(); 582 report.packageName = r.info.packageName; 583 report.installerPackageName = r.errorReportReceiver.getPackageName(); 584 report.processName = r.processName; 585 report.time = timeMillis; 586 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 587 588 if (r.crashing || r.forceCrashReport) { 589 report.type = ApplicationErrorReport.TYPE_CRASH; 590 report.crashInfo = crashInfo; 591 } else if (r.notResponding) { 592 report.type = ApplicationErrorReport.TYPE_ANR; 593 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 594 595 report.anrInfo.activity = r.notRespondingReport.tag; 596 report.anrInfo.cause = r.notRespondingReport.shortMsg; 597 report.anrInfo.info = r.notRespondingReport.longMsg; 598 } 599 600 return report; 601 } 602 603 boolean handleAppCrashLocked(ProcessRecord app, String reason, 604 String shortMsg, String longMsg, String stackTrace, AppErrorDialog.Data data) { 605 long now = SystemClock.uptimeMillis(); 606 607 Long crashTime; 608 Long crashTimePersistent; 609 if (!app.isolated) { 610 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 611 crashTimePersistent = mProcessCrashTimesPersistent.get(app.info.processName, app.uid); 612 } else { 613 crashTime = crashTimePersistent = null; 614 } 615 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 616 // This process loses! 617 Slog.w(TAG, "Process " + app.info.processName 618 + " has crashed too many times: killing!"); 619 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 620 app.userId, app.info.processName, app.uid); 621 mService.mStackSupervisor.handleAppCrashLocked(app); 622 if (!app.persistent) { 623 // We don't want to start this process again until the user 624 // explicitly does so... but for persistent process, we really 625 // need to keep it running. If a persistent process is actually 626 // repeatedly crashing, then badness for everyone. 627 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 628 app.info.processName); 629 if (!app.isolated) { 630 // XXX We don't have a way to mark isolated processes 631 // as bad, since they don't have a peristent identity. 632 mBadProcesses.put(app.info.processName, app.uid, 633 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 634 mProcessCrashTimes.remove(app.info.processName, app.uid); 635 } 636 app.bad = true; 637 app.removed = true; 638 // Don't let services in this process be restarted and potentially 639 // annoy the user repeatedly. Unless it is persistent, since those 640 // processes run critical code. 641 mService.removeProcessLocked(app, false, false, "crash"); 642 mService.mStackSupervisor.resumeFocusedStackTopActivityLocked(); 643 return false; 644 } 645 mService.mStackSupervisor.resumeFocusedStackTopActivityLocked(); 646 } else { 647 TaskRecord affectedTask = 648 mService.mStackSupervisor.finishTopRunningActivityLocked(app, reason); 649 if (data != null) { 650 data.task = affectedTask; 651 } 652 if (data != null && crashTimePersistent != null 653 && now < crashTimePersistent + ProcessList.MIN_CRASH_INTERVAL) { 654 data.repeating = true; 655 } 656 } 657 658 // Bump up the crash count of any services currently running in the proc. 659 for (int i=app.services.size()-1; i>=0; i--) { 660 // Any services running in the application need to be placed 661 // back in the pending list. 662 ServiceRecord sr = app.services.valueAt(i); 663 sr.crashCount++; 664 } 665 666 // If the crashing process is what we consider to be the "home process" and it has been 667 // replaced by a third-party app, clear the package preferred activities from packages 668 // with a home activity running in the process to prevent a repeatedly crashing app 669 // from blocking the user to manually clear the list. 670 final ArrayList<ActivityRecord> activities = app.activities; 671 if (app == mService.mHomeProcess && activities.size() > 0 672 && (mService.mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 673 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 674 final ActivityRecord r = activities.get(activityNdx); 675 if (r.isHomeActivity()) { 676 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 677 try { 678 ActivityThread.getPackageManager() 679 .clearPackagePreferredActivities(r.packageName); 680 } catch (RemoteException c) { 681 // pm is in same process, this will never happen. 682 } 683 } 684 } 685 } 686 687 if (!app.isolated) { 688 // XXX Can't keep track of crash times for isolated processes, 689 // because they don't have a perisistent identity. 690 mProcessCrashTimes.put(app.info.processName, app.uid, now); 691 mProcessCrashTimesPersistent.put(app.info.processName, app.uid, now); 692 } 693 694 if (app.crashHandler != null) mService.mHandler.post(app.crashHandler); 695 return true; 696 } 697 698 void handleShowAppErrorUi(Message msg) { 699 AppErrorDialog.Data data = (AppErrorDialog.Data) msg.obj; 700 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 701 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 702 synchronized (mService) { 703 ProcessRecord proc = data.proc; 704 AppErrorResult res = data.result; 705 if (proc != null && proc.crashDialog != null) { 706 Slog.e(TAG, "App already has crash dialog: " + proc); 707 if (res != null) { 708 res.set(AppErrorDialog.ALREADY_SHOWING); 709 } 710 return; 711 } 712 boolean isBackground = (UserHandle.getAppId(proc.uid) 713 >= Process.FIRST_APPLICATION_UID 714 && proc.pid != MY_PID); 715 for (int userId : mService.mUserController.getCurrentProfileIdsLocked()) { 716 isBackground &= (proc.userId != userId); 717 } 718 if (isBackground && !showBackground) { 719 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 720 if (res != null) { 721 res.set(AppErrorDialog.BACKGROUND_USER); 722 } 723 return; 724 } 725 final boolean crashSilenced = mAppsNotReportingCrashes != null && 726 mAppsNotReportingCrashes.contains(proc.info.packageName); 727 if (mService.canShowErrorDialogs() && !crashSilenced) { 728 proc.crashDialog = new AppErrorDialog(mContext, mService, data); 729 } else { 730 // The device is asleep, so just pretend that the user 731 // saw a crash dialog and hit "force quit". 732 if (res != null) { 733 res.set(AppErrorDialog.CANT_SHOW); 734 } 735 } 736 } 737 // If we've created a crash dialog, show it without the lock held 738 if(data.proc.crashDialog != null) { 739 data.proc.crashDialog.show(); 740 } 741 } 742 743 void stopReportingCrashesLocked(ProcessRecord proc) { 744 if (mAppsNotReportingCrashes == null) { 745 mAppsNotReportingCrashes = new ArraySet<>(); 746 } 747 mAppsNotReportingCrashes.add(proc.info.packageName); 748 } 749 750 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 751 ActivityRecord parent, boolean aboveSystem, final String annotation) { 752 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 753 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 754 755 if (mService.mController != null) { 756 try { 757 // 0 == continue, -1 = kill process immediately 758 int res = mService.mController.appEarlyNotResponding( 759 app.processName, app.pid, annotation); 760 if (res < 0 && app.pid != MY_PID) { 761 app.kill("anr", true); 762 } 763 } catch (RemoteException e) { 764 mService.mController = null; 765 Watchdog.getInstance().setActivityController(null); 766 } 767 } 768 769 long anrTime = SystemClock.uptimeMillis(); 770 if (ActivityManagerService.MONITOR_CPU_USAGE) { 771 mService.updateCpuStatsNow(); 772 } 773 774 synchronized (mService) { 775 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 776 if (mService.mShuttingDown) { 777 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 778 return; 779 } else if (app.notResponding) { 780 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 781 return; 782 } else if (app.crashing) { 783 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 784 return; 785 } 786 787 // In case we come through here for the same app before completing 788 // this one, mark as anring now so we will bail out. 789 app.notResponding = true; 790 791 // Log the ANR to the event log. 792 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 793 app.processName, app.info.flags, annotation); 794 795 // Dump thread traces as quickly as we can, starting with "interesting" processes. 796 firstPids.add(app.pid); 797 798 int parentPid = app.pid; 799 if (parent != null && parent.app != null && parent.app.pid > 0) { 800 parentPid = parent.app.pid; 801 } 802 if (parentPid != app.pid) firstPids.add(parentPid); 803 804 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 805 806 for (int i = mService.mLruProcesses.size() - 1; i >= 0; i--) { 807 ProcessRecord r = mService.mLruProcesses.get(i); 808 if (r != null && r.thread != null) { 809 int pid = r.pid; 810 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 811 if (r.persistent) { 812 firstPids.add(pid); 813 if (DEBUG_ANR) Slog.i(TAG, "Adding persistent proc: " + r); 814 } else { 815 lastPids.put(pid, Boolean.TRUE); 816 if (DEBUG_ANR) Slog.i(TAG, "Adding ANR proc: " + r); 817 } 818 } 819 } 820 } 821 } 822 823 // Log the ANR to the main log. 824 StringBuilder info = new StringBuilder(); 825 info.setLength(0); 826 info.append("ANR in ").append(app.processName); 827 if (activity != null && activity.shortComponentName != null) { 828 info.append(" (").append(activity.shortComponentName).append(")"); 829 } 830 info.append("\n"); 831 info.append("PID: ").append(app.pid).append("\n"); 832 if (annotation != null) { 833 info.append("Reason: ").append(annotation).append("\n"); 834 } 835 if (parent != null && parent != activity) { 836 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 837 } 838 839 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 840 841 File tracesFile = mService.dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 842 NATIVE_STACKS_OF_INTEREST); 843 844 String cpuInfo = null; 845 if (ActivityManagerService.MONITOR_CPU_USAGE) { 846 mService.updateCpuStatsNow(); 847 synchronized (mService.mProcessCpuTracker) { 848 cpuInfo = mService.mProcessCpuTracker.printCurrentState(anrTime); 849 } 850 info.append(processCpuTracker.printCurrentLoad()); 851 info.append(cpuInfo); 852 } 853 854 info.append(processCpuTracker.printCurrentState(anrTime)); 855 856 Slog.e(TAG, info.toString()); 857 if (tracesFile == null) { 858 // There is no trace file, so dump (only) the alleged culprit's threads to the log 859 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 860 } 861 862 mService.addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 863 cpuInfo, tracesFile, null); 864 865 if (mService.mController != null) { 866 try { 867 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 868 int res = mService.mController.appNotResponding( 869 app.processName, app.pid, info.toString()); 870 if (res != 0) { 871 if (res < 0 && app.pid != MY_PID) { 872 app.kill("anr", true); 873 } else { 874 synchronized (mService) { 875 mService.mServices.scheduleServiceTimeoutLocked(app); 876 } 877 } 878 return; 879 } 880 } catch (RemoteException e) { 881 mService.mController = null; 882 Watchdog.getInstance().setActivityController(null); 883 } 884 } 885 886 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 887 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 888 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 889 890 synchronized (mService) { 891 mService.mBatteryStatsService.noteProcessAnr(app.processName, app.uid); 892 893 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 894 app.kill("bg anr", true); 895 return; 896 } 897 898 // Set the app's notResponding state, and look up the errorReportReceiver 899 makeAppNotRespondingLocked(app, 900 activity != null ? activity.shortComponentName : null, 901 annotation != null ? "ANR " + annotation : "ANR", 902 info.toString()); 903 904 // Bring up the infamous App Not Responding dialog 905 Message msg = Message.obtain(); 906 HashMap<String, Object> map = new HashMap<String, Object>(); 907 msg.what = ActivityManagerService.SHOW_NOT_RESPONDING_UI_MSG; 908 msg.obj = map; 909 msg.arg1 = aboveSystem ? 1 : 0; 910 map.put("app", app); 911 if (activity != null) { 912 map.put("activity", activity); 913 } 914 915 mService.mUiHandler.sendMessage(msg); 916 } 917 } 918 919 private void makeAppNotRespondingLocked(ProcessRecord app, 920 String activity, String shortMsg, String longMsg) { 921 app.notResponding = true; 922 app.notRespondingReport = generateProcessError(app, 923 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 924 activity, shortMsg, longMsg, null); 925 startAppProblemLocked(app); 926 app.stopFreezingAllLocked(); 927 } 928 929 void handleShowAnrUi(Message msg) { 930 Dialog d = null; 931 synchronized (mService) { 932 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 933 ProcessRecord proc = (ProcessRecord)data.get("app"); 934 if (proc != null && proc.anrDialog != null) { 935 Slog.e(TAG, "App already has anr dialog: " + proc); 936 MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_ANR, 937 AppNotRespondingDialog.ALREADY_SHOWING); 938 return; 939 } 940 941 Intent intent = new Intent("android.intent.action.ANR"); 942 if (!mService.mProcessesReady) { 943 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 944 | Intent.FLAG_RECEIVER_FOREGROUND); 945 } 946 mService.broadcastIntentLocked(null, null, intent, 947 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 948 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 949 950 if (mService.canShowErrorDialogs()) { 951 d = new AppNotRespondingDialog(mService, 952 mContext, proc, (ActivityRecord)data.get("activity"), 953 msg.arg1 != 0); 954 proc.anrDialog = d; 955 } else { 956 MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_ANR, 957 AppNotRespondingDialog.CANT_SHOW); 958 // Just kill the app if there is no dialog to be shown. 959 mService.killAppAtUsersRequest(proc, null); 960 } 961 } 962 // If we've created a crash dialog, show it without the lock held 963 if (d != null) { 964 d.show(); 965 } 966 } 967 968 /** 969 * Information about a process that is currently marked as bad. 970 */ 971 static final class BadProcessInfo { 972 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 973 this.time = time; 974 this.shortMsg = shortMsg; 975 this.longMsg = longMsg; 976 this.stack = stack; 977 } 978 979 final long time; 980 final String shortMsg; 981 final String longMsg; 982 final String stack; 983 } 984 985} 986