OSDN Git Service

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