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 17 package com.android.server.am; 18 19 import com.android.internal.app.ProcessMap; 20 import com.android.internal.logging.MetricsLogger; 21 import com.android.internal.logging.MetricsProto; 22 import com.android.internal.os.ProcessCpuTracker; 23 import com.android.server.Watchdog; 24 25 import android.app.Activity; 26 import android.app.ActivityManager; 27 import android.app.ActivityOptions; 28 import android.app.ActivityThread; 29 import android.app.AppOpsManager; 30 import android.app.ApplicationErrorReport; 31 import android.app.Dialog; 32 import android.content.ActivityNotFoundException; 33 import android.content.Context; 34 import android.content.Intent; 35 import android.content.pm.ApplicationInfo; 36 import android.content.pm.IPackageDataObserver; 37 import android.content.pm.PackageManager; 38 import android.os.Binder; 39 import android.os.Bundle; 40 import android.os.Message; 41 import android.os.Process; 42 import android.os.RemoteException; 43 import android.os.SystemClock; 44 import android.os.SystemProperties; 45 import android.os.UserHandle; 46 import android.provider.Settings; 47 import android.util.ArrayMap; 48 import android.util.ArraySet; 49 import android.util.EventLog; 50 import android.util.Log; 51 import android.util.Slog; 52 import android.util.SparseArray; 53 import android.util.TimeUtils; 54 55 import java.io.File; 56 import java.io.FileDescriptor; 57 import java.io.PrintWriter; 58 import java.util.ArrayList; 59 import java.util.Collections; 60 import java.util.HashMap; 61 import java.util.concurrent.Semaphore; 62 63 import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 64 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR; 65 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; 66 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; 67 import static com.android.server.am.ActivityManagerService.MY_PID; 68 import static com.android.server.am.ActivityManagerService.SYSTEM_DEBUGGABLE; 69 70 /** 71 * Controls error conditions in applications. 72 */ 73 class 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 || res == AppErrorDialog.CANCEL) { 374 res = AppErrorDialog.FORCE_QUIT; 375 } 376 synchronized (mService) { 377 if (res == AppErrorDialog.MUTE) { 378 stopReportingCrashesLocked(r); 379 } 380 if (res == AppErrorDialog.RESTART) { 381 mService.removeProcessLocked(r, false, true, "crash"); 382 if (task != null) { 383 try { 384 mService.startActivityFromRecents(task.taskId, 385 ActivityOptions.makeBasic().toBundle()); 386 } catch (IllegalArgumentException e) { 387 // Hmm, that didn't work, app might have crashed before creating a 388 // recents entry. Let's see if we have a safe-to-restart intent. 389 if (task.intent.getCategories().contains( 390 Intent.CATEGORY_LAUNCHER)) { 391 mService.startActivityInPackage(task.mCallingUid, 392 task.mCallingPackage, task.intent, 393 null, null, null, 0, 0, 394 ActivityOptions.makeBasic().toBundle(), 395 task.userId, null, null); 396 } 397 } 398 } 399 } 400 if (res == AppErrorDialog.FORCE_QUIT) { 401 long orig = Binder.clearCallingIdentity(); 402 try { 403 // Kill it with fire! 404 mService.mStackSupervisor.handleAppCrashLocked(r); 405 if (!r.persistent) { 406 mService.removeProcessLocked(r, false, false, "crash"); 407 mService.mStackSupervisor.resumeFocusedStackTopActivityLocked(); 408 } 409 } finally { 410 Binder.restoreCallingIdentity(orig); 411 } 412 } 413 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 414 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 415 } 416 if (r != null && !r.isolated && res != AppErrorDialog.RESTART) { 417 // XXX Can't keep track of crash time for isolated processes, 418 // since they don't have a persistent identity. 419 mProcessCrashTimes.put(r.info.processName, r.uid, 420 SystemClock.uptimeMillis()); 421 } 422 } 423 424 if (appErrorIntent != null) { 425 try { 426 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 427 } catch (ActivityNotFoundException e) { 428 Slog.w(TAG, "bug report receiver dissappeared", e); 429 } 430 } 431 } 432 433 private boolean handleAppCrashInActivityController(ProcessRecord r, 434 ApplicationErrorReport.CrashInfo crashInfo, 435 String shortMsg, String longMsg, 436 String stackTrace, long timeMillis) { 437 if (mService.mController == null) { 438 return false; 439 } 440 441 try { 442 String name = r != null ? r.processName : null; 443 int pid = r != null ? r.pid : Binder.getCallingPid(); 444 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 445 if (!mService.mController.appCrashed(name, pid, 446 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 447 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 448 && "Native crash".equals(crashInfo.exceptionClassName)) { 449 Slog.w(TAG, "Skip killing native crashed app " + name 450 + "(" + pid + ") during testing"); 451 } else { 452 Slog.w(TAG, "Force-killing crashed app " + name 453 + " at watcher's request"); 454 if (r != null) { 455 if (!makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace, null)) 456 { 457 r.kill("crash", true); 458 } 459 } else { 460 // Huh. 461 Process.killProcess(pid); 462 ActivityManagerService.killProcessGroup(uid, pid); 463 } 464 } 465 return true; 466 } 467 } catch (RemoteException e) { 468 mService.mController = null; 469 Watchdog.getInstance().setActivityController(null); 470 } 471 return false; 472 } 473 474 private boolean makeAppCrashingLocked(ProcessRecord app, 475 String shortMsg, String longMsg, String stackTrace, AppErrorDialog.Data data) { 476 app.crashing = true; 477 app.crashingReport = generateProcessError(app, 478 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 479 startAppProblemLocked(app); 480 app.stopFreezingAllLocked(); 481 return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace, 482 data); 483 } 484 485 void startAppProblemLocked(ProcessRecord app) { 486 // If this app is not running under the current user, then we 487 // can't give it a report button because that would require 488 // launching the report UI under a different user. 489 app.errorReportReceiver = null; 490 491 for (int userId : mService.mUserController.getCurrentProfileIdsLocked()) { 492 if (app.userId == userId) { 493 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 494 mContext, app.info.packageName, app.info.flags); 495 } 496 } 497 mService.skipCurrentReceiverLocked(app); 498 } 499 500 /** 501 * Generate a process error record, suitable for attachment to a ProcessRecord. 502 * 503 * @param app The ProcessRecord in which the error occurred. 504 * @param condition Crashing, Application Not Responding, etc. Values are defined in 505 * ActivityManager.AppErrorStateInfo 506 * @param activity The activity associated with the crash, if known. 507 * @param shortMsg Short message describing the crash. 508 * @param longMsg Long message describing the crash. 509 * @param stackTrace Full crash stack trace, may be null. 510 * 511 * @return Returns a fully-formed AppErrorStateInfo record. 512 */ 513 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 514 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 515 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 516 517 report.condition = condition; 518 report.processName = app.processName; 519 report.pid = app.pid; 520 report.uid = app.info.uid; 521 report.tag = activity; 522 report.shortMsg = shortMsg; 523 report.longMsg = longMsg; 524 report.stackTrace = stackTrace; 525 526 return report; 527 } 528 529 Intent createAppErrorIntentLocked(ProcessRecord r, 530 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 531 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 532 if (report == null) { 533 return null; 534 } 535 Intent result = new Intent(Intent.ACTION_APP_ERROR); 536 result.setComponent(r.errorReportReceiver); 537 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 538 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 539 return result; 540 } 541 542 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 543 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 544 if (r.errorReportReceiver == null) { 545 return null; 546 } 547 548 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 549 return null; 550 } 551 552 ApplicationErrorReport report = new ApplicationErrorReport(); 553 report.packageName = r.info.packageName; 554 report.installerPackageName = r.errorReportReceiver.getPackageName(); 555 report.processName = r.processName; 556 report.time = timeMillis; 557 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 558 559 if (r.crashing || r.forceCrashReport) { 560 report.type = ApplicationErrorReport.TYPE_CRASH; 561 report.crashInfo = crashInfo; 562 } else if (r.notResponding) { 563 report.type = ApplicationErrorReport.TYPE_ANR; 564 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 565 566 report.anrInfo.activity = r.notRespondingReport.tag; 567 report.anrInfo.cause = r.notRespondingReport.shortMsg; 568 report.anrInfo.info = r.notRespondingReport.longMsg; 569 } 570 571 return report; 572 } 573 574 boolean handleAppCrashLocked(ProcessRecord app, String reason, 575 String shortMsg, String longMsg, String stackTrace, AppErrorDialog.Data data) { 576 long now = SystemClock.uptimeMillis(); 577 578 Long crashTime; 579 Long crashTimePersistent; 580 if (!app.isolated) { 581 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 582 crashTimePersistent = mProcessCrashTimesPersistent.get(app.info.processName, app.uid); 583 } else { 584 crashTime = crashTimePersistent = null; 585 } 586 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 587 // This process loses! 588 Slog.w(TAG, "Process " + app.info.processName 589 + " has crashed too many times: killing!"); 590 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 591 app.userId, app.info.processName, app.uid); 592 mService.mStackSupervisor.handleAppCrashLocked(app); 593 if (!app.persistent) { 594 // We don't want to start this process again until the user 595 // explicitly does so... but for persistent process, we really 596 // need to keep it running. If a persistent process is actually 597 // repeatedly crashing, then badness for everyone. 598 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 599 app.info.processName); 600 if (!app.isolated) { 601 // XXX We don't have a way to mark isolated processes 602 // as bad, since they don't have a peristent identity. 603 mBadProcesses.put(app.info.processName, app.uid, 604 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 605 mProcessCrashTimes.remove(app.info.processName, app.uid); 606 } 607 app.bad = true; 608 app.removed = true; 609 // Don't let services in this process be restarted and potentially 610 // annoy the user repeatedly. Unless it is persistent, since those 611 // processes run critical code. 612 mService.removeProcessLocked(app, false, false, "crash"); 613 mService.mStackSupervisor.resumeFocusedStackTopActivityLocked(); 614 return false; 615 } 616 mService.mStackSupervisor.resumeFocusedStackTopActivityLocked(); 617 } else { 618 TaskRecord affectedTask = 619 mService.mStackSupervisor.finishTopRunningActivityLocked(app, reason); 620 if (data != null) { 621 data.task = affectedTask; 622 } 623 if (data != null && crashTimePersistent != null 624 && now < crashTimePersistent + ProcessList.MIN_CRASH_INTERVAL) { 625 data.repeating = true; 626 } 627 } 628 629 // Bump up the crash count of any services currently running in the proc. 630 for (int i=app.services.size()-1; i>=0; i--) { 631 // Any services running in the application need to be placed 632 // back in the pending list. 633 ServiceRecord sr = app.services.valueAt(i); 634 sr.crashCount++; 635 } 636 637 // If the crashing process is what we consider to be the "home process" and it has been 638 // replaced by a third-party app, clear the package preferred activities from packages 639 // with a home activity running in the process to prevent a repeatedly crashing app 640 // from blocking the user to manually clear the list. 641 final ArrayList<ActivityRecord> activities = app.activities; 642 if (app == mService.mHomeProcess && activities.size() > 0 643 && (mService.mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 644 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 645 final ActivityRecord r = activities.get(activityNdx); 646 if (r.isHomeActivity()) { 647 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 648 try { 649 ActivityThread.getPackageManager() 650 .clearPackagePreferredActivities(r.packageName); 651 } catch (RemoteException c) { 652 // pm is in same process, this will never happen. 653 } 654 } 655 } 656 } 657 658 if (!app.isolated) { 659 // XXX Can't keep track of crash times for isolated processes, 660 // because they don't have a perisistent identity. 661 mProcessCrashTimes.put(app.info.processName, app.uid, now); 662 mProcessCrashTimesPersistent.put(app.info.processName, app.uid, now); 663 } 664 665 if (app.crashHandler != null) mService.mHandler.post(app.crashHandler); 666 return true; 667 } 668 669 void handleShowAppErrorUi(Message msg) { 670 AppErrorDialog.Data data = (AppErrorDialog.Data) msg.obj; 671 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 672 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 673 synchronized (mService) { 674 ProcessRecord proc = data.proc; 675 AppErrorResult res = data.result; 676 if (proc != null && proc.crashDialog != null) { 677 Slog.e(TAG, "App already has crash dialog: " + proc); 678 if (res != null) { 679 res.set(AppErrorDialog.ALREADY_SHOWING); 680 } 681 return; 682 } 683 boolean isBackground = (UserHandle.getAppId(proc.uid) 684 >= Process.FIRST_APPLICATION_UID 685 && proc.pid != MY_PID); 686 for (int userId : mService.mUserController.getCurrentProfileIdsLocked()) { 687 isBackground &= (proc.userId != userId); 688 } 689 if (isBackground && !showBackground) { 690 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 691 if (res != null) { 692 res.set(AppErrorDialog.BACKGROUND_USER); 693 } 694 return; 695 } 696 final boolean crashSilenced = mAppsNotReportingCrashes != null && 697 mAppsNotReportingCrashes.contains(proc.info.packageName); 698 if (mService.canShowErrorDialogs() && !crashSilenced) { 699 proc.crashDialog = new AppErrorDialog(mContext, mService, data); 700 } else { 701 // The device is asleep, so just pretend that the user 702 // saw a crash dialog and hit "force quit". 703 if (res != null) { 704 res.set(AppErrorDialog.CANT_SHOW); 705 } 706 } 707 } 708 // If we've created a crash dialog, show it without the lock held 709 if(data.proc.crashDialog != null) { 710 data.proc.crashDialog.show(); 711 } 712 } 713 714 void stopReportingCrashesLocked(ProcessRecord proc) { 715 if (mAppsNotReportingCrashes == null) { 716 mAppsNotReportingCrashes = new ArraySet<>(); 717 } 718 mAppsNotReportingCrashes.add(proc.info.packageName); 719 } 720 721 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 722 ActivityRecord parent, boolean aboveSystem, final String annotation) { 723 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 724 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 725 726 if (mService.mController != null) { 727 try { 728 // 0 == continue, -1 = kill process immediately 729 int res = mService.mController.appEarlyNotResponding( 730 app.processName, app.pid, annotation); 731 if (res < 0 && app.pid != MY_PID) { 732 app.kill("anr", true); 733 } 734 } catch (RemoteException e) { 735 mService.mController = null; 736 Watchdog.getInstance().setActivityController(null); 737 } 738 } 739 740 long anrTime = SystemClock.uptimeMillis(); 741 if (ActivityManagerService.MONITOR_CPU_USAGE) { 742 mService.updateCpuStatsNow(); 743 } 744 745 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 746 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 747 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 748 749 boolean isSilentANR; 750 751 synchronized (mService) { 752 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 753 if (mService.mShuttingDown) { 754 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 755 return; 756 } else if (app.notResponding) { 757 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 758 return; 759 } else if (app.crashing) { 760 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 761 return; 762 } 763 764 // In case we come through here for the same app before completing 765 // this one, mark as anring now so we will bail out. 766 app.notResponding = true; 767 768 // Log the ANR to the event log. 769 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 770 app.processName, app.info.flags, annotation); 771 772 // Dump thread traces as quickly as we can, starting with "interesting" processes. 773 firstPids.add(app.pid); 774 775 // Don't dump other PIDs if it's a background ANR 776 isSilentANR = !showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID; 777 if (!isSilentANR) { 778 int parentPid = app.pid; 779 if (parent != null && parent.app != null && parent.app.pid > 0) { 780 parentPid = parent.app.pid; 781 } 782 if (parentPid != app.pid) firstPids.add(parentPid); 783 784 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 785 786 for (int i = mService.mLruProcesses.size() - 1; i >= 0; i--) { 787 ProcessRecord r = mService.mLruProcesses.get(i); 788 if (r != null && r.thread != null) { 789 int pid = r.pid; 790 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 791 if (r.persistent) { 792 firstPids.add(pid); 793 if (DEBUG_ANR) Slog.i(TAG, "Adding persistent proc: " + r); 794 } else { 795 lastPids.put(pid, Boolean.TRUE); 796 if (DEBUG_ANR) Slog.i(TAG, "Adding ANR proc: " + r); 797 } 798 } 799 } 800 } 801 } 802 } 803 804 // Log the ANR to the main log. 805 StringBuilder info = new StringBuilder(); 806 info.setLength(0); 807 info.append("ANR in ").append(app.processName); 808 if (activity != null && activity.shortComponentName != null) { 809 info.append(" (").append(activity.shortComponentName).append(")"); 810 } 811 info.append("\n"); 812 info.append("PID: ").append(app.pid).append("\n"); 813 if (annotation != null) { 814 info.append("Reason: ").append(annotation).append("\n"); 815 } 816 if (parent != null && parent != activity) { 817 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 818 } 819 820 ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 821 822 String[] nativeProcs = NATIVE_STACKS_OF_INTEREST; 823 // don't dump native PIDs for background ANRs 824 File tracesFile = null; 825 if (isSilentANR) { 826 tracesFile = mService.dumpStackTraces(true, firstPids, null, lastPids, 827 null); 828 } else { 829 tracesFile = mService.dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 830 nativeProcs); 831 } 832 833 String cpuInfo = null; 834 if (ActivityManagerService.MONITOR_CPU_USAGE) { 835 mService.updateCpuStatsNow(); 836 synchronized (mService.mProcessCpuTracker) { 837 cpuInfo = mService.mProcessCpuTracker.printCurrentState(anrTime); 838 } 839 info.append(processCpuTracker.printCurrentLoad()); 840 info.append(cpuInfo); 841 } 842 843 info.append(processCpuTracker.printCurrentState(anrTime)); 844 845 Slog.e(TAG, info.toString()); 846 if (tracesFile == null) { 847 // There is no trace file, so dump (only) the alleged culprit's threads to the log 848 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 849 } 850 851 mService.addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 852 cpuInfo, tracesFile, null); 853 854 if (mService.mController != null) { 855 try { 856 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 857 int res = mService.mController.appNotResponding( 858 app.processName, app.pid, info.toString()); 859 if (res != 0) { 860 if (res < 0 && app.pid != MY_PID) { 861 app.kill("anr", true); 862 } else { 863 synchronized (mService) { 864 mService.mServices.scheduleServiceTimeoutLocked(app); 865 } 866 } 867 return; 868 } 869 } catch (RemoteException e) { 870 mService.mController = null; 871 Watchdog.getInstance().setActivityController(null); 872 } 873 } 874 875 synchronized (mService) { 876 mService.mBatteryStatsService.noteProcessAnr(app.processName, app.uid); 877 878 if (isSilentANR) { 879 app.kill("bg anr", true); 880 return; 881 } 882 883 // Set the app's notResponding state, and look up the errorReportReceiver 884 makeAppNotRespondingLocked(app, 885 activity != null ? activity.shortComponentName : null, 886 annotation != null ? "ANR " + annotation : "ANR", 887 info.toString()); 888 889 // Bring up the infamous App Not Responding dialog 890 Message msg = Message.obtain(); 891 HashMap<String, Object> map = new HashMap<String, Object>(); 892 msg.what = ActivityManagerService.SHOW_NOT_RESPONDING_UI_MSG; 893 msg.obj = map; 894 msg.arg1 = aboveSystem ? 1 : 0; 895 map.put("app", app); 896 if (activity != null) { 897 map.put("activity", activity); 898 } 899 900 mService.mUiHandler.sendMessage(msg); 901 } 902 } 903 904 private void makeAppNotRespondingLocked(ProcessRecord app, 905 String activity, String shortMsg, String longMsg) { 906 app.notResponding = true; 907 app.notRespondingReport = generateProcessError(app, 908 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 909 activity, shortMsg, longMsg, null); 910 startAppProblemLocked(app); 911 app.stopFreezingAllLocked(); 912 } 913 914 void handleShowAnrUi(Message msg) { 915 Dialog d = null; 916 synchronized (mService) { 917 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 918 ProcessRecord proc = (ProcessRecord)data.get("app"); 919 if (proc != null && proc.anrDialog != null) { 920 Slog.e(TAG, "App already has anr dialog: " + proc); 921 MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_ANR, 922 AppNotRespondingDialog.ALREADY_SHOWING); 923 return; 924 } 925 926 Intent intent = new Intent("android.intent.action.ANR"); 927 if (!mService.mProcessesReady) { 928 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 929 | Intent.FLAG_RECEIVER_FOREGROUND); 930 } 931 mService.broadcastIntentLocked(null, null, intent, 932 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 933 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 934 935 if (mService.canShowErrorDialogs()) { 936 d = new AppNotRespondingDialog(mService, 937 mContext, proc, (ActivityRecord)data.get("activity"), 938 msg.arg1 != 0); 939 proc.anrDialog = d; 940 } else { 941 MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_ANR, 942 AppNotRespondingDialog.CANT_SHOW); 943 // Just kill the app if there is no dialog to be shown. 944 mService.killAppAtUsersRequest(proc, null); 945 } 946 } 947 // If we've created a crash dialog, show it without the lock held 948 if (d != null) { 949 d.show(); 950 } 951 } 952 953 /** 954 * Information about a process that is currently marked as bad. 955 */ 956 static final class BadProcessInfo { 957 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 958 this.time = time; 959 this.shortMsg = shortMsg; 960 this.longMsg = longMsg; 961 this.stack = stack; 962 } 963 964 final long time; 965 final String shortMsg; 966 final String longMsg; 967 final String stack; 968 } 969 970 } 971