blob: c7d93be893fc01ce80233c768b61c0e03370390e [file] [log] [blame]
Adrian Roos20d7df32016-01-12 18:59:43 +01001/*
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;
Adrian Roos90462222016-02-17 15:45:09 -080020import com.android.internal.logging.MetricsLogger;
Tamas Berghammer383db5eb2016-06-22 15:21:38 +010021import com.android.internal.logging.nano.MetricsProto;
Adrian Roos20d7df32016-01-12 18:59:43 +010022import com.android.internal.os.ProcessCpuTracker;
Jeff Sharkeyfe6f85c2017-01-20 10:42:57 -070023import com.android.server.RescueParty;
Adrian Roos20d7df32016-01-12 18:59:43 +010024import com.android.server.Watchdog;
Yi Jin148d7f42017-11-28 14:23:56 -080025import com.android.server.am.proto.AppErrorsProto;
Adrian Roos20d7df32016-01-12 18:59:43 +010026
Adrian Roos20d7df32016-01-12 18:59:43 +010027import android.app.ActivityManager;
28import android.app.ActivityOptions;
29import android.app.ActivityThread;
30import android.app.AppOpsManager;
31import android.app.ApplicationErrorReport;
32import android.app.Dialog;
33import android.content.ActivityNotFoundException;
34import android.content.Context;
35import android.content.Intent;
36import android.content.pm.ApplicationInfo;
Adrian Roos20d7df32016-01-12 18:59:43 +010037import android.os.Binder;
Adrian Roos20d7df32016-01-12 18:59:43 +010038import android.os.Message;
39import android.os.Process;
40import android.os.RemoteException;
41import android.os.SystemClock;
42import android.os.SystemProperties;
43import android.os.UserHandle;
44import android.provider.Settings;
45import android.util.ArrayMap;
46import android.util.ArraySet;
47import android.util.EventLog;
48import android.util.Log;
49import android.util.Slog;
50import android.util.SparseArray;
51import android.util.TimeUtils;
Yi Jin148d7f42017-11-28 14:23:56 -080052import android.util.proto.ProtoOutputStream;
Adrian Roos20d7df32016-01-12 18:59:43 +010053
54import java.io.File;
55import java.io.FileDescriptor;
56import java.io.PrintWriter;
57import java.util.ArrayList;
58import java.util.Collections;
59import java.util.HashMap;
Dianne Hackborn4d895942016-07-12 13:36:02 -070060import java.util.Set;
Adrian Roos20d7df32016-01-12 18:59:43 +010061
62import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
Dianne Hackborn9369efd2016-03-02 15:49:58 -080063import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
Adrian Roos20d7df32016-01-12 18:59:43 +010064import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
65import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
66import static com.android.server.am.ActivityManagerService.MY_PID;
67import static com.android.server.am.ActivityManagerService.SYSTEM_DEBUGGABLE;
68
69/**
70 * Controls error conditions in applications.
71 */
72class AppErrors {
73
74 private static final String TAG = TAG_WITH_CLASS_NAME ? "AppErrors" : TAG_AM;
75
76 private final ActivityManagerService mService;
77 private final Context mContext;
78
79 private ArraySet<String> mAppsNotReportingCrashes;
80
81 /**
82 * The last time that various processes have crashed since they were last explicitly started.
83 */
84 private final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<>();
85
86 /**
87 * The last time that various processes have crashed (not reset even when explicitly started).
88 */
89 private final ProcessMap<Long> mProcessCrashTimesPersistent = new ProcessMap<>();
90
91 /**
92 * Set of applications that we consider to be bad, and will reject
93 * incoming broadcasts from (which the user has no control over).
94 * Processes are added to this set when they have crashed twice within
95 * a minimum amount of time; they are removed from it when they are
96 * later restarted (hopefully due to some user action). The value is the
97 * time it was added to the list.
98 */
99 private final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<>();
100
101
102 AppErrors(Context context, ActivityManagerService service) {
Adam Lesinskia82b6262017-03-21 16:56:17 -0700103 context.assertRuntimeOverlayThemable();
Adrian Roos20d7df32016-01-12 18:59:43 +0100104 mService = service;
105 mContext = context;
106 }
107
Yi Jin148d7f42017-11-28 14:23:56 -0800108 void writeToProto(ProtoOutputStream proto, long fieldId, String dumpPackage) {
109 if (mProcessCrashTimes.getMap().isEmpty() && mBadProcesses.getMap().isEmpty()) {
110 return;
111 }
112
113 final long token = proto.start(fieldId);
114 final long now = SystemClock.uptimeMillis();
115 proto.write(AppErrorsProto.NOW_UPTIME_MS, now);
116
117 if (!mProcessCrashTimes.getMap().isEmpty()) {
118 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
119 final int procCount = pmap.size();
120 for (int ip = 0; ip < procCount; ip++) {
121 final long ctoken = proto.start(AppErrorsProto.PROCESS_CRASH_TIMES);
122 final String pname = pmap.keyAt(ip);
123 final SparseArray<Long> uids = pmap.valueAt(ip);
124 final int uidCount = uids.size();
125
126 proto.write(AppErrorsProto.ProcessCrashTime.PROCESS_NAME, pname);
127 for (int i = 0; i < uidCount; i++) {
128 final int puid = uids.keyAt(i);
129 final ProcessRecord r = mService.mProcessNames.get(pname, puid);
130 if (dumpPackage != null && (r == null || !r.pkgList.containsKey(dumpPackage))) {
131 continue;
132 }
133 final long etoken = proto.start(AppErrorsProto.ProcessCrashTime.ENTRIES);
134 proto.write(AppErrorsProto.ProcessCrashTime.Entry.UID, puid);
135 proto.write(AppErrorsProto.ProcessCrashTime.Entry.LAST_CRASHED_AT_MS,
136 uids.valueAt(i));
137 proto.end(etoken);
138 }
139 proto.end(ctoken);
140 }
141
142 }
143
144 if (!mBadProcesses.getMap().isEmpty()) {
145 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
146 final int processCount = pmap.size();
147 for (int ip = 0; ip < processCount; ip++) {
148 final long btoken = proto.start(AppErrorsProto.BAD_PROCESSES);
149 final String pname = pmap.keyAt(ip);
150 final SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
151 final int uidCount = uids.size();
152
153 proto.write(AppErrorsProto.BadProcess.PROCESS_NAME, pname);
154 for (int i = 0; i < uidCount; i++) {
155 final int puid = uids.keyAt(i);
156 final ProcessRecord r = mService.mProcessNames.get(pname, puid);
157 if (dumpPackage != null && (r == null
158 || !r.pkgList.containsKey(dumpPackage))) {
159 continue;
160 }
161 final BadProcessInfo info = uids.valueAt(i);
162 final long etoken = proto.start(AppErrorsProto.BadProcess.ENTRIES);
163 proto.write(AppErrorsProto.BadProcess.Entry.UID, puid);
164 proto.write(AppErrorsProto.BadProcess.Entry.CRASHED_AT_MS, info.time);
165 proto.write(AppErrorsProto.BadProcess.Entry.SHORT_MSG, info.shortMsg);
166 proto.write(AppErrorsProto.BadProcess.Entry.LONG_MSG, info.longMsg);
167 proto.write(AppErrorsProto.BadProcess.Entry.STACK, info.stack);
168 proto.end(etoken);
169 }
170 proto.end(btoken);
171 }
172 }
173
174 proto.end(token);
175 }
176
177 boolean dumpLocked(FileDescriptor fd, PrintWriter pw, boolean needSep, String dumpPackage) {
Adrian Roos20d7df32016-01-12 18:59:43 +0100178 if (!mProcessCrashTimes.getMap().isEmpty()) {
179 boolean printed = false;
180 final long now = SystemClock.uptimeMillis();
181 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
182 final int processCount = pmap.size();
183 for (int ip = 0; ip < processCount; ip++) {
184 final String pname = pmap.keyAt(ip);
185 final SparseArray<Long> uids = pmap.valueAt(ip);
186 final int uidCount = uids.size();
187 for (int i = 0; i < uidCount; i++) {
188 final int puid = uids.keyAt(i);
189 final ProcessRecord r = mService.mProcessNames.get(pname, puid);
190 if (dumpPackage != null && (r == null
191 || !r.pkgList.containsKey(dumpPackage))) {
192 continue;
193 }
194 if (!printed) {
195 if (needSep) pw.println();
196 needSep = true;
197 pw.println(" Time since processes crashed:");
198 printed = true;
199 }
200 pw.print(" Process "); pw.print(pname);
201 pw.print(" uid "); pw.print(puid);
202 pw.print(": last crashed ");
203 TimeUtils.formatDuration(now-uids.valueAt(i), pw);
204 pw.println(" ago");
205 }
206 }
207 }
208
209 if (!mBadProcesses.getMap().isEmpty()) {
210 boolean printed = false;
211 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
212 final int processCount = pmap.size();
213 for (int ip = 0; ip < processCount; ip++) {
214 final String pname = pmap.keyAt(ip);
215 final SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
216 final int uidCount = uids.size();
217 for (int i = 0; i < uidCount; i++) {
218 final int puid = uids.keyAt(i);
219 final ProcessRecord r = mService.mProcessNames.get(pname, puid);
220 if (dumpPackage != null && (r == null
221 || !r.pkgList.containsKey(dumpPackage))) {
222 continue;
223 }
224 if (!printed) {
225 if (needSep) pw.println();
226 needSep = true;
227 pw.println(" Bad processes:");
228 printed = true;
229 }
230 final BadProcessInfo info = uids.valueAt(i);
231 pw.print(" Bad process "); pw.print(pname);
232 pw.print(" uid "); pw.print(puid);
233 pw.print(": crashed at time "); pw.println(info.time);
234 if (info.shortMsg != null) {
235 pw.print(" Short msg: "); pw.println(info.shortMsg);
236 }
237 if (info.longMsg != null) {
238 pw.print(" Long msg: "); pw.println(info.longMsg);
239 }
240 if (info.stack != null) {
241 pw.println(" Stack:");
242 int lastPos = 0;
243 for (int pos = 0; pos < info.stack.length(); pos++) {
244 if (info.stack.charAt(pos) == '\n') {
245 pw.print(" ");
246 pw.write(info.stack, lastPos, pos-lastPos);
247 pw.println();
248 lastPos = pos+1;
249 }
250 }
251 if (lastPos < info.stack.length()) {
252 pw.print(" ");
253 pw.write(info.stack, lastPos, info.stack.length()-lastPos);
254 pw.println();
255 }
256 }
257 }
258 }
259 }
260 return needSep;
261 }
262
263 boolean isBadProcessLocked(ApplicationInfo info) {
264 return mBadProcesses.get(info.processName, info.uid) != null;
265 }
266
267 void clearBadProcessLocked(ApplicationInfo info) {
268 mBadProcesses.remove(info.processName, info.uid);
269 }
270
271 void resetProcessCrashTimeLocked(ApplicationInfo info) {
272 mProcessCrashTimes.remove(info.processName, info.uid);
273 }
274
275 void resetProcessCrashTimeLocked(boolean resetEntireUser, int appId, int userId) {
276 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
277 for (int ip = pmap.size() - 1; ip >= 0; ip--) {
278 SparseArray<Long> ba = pmap.valueAt(ip);
279 for (int i = ba.size() - 1; i >= 0; i--) {
280 boolean remove = false;
281 final int entUid = ba.keyAt(i);
282 if (!resetEntireUser) {
283 if (userId == UserHandle.USER_ALL) {
284 if (UserHandle.getAppId(entUid) == appId) {
285 remove = true;
286 }
287 } else {
288 if (entUid == UserHandle.getUid(userId, appId)) {
289 remove = true;
290 }
291 }
292 } else if (UserHandle.getUserId(entUid) == userId) {
293 remove = true;
294 }
295 if (remove) {
296 ba.removeAt(i);
297 }
298 }
299 if (ba.size() == 0) {
300 pmap.removeAt(ip);
301 }
302 }
303 }
304
305 void loadAppsNotReportingCrashesFromConfigLocked(String appsNotReportingCrashesConfig) {
306 if (appsNotReportingCrashesConfig != null) {
307 final String[] split = appsNotReportingCrashesConfig.split(",");
308 if (split.length > 0) {
309 mAppsNotReportingCrashes = new ArraySet<>();
310 Collections.addAll(mAppsNotReportingCrashes, split);
311 }
312 }
313 }
314
315 void killAppAtUserRequestLocked(ProcessRecord app, Dialog fromDialog) {
316 app.crashing = false;
317 app.crashingReport = null;
318 app.notResponding = false;
319 app.notRespondingReport = null;
320 if (app.anrDialog == fromDialog) {
321 app.anrDialog = null;
322 }
323 if (app.waitDialog == fromDialog) {
324 app.waitDialog = null;
325 }
326 if (app.pid > 0 && app.pid != MY_PID) {
327 handleAppCrashLocked(app, "user-terminated" /*reason*/,
328 null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/, null /*data*/);
329 app.kill("user request after error", true);
330 }
331 }
332
Christopher Tate8aa8fe12017-01-20 17:50:32 -0800333 /**
334 * Induce a crash in the given app.
335 *
336 * @param uid if nonnegative, the required matching uid of the target to crash
337 * @param initialPid fast-path match for the target to crash
338 * @param packageName fallback match if the stated pid is not found or doesn't match uid
339 * @param userId If nonnegative, required to identify a match by package name
340 * @param message
341 */
342 void scheduleAppCrashLocked(int uid, int initialPid, String packageName, int userId,
Adrian Roos20d7df32016-01-12 18:59:43 +0100343 String message) {
344 ProcessRecord proc = null;
345
346 // Figure out which process to kill. We don't trust that initialPid
347 // still has any relation to current pids, so must scan through the
348 // list.
349
350 synchronized (mService.mPidsSelfLocked) {
351 for (int i=0; i<mService.mPidsSelfLocked.size(); i++) {
352 ProcessRecord p = mService.mPidsSelfLocked.valueAt(i);
Christopher Tate8aa8fe12017-01-20 17:50:32 -0800353 if (uid >= 0 && p.uid != uid) {
Adrian Roos20d7df32016-01-12 18:59:43 +0100354 continue;
355 }
356 if (p.pid == initialPid) {
357 proc = p;
358 break;
359 }
Christopher Tate8aa8fe12017-01-20 17:50:32 -0800360 if (p.pkgList.containsKey(packageName)
361 && (userId < 0 || p.userId == userId)) {
Adrian Roos20d7df32016-01-12 18:59:43 +0100362 proc = p;
363 }
364 }
365 }
366
367 if (proc == null) {
368 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
369 + " initialPid=" + initialPid
Christopher Tate8aa8fe12017-01-20 17:50:32 -0800370 + " packageName=" + packageName
371 + " userId=" + userId);
Adrian Roos20d7df32016-01-12 18:59:43 +0100372 return;
373 }
374
Joe Onorato57190282016-04-20 15:37:49 -0700375 proc.scheduleCrash(message);
Adrian Roos20d7df32016-01-12 18:59:43 +0100376 }
377
378 /**
379 * Bring up the "unexpected error" dialog box for a crashing app.
380 * Deal with edge cases (intercepts from instrumented applications,
381 * ActivityController, error intent receivers, that sort of thing).
382 * @param r the application crashing
383 * @param crashInfo describing the failure
384 */
385 void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
Mark Lub5e24992016-11-21 15:38:13 +0800386 final int callingPid = Binder.getCallingPid();
387 final int callingUid = Binder.getCallingUid();
388
Andrii Kulianfa3991a2016-04-28 14:18:37 -0700389 final long origId = Binder.clearCallingIdentity();
390 try {
Mark Lub5e24992016-11-21 15:38:13 +0800391 crashApplicationInner(r, crashInfo, callingPid, callingUid);
Andrii Kulianfa3991a2016-04-28 14:18:37 -0700392 } finally {
393 Binder.restoreCallingIdentity(origId);
394 }
395 }
396
Mark Lub5e24992016-11-21 15:38:13 +0800397 void crashApplicationInner(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo,
398 int callingPid, int callingUid) {
Adrian Roos20d7df32016-01-12 18:59:43 +0100399 long timeMillis = System.currentTimeMillis();
400 String shortMsg = crashInfo.exceptionClassName;
401 String longMsg = crashInfo.exceptionMessage;
402 String stackTrace = crashInfo.stackTrace;
403 if (shortMsg != null && longMsg != null) {
404 longMsg = shortMsg + ": " + longMsg;
405 } else if (shortMsg != null) {
406 longMsg = shortMsg;
407 }
408
Jeff Sharkeyfe6f85c2017-01-20 10:42:57 -0700409 // If a persistent app is stuck in a crash loop, the device isn't very
410 // usable, so we want to consider sending out a rescue party.
411 if (r != null && r.persistent) {
412 RescueParty.notePersistentAppCrash(mContext, r.uid);
413 }
414
Adrian Roos20d7df32016-01-12 18:59:43 +0100415 AppErrorResult result = new AppErrorResult();
416 TaskRecord task;
417 synchronized (mService) {
Andrii Kulianfa3991a2016-04-28 14:18:37 -0700418 /**
419 * If crash is handled by instance of {@link android.app.IActivityController},
420 * finish now and don't show the app error dialog.
421 */
422 if (handleAppCrashInActivityController(r, crashInfo, shortMsg, longMsg, stackTrace,
Mark Lub5e24992016-11-21 15:38:13 +0800423 timeMillis, callingPid, callingUid)) {
Andrii Kulianfa3991a2016-04-28 14:18:37 -0700424 return;
Adrian Roos20d7df32016-01-12 18:59:43 +0100425 }
426
Andrii Kulianfa3991a2016-04-28 14:18:37 -0700427 /**
428 * If this process was running instrumentation, finish now - it will be handled in
429 * {@link ActivityManagerService#handleAppDiedLocked}.
430 */
Dianne Hackborn34041732017-01-31 15:27:13 -0800431 if (r != null && r.instr != null) {
Adrian Roos20d7df32016-01-12 18:59:43 +0100432 return;
433 }
434
435 // Log crash in battery stats.
436 if (r != null) {
437 mService.mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
438 }
439
440 AppErrorDialog.Data data = new AppErrorDialog.Data();
441 data.result = result;
442 data.proc = r;
443
444 // If we can't identify the process or it's already exceeded its crash quota,
445 // quit right away without showing a crash dialog.
446 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace, data)) {
Adrian Roos20d7df32016-01-12 18:59:43 +0100447 return;
448 }
449
Wale Ogunwale9645b0f2016-09-12 10:49:35 -0700450 final Message msg = Message.obtain();
Adrian Roos20d7df32016-01-12 18:59:43 +0100451 msg.what = ActivityManagerService.SHOW_ERROR_UI_MSG;
452
453 task = data.task;
454 msg.obj = data;
455 mService.mUiHandler.sendMessage(msg);
Adrian Roos20d7df32016-01-12 18:59:43 +0100456 }
457
458 int res = result.get();
459
460 Intent appErrorIntent = null;
Andrii Kulianfa3991a2016-04-28 14:18:37 -0700461 MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_CRASH, res);
Adrian Roosad028c12016-05-17 14:30:42 -0700462 if (res == AppErrorDialog.TIMEOUT || res == AppErrorDialog.CANCEL) {
Andrii Kulianfa3991a2016-04-28 14:18:37 -0700463 res = AppErrorDialog.FORCE_QUIT;
464 }
Andrii Kulianfa3991a2016-04-28 14:18:37 -0700465 synchronized (mService) {
466 if (res == AppErrorDialog.MUTE) {
467 stopReportingCrashesLocked(r);
468 }
469 if (res == AppErrorDialog.RESTART) {
470 mService.removeProcessLocked(r, false, true, "crash");
471 if (task != null) {
472 try {
473 mService.startActivityFromRecents(task.taskId,
474 ActivityOptions.makeBasic().toBundle());
475 } catch (IllegalArgumentException e) {
476 // Hmm, that didn't work, app might have crashed before creating a
477 // recents entry. Let's see if we have a safe-to-restart intent.
Dianne Hackborn4d895942016-07-12 13:36:02 -0700478 final Set<String> cats = task.intent.getCategories();
479 if (cats != null && cats.contains(Intent.CATEGORY_LAUNCHER)) {
Bryce Leed3624e12017-11-30 08:51:45 -0800480 mService.getActivityStartController().startActivityInPackage(
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100481 task.mCallingUid, callingPid, callingUid, task.mCallingPackage,
482 task.intent, null, null, null, 0, 0,
483 new SafeActivityOptions(ActivityOptions.makeBasic()),
484 task.userId, null,
485 "AppErrors");
Andrii Kulianfa3991a2016-04-28 14:18:37 -0700486 }
487 }
488 }
489 }
490 if (res == AppErrorDialog.FORCE_QUIT) {
491 long orig = Binder.clearCallingIdentity();
492 try {
493 // Kill it with fire!
494 mService.mStackSupervisor.handleAppCrashLocked(r);
495 if (!r.persistent) {
496 mService.removeProcessLocked(r, false, false, "crash");
497 mService.mStackSupervisor.resumeFocusedStackTopActivityLocked();
498 }
499 } finally {
500 Binder.restoreCallingIdentity(orig);
501 }
502 }
503 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
504 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
505 }
506 if (r != null && !r.isolated && res != AppErrorDialog.RESTART) {
507 // XXX Can't keep track of crash time for isolated processes,
508 // since they don't have a persistent identity.
509 mProcessCrashTimes.put(r.info.processName, r.uid,
510 SystemClock.uptimeMillis());
511 }
Adrian Roos20d7df32016-01-12 18:59:43 +0100512 }
513
514 if (appErrorIntent != null) {
515 try {
516 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
517 } catch (ActivityNotFoundException e) {
518 Slog.w(TAG, "bug report receiver dissappeared", e);
519 }
520 }
521 }
522
Andrii Kulianfa3991a2016-04-28 14:18:37 -0700523 private boolean handleAppCrashInActivityController(ProcessRecord r,
524 ApplicationErrorReport.CrashInfo crashInfo,
525 String shortMsg, String longMsg,
Mark Lub5e24992016-11-21 15:38:13 +0800526 String stackTrace, long timeMillis,
527 int callingPid, int callingUid) {
Andrii Kulianfa3991a2016-04-28 14:18:37 -0700528 if (mService.mController == null) {
529 return false;
530 }
531
532 try {
533 String name = r != null ? r.processName : null;
Mark Lub5e24992016-11-21 15:38:13 +0800534 int pid = r != null ? r.pid : callingPid;
535 int uid = r != null ? r.info.uid : callingUid;
Andrii Kulianfa3991a2016-04-28 14:18:37 -0700536 if (!mService.mController.appCrashed(name, pid,
537 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
538 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
539 && "Native crash".equals(crashInfo.exceptionClassName)) {
540 Slog.w(TAG, "Skip killing native crashed app " + name
541 + "(" + pid + ") during testing");
542 } else {
543 Slog.w(TAG, "Force-killing crashed app " + name
544 + " at watcher's request");
545 if (r != null) {
546 if (!makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace, null))
547 {
548 r.kill("crash", true);
549 }
550 } else {
551 // Huh.
552 Process.killProcess(pid);
553 ActivityManagerService.killProcessGroup(uid, pid);
554 }
555 }
556 return true;
557 }
558 } catch (RemoteException e) {
559 mService.mController = null;
560 Watchdog.getInstance().setActivityController(null);
561 }
562 return false;
563 }
564
Adrian Roos20d7df32016-01-12 18:59:43 +0100565 private boolean makeAppCrashingLocked(ProcessRecord app,
566 String shortMsg, String longMsg, String stackTrace, AppErrorDialog.Data data) {
567 app.crashing = true;
568 app.crashingReport = generateProcessError(app,
569 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
570 startAppProblemLocked(app);
571 app.stopFreezingAllLocked();
572 return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace,
573 data);
574 }
575
576 void startAppProblemLocked(ProcessRecord app) {
577 // If this app is not running under the current user, then we
578 // can't give it a report button because that would require
579 // launching the report UI under a different user.
580 app.errorReportReceiver = null;
581
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700582 for (int userId : mService.mUserController.getCurrentProfileIds()) {
Adrian Roos20d7df32016-01-12 18:59:43 +0100583 if (app.userId == userId) {
584 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
585 mContext, app.info.packageName, app.info.flags);
586 }
587 }
588 mService.skipCurrentReceiverLocked(app);
589 }
590
591 /**
592 * Generate a process error record, suitable for attachment to a ProcessRecord.
593 *
594 * @param app The ProcessRecord in which the error occurred.
595 * @param condition Crashing, Application Not Responding, etc. Values are defined in
Sudheer Shankaf6690102017-10-16 10:20:32 -0700596 * ActivityManager.ProcessErrorStateInfo
Adrian Roos20d7df32016-01-12 18:59:43 +0100597 * @param activity The activity associated with the crash, if known.
598 * @param shortMsg Short message describing the crash.
599 * @param longMsg Long message describing the crash.
600 * @param stackTrace Full crash stack trace, may be null.
601 *
Sudheer Shankaf6690102017-10-16 10:20:32 -0700602 * @return Returns a fully-formed ProcessErrorStateInfo record.
Adrian Roos20d7df32016-01-12 18:59:43 +0100603 */
604 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
605 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
606 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
607
608 report.condition = condition;
609 report.processName = app.processName;
610 report.pid = app.pid;
611 report.uid = app.info.uid;
612 report.tag = activity;
613 report.shortMsg = shortMsg;
614 report.longMsg = longMsg;
615 report.stackTrace = stackTrace;
616
617 return report;
618 }
619
620 Intent createAppErrorIntentLocked(ProcessRecord r,
621 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
622 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
623 if (report == null) {
624 return null;
625 }
626 Intent result = new Intent(Intent.ACTION_APP_ERROR);
627 result.setComponent(r.errorReportReceiver);
628 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
629 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
630 return result;
631 }
632
633 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
634 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
635 if (r.errorReportReceiver == null) {
636 return null;
637 }
638
639 if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
640 return null;
641 }
642
643 ApplicationErrorReport report = new ApplicationErrorReport();
644 report.packageName = r.info.packageName;
645 report.installerPackageName = r.errorReportReceiver.getPackageName();
646 report.processName = r.processName;
647 report.time = timeMillis;
648 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
649
650 if (r.crashing || r.forceCrashReport) {
651 report.type = ApplicationErrorReport.TYPE_CRASH;
652 report.crashInfo = crashInfo;
653 } else if (r.notResponding) {
654 report.type = ApplicationErrorReport.TYPE_ANR;
655 report.anrInfo = new ApplicationErrorReport.AnrInfo();
656
657 report.anrInfo.activity = r.notRespondingReport.tag;
658 report.anrInfo.cause = r.notRespondingReport.shortMsg;
659 report.anrInfo.info = r.notRespondingReport.longMsg;
660 }
661
662 return report;
663 }
664
665 boolean handleAppCrashLocked(ProcessRecord app, String reason,
666 String shortMsg, String longMsg, String stackTrace, AppErrorDialog.Data data) {
Amith Yamasanib0c8a882017-08-28 09:36:42 -0700667 final long now = SystemClock.uptimeMillis();
668 final boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
Adrian Roos6a7e0892016-08-23 14:26:39 +0200669 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
Adrian Roos20d7df32016-01-12 18:59:43 +0100670
Amith Yamasanib0c8a882017-08-28 09:36:42 -0700671 final boolean procIsBoundForeground =
672 (app.curProcState == ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
673
Adrian Roos20d7df32016-01-12 18:59:43 +0100674 Long crashTime;
675 Long crashTimePersistent;
Amith Yamasanib0c8a882017-08-28 09:36:42 -0700676 boolean tryAgain = false;
677
Adrian Roos20d7df32016-01-12 18:59:43 +0100678 if (!app.isolated) {
679 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
680 crashTimePersistent = mProcessCrashTimesPersistent.get(app.info.processName, app.uid);
681 } else {
682 crashTime = crashTimePersistent = null;
683 }
Amith Yamasanib0c8a882017-08-28 09:36:42 -0700684
685 // Bump up the crash count of any services currently running in the proc.
686 for (int i = app.services.size() - 1; i >= 0; i--) {
687 // Any services running in the application need to be placed
688 // back in the pending list.
689 ServiceRecord sr = app.services.valueAt(i);
690 // If the service was restarted a while ago, then reset crash count, else increment it.
691 if (now > sr.restartTime + ProcessList.MIN_CRASH_INTERVAL) {
692 sr.crashCount = 1;
693 } else {
694 sr.crashCount++;
695 }
696 // Allow restarting for started or bound foreground services that are crashing.
697 // This includes wallpapers.
698 if (sr.crashCount < mService.mConstants.BOUND_SERVICE_MAX_CRASH_RETRY
699 && (sr.isForeground || procIsBoundForeground)) {
700 tryAgain = true;
701 }
702 }
703
704 if (crashTime != null && now < crashTime + ProcessList.MIN_CRASH_INTERVAL) {
705 // The process crashed again very quickly. If it was a bound foreground service, let's
706 // try to restart again in a while, otherwise the process loses!
Adrian Roos20d7df32016-01-12 18:59:43 +0100707 Slog.w(TAG, "Process " + app.info.processName
708 + " has crashed too many times: killing!");
709 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
710 app.userId, app.info.processName, app.uid);
711 mService.mStackSupervisor.handleAppCrashLocked(app);
712 if (!app.persistent) {
713 // We don't want to start this process again until the user
714 // explicitly does so... but for persistent process, we really
715 // need to keep it running. If a persistent process is actually
716 // repeatedly crashing, then badness for everyone.
717 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
718 app.info.processName);
719 if (!app.isolated) {
720 // XXX We don't have a way to mark isolated processes
721 // as bad, since they don't have a peristent identity.
722 mBadProcesses.put(app.info.processName, app.uid,
723 new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
724 mProcessCrashTimes.remove(app.info.processName, app.uid);
725 }
726 app.bad = true;
727 app.removed = true;
728 // Don't let services in this process be restarted and potentially
729 // annoy the user repeatedly. Unless it is persistent, since those
730 // processes run critical code.
Amith Yamasanib0c8a882017-08-28 09:36:42 -0700731 mService.removeProcessLocked(app, false, tryAgain, "crash");
Adrian Roos20d7df32016-01-12 18:59:43 +0100732 mService.mStackSupervisor.resumeFocusedStackTopActivityLocked();
Adrian Roos6a7e0892016-08-23 14:26:39 +0200733 if (!showBackground) {
734 return false;
735 }
Adrian Roos20d7df32016-01-12 18:59:43 +0100736 }
737 mService.mStackSupervisor.resumeFocusedStackTopActivityLocked();
738 } else {
739 TaskRecord affectedTask =
740 mService.mStackSupervisor.finishTopRunningActivityLocked(app, reason);
741 if (data != null) {
742 data.task = affectedTask;
743 }
744 if (data != null && crashTimePersistent != null
745 && now < crashTimePersistent + ProcessList.MIN_CRASH_INTERVAL) {
746 data.repeating = true;
747 }
748 }
749
Amith Yamasanib0c8a882017-08-28 09:36:42 -0700750 if (data != null && tryAgain) {
751 data.isRestartableForService = true;
Adrian Roos20d7df32016-01-12 18:59:43 +0100752 }
753
754 // If the crashing process is what we consider to be the "home process" and it has been
755 // replaced by a third-party app, clear the package preferred activities from packages
756 // with a home activity running in the process to prevent a repeatedly crashing app
757 // from blocking the user to manually clear the list.
758 final ArrayList<ActivityRecord> activities = app.activities;
759 if (app == mService.mHomeProcess && activities.size() > 0
760 && (mService.mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
761 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
762 final ActivityRecord r = activities.get(activityNdx);
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700763 if (r.isActivityTypeHome()) {
Adrian Roos20d7df32016-01-12 18:59:43 +0100764 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
765 try {
766 ActivityThread.getPackageManager()
767 .clearPackagePreferredActivities(r.packageName);
768 } catch (RemoteException c) {
769 // pm is in same process, this will never happen.
770 }
771 }
772 }
773 }
774
775 if (!app.isolated) {
776 // XXX Can't keep track of crash times for isolated processes,
Amith Yamasanib0c8a882017-08-28 09:36:42 -0700777 // because they don't have a persistent identity.
Adrian Roos20d7df32016-01-12 18:59:43 +0100778 mProcessCrashTimes.put(app.info.processName, app.uid, now);
779 mProcessCrashTimesPersistent.put(app.info.processName, app.uid, now);
780 }
781
782 if (app.crashHandler != null) mService.mHandler.post(app.crashHandler);
783 return true;
784 }
785
786 void handleShowAppErrorUi(Message msg) {
787 AppErrorDialog.Data data = (AppErrorDialog.Data) msg.obj;
788 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
789 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
790 synchronized (mService) {
791 ProcessRecord proc = data.proc;
792 AppErrorResult res = data.result;
793 if (proc != null && proc.crashDialog != null) {
794 Slog.e(TAG, "App already has crash dialog: " + proc);
795 if (res != null) {
Adrian Roos90462222016-02-17 15:45:09 -0800796 res.set(AppErrorDialog.ALREADY_SHOWING);
Adrian Roos20d7df32016-01-12 18:59:43 +0100797 }
798 return;
799 }
800 boolean isBackground = (UserHandle.getAppId(proc.uid)
801 >= Process.FIRST_APPLICATION_UID
802 && proc.pid != MY_PID);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700803 for (int userId : mService.mUserController.getCurrentProfileIds()) {
Adrian Roos20d7df32016-01-12 18:59:43 +0100804 isBackground &= (proc.userId != userId);
805 }
806 if (isBackground && !showBackground) {
807 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
808 if (res != null) {
Adrian Roos90462222016-02-17 15:45:09 -0800809 res.set(AppErrorDialog.BACKGROUND_USER);
Adrian Roos20d7df32016-01-12 18:59:43 +0100810 }
811 return;
812 }
Andrew Sapperstein43643ae2017-12-20 15:17:33 -0800813 final boolean showFirstCrash = Settings.Global.getInt(
814 mContext.getContentResolver(),
815 Settings.Global.SHOW_FIRST_CRASH_DIALOG, 0) != 0;
816 final boolean showFirstCrashDevOption = Settings.Secure.getIntForUser(
817 mContext.getContentResolver(),
818 Settings.Secure.SHOW_FIRST_CRASH_DIALOG_DEV_OPTION,
819 0,
Andrew Sappersteinfd5238c2018-01-21 09:45:05 -0800820 mService.mUserController.getCurrentUserId()) != 0;
Adrian Roos20d7df32016-01-12 18:59:43 +0100821 final boolean crashSilenced = mAppsNotReportingCrashes != null &&
822 mAppsNotReportingCrashes.contains(proc.info.packageName);
Andrew Sapperstein43643ae2017-12-20 15:17:33 -0800823 if ((mService.canShowErrorDialogs() || showBackground) && !crashSilenced
824 && (showFirstCrash || showFirstCrashDevOption || data.repeating)) {
Phil Weaver445fd2a2016-03-17 17:26:24 -0700825 proc.crashDialog = new AppErrorDialog(mContext, mService, data);
Adrian Roos20d7df32016-01-12 18:59:43 +0100826 } else {
827 // The device is asleep, so just pretend that the user
828 // saw a crash dialog and hit "force quit".
829 if (res != null) {
Adrian Roos90462222016-02-17 15:45:09 -0800830 res.set(AppErrorDialog.CANT_SHOW);
Adrian Roos20d7df32016-01-12 18:59:43 +0100831 }
832 }
833 }
Phil Weaver445fd2a2016-03-17 17:26:24 -0700834 // If we've created a crash dialog, show it without the lock held
835 if(data.proc.crashDialog != null) {
Fyodor Kupolov5ddcca72017-04-28 17:38:10 -0700836 Slog.i(TAG, "Showing crash dialog for package " + data.proc.info.packageName
837 + " u" + data.proc.userId);
Phil Weaver445fd2a2016-03-17 17:26:24 -0700838 data.proc.crashDialog.show();
839 }
Adrian Roos20d7df32016-01-12 18:59:43 +0100840 }
841
842 void stopReportingCrashesLocked(ProcessRecord proc) {
843 if (mAppsNotReportingCrashes == null) {
844 mAppsNotReportingCrashes = new ArraySet<>();
845 }
846 mAppsNotReportingCrashes.add(proc.info.packageName);
847 }
848
Narayan Kamatha22d9fb2017-04-26 15:14:26 +0100849 static boolean isInterestingForBackgroundTraces(ProcessRecord app) {
850 // The system_server is always considered interesting.
851 if (app.pid == MY_PID) {
852 return true;
853 }
854
855 // A package is considered interesting if any of the following is true :
856 //
857 // - It's displaying an activity.
858 // - It's the SystemUI.
859 // - It has an overlay or a top UI visible.
860 //
861 // NOTE: The check whether a given ProcessRecord belongs to the systemui
862 // process is a bit of a kludge, but the same pattern seems repeated at
863 // several places in the system server.
864 return app.isInterestingToUserLocked() ||
865 (app.info != null && "com.android.systemui".equals(app.info.packageName)) ||
866 (app.hasTopUi || app.hasOverlayUi);
867 }
868
Adrian Roos20d7df32016-01-12 18:59:43 +0100869 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
870 ActivityRecord parent, boolean aboveSystem, final String annotation) {
871 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
872 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
873
874 if (mService.mController != null) {
875 try {
876 // 0 == continue, -1 = kill process immediately
Adrian Roosa85a2c62016-01-26 09:14:22 -0800877 int res = mService.mController.appEarlyNotResponding(
878 app.processName, app.pid, annotation);
Adrian Roos20d7df32016-01-12 18:59:43 +0100879 if (res < 0 && app.pid != MY_PID) {
880 app.kill("anr", true);
881 }
882 } catch (RemoteException e) {
883 mService.mController = null;
884 Watchdog.getInstance().setActivityController(null);
885 }
886 }
887
888 long anrTime = SystemClock.uptimeMillis();
889 if (ActivityManagerService.MONITOR_CPU_USAGE) {
890 mService.updateCpuStatsNow();
891 }
892
Tim Murrayf0f9a822016-07-13 13:33:28 -0700893 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
894 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
895 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
896
897 boolean isSilentANR;
898
Adrian Roos20d7df32016-01-12 18:59:43 +0100899 synchronized (mService) {
900 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
901 if (mService.mShuttingDown) {
902 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
903 return;
904 } else if (app.notResponding) {
905 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
906 return;
907 } else if (app.crashing) {
908 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
909 return;
Tobias Lindskog313177d2015-02-03 11:45:58 +0100910 } else if (app.killedByAm) {
911 Slog.i(TAG, "App already killed by AM skipping ANR: " + app + " " + annotation);
912 return;
Mark Lu41d65f22016-03-23 19:08:44 +0800913 } else if (app.killed) {
914 Slog.i(TAG, "Skipping died app ANR: " + app + " " + annotation);
915 return;
Adrian Roos20d7df32016-01-12 18:59:43 +0100916 }
917
918 // In case we come through here for the same app before completing
919 // this one, mark as anring now so we will bail out.
920 app.notResponding = true;
921
922 // Log the ANR to the event log.
923 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
924 app.processName, app.info.flags, annotation);
925
926 // Dump thread traces as quickly as we can, starting with "interesting" processes.
927 firstPids.add(app.pid);
928
Tim Murrayf0f9a822016-07-13 13:33:28 -0700929 // Don't dump other PIDs if it's a background ANR
Narayan Kamatha22d9fb2017-04-26 15:14:26 +0100930 isSilentANR = !showBackground && !isInterestingForBackgroundTraces(app);
Tim Murrayf0f9a822016-07-13 13:33:28 -0700931 if (!isSilentANR) {
932 int parentPid = app.pid;
933 if (parent != null && parent.app != null && parent.app.pid > 0) {
934 parentPid = parent.app.pid;
935 }
936 if (parentPid != app.pid) firstPids.add(parentPid);
Adrian Roos20d7df32016-01-12 18:59:43 +0100937
Tim Murrayf0f9a822016-07-13 13:33:28 -0700938 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
Adrian Roos20d7df32016-01-12 18:59:43 +0100939
Tim Murrayf0f9a822016-07-13 13:33:28 -0700940 for (int i = mService.mLruProcesses.size() - 1; i >= 0; i--) {
941 ProcessRecord r = mService.mLruProcesses.get(i);
942 if (r != null && r.thread != null) {
943 int pid = r.pid;
944 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
945 if (r.persistent) {
946 firstPids.add(pid);
947 if (DEBUG_ANR) Slog.i(TAG, "Adding persistent proc: " + r);
Brian Carlstrom90d1e362017-03-29 20:25:57 -0700948 } else if (r.treatLikeActivity) {
949 firstPids.add(pid);
950 if (DEBUG_ANR) Slog.i(TAG, "Adding likely IME: " + r);
Tim Murrayf0f9a822016-07-13 13:33:28 -0700951 } else {
952 lastPids.put(pid, Boolean.TRUE);
953 if (DEBUG_ANR) Slog.i(TAG, "Adding ANR proc: " + r);
954 }
Adrian Roos20d7df32016-01-12 18:59:43 +0100955 }
956 }
957 }
958 }
959 }
960
961 // Log the ANR to the main log.
962 StringBuilder info = new StringBuilder();
963 info.setLength(0);
964 info.append("ANR in ").append(app.processName);
965 if (activity != null && activity.shortComponentName != null) {
966 info.append(" (").append(activity.shortComponentName).append(")");
967 }
968 info.append("\n");
969 info.append("PID: ").append(app.pid).append("\n");
970 if (annotation != null) {
971 info.append("Reason: ").append(annotation).append("\n");
972 }
973 if (parent != null && parent != activity) {
974 info.append("Parent: ").append(parent.shortComponentName).append("\n");
975 }
976
Tim Murrayf0f9a822016-07-13 13:33:28 -0700977 ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
Adrian Roos20d7df32016-01-12 18:59:43 +0100978
Brian Carlstrom66524242017-03-11 00:14:13 -0800979 // don't dump native PIDs for background ANRs unless it is the process of interest
980 String[] nativeProcs = null;
Tim Murrayf0f9a822016-07-13 13:33:28 -0700981 if (isSilentANR) {
Brian Carlstrom66524242017-03-11 00:14:13 -0800982 for (int i = 0; i < NATIVE_STACKS_OF_INTEREST.length; i++) {
983 if (NATIVE_STACKS_OF_INTEREST[i].equals(app.processName)) {
984 nativeProcs = new String[] { app.processName };
985 break;
986 }
987 }
Tim Murrayf0f9a822016-07-13 13:33:28 -0700988 } else {
Brian Carlstrom66524242017-03-11 00:14:13 -0800989 nativeProcs = NATIVE_STACKS_OF_INTEREST;
Tim Murrayf0f9a822016-07-13 13:33:28 -0700990 }
Adrian Roos20d7df32016-01-12 18:59:43 +0100991
Martijn Coenen94a0dcd2017-03-27 12:45:19 -0700992 int[] pids = nativeProcs == null ? null : Process.getPidsForCommands(nativeProcs);
Steven Moreland6b47c542017-03-21 12:52:16 -0700993 ArrayList<Integer> nativePids = null;
994
995 if (pids != null) {
996 nativePids = new ArrayList<Integer>(pids.length);
997 for (int i : pids) {
998 nativePids.add(i);
999 }
1000 }
1001
Brian Carlstrom66524242017-03-11 00:14:13 -08001002 // For background ANRs, don't pass the ProcessCpuTracker to
1003 // avoid spending 1/2 second collecting stats to rank lastPids.
Narayan Kamathf013daa2017-05-09 12:55:02 +01001004 File tracesFile = ActivityManagerService.dumpStackTraces(
1005 true, firstPids,
1006 (isSilentANR) ? null : processCpuTracker,
1007 (isSilentANR) ? null : lastPids,
1008 nativePids);
Brian Carlstrom66524242017-03-11 00:14:13 -08001009
Adrian Roos20d7df32016-01-12 18:59:43 +01001010 String cpuInfo = null;
1011 if (ActivityManagerService.MONITOR_CPU_USAGE) {
1012 mService.updateCpuStatsNow();
1013 synchronized (mService.mProcessCpuTracker) {
1014 cpuInfo = mService.mProcessCpuTracker.printCurrentState(anrTime);
1015 }
1016 info.append(processCpuTracker.printCurrentLoad());
1017 info.append(cpuInfo);
1018 }
1019
1020 info.append(processCpuTracker.printCurrentState(anrTime));
1021
1022 Slog.e(TAG, info.toString());
1023 if (tracesFile == null) {
1024 // There is no trace file, so dump (only) the alleged culprit's threads to the log
1025 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
1026 }
1027
1028 mService.addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
1029 cpuInfo, tracesFile, null);
1030
1031 if (mService.mController != null) {
1032 try {
1033 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
1034 int res = mService.mController.appNotResponding(
1035 app.processName, app.pid, info.toString());
1036 if (res != 0) {
1037 if (res < 0 && app.pid != MY_PID) {
1038 app.kill("anr", true);
1039 } else {
1040 synchronized (mService) {
1041 mService.mServices.scheduleServiceTimeoutLocked(app);
1042 }
1043 }
1044 return;
1045 }
1046 } catch (RemoteException e) {
1047 mService.mController = null;
1048 Watchdog.getInstance().setActivityController(null);
1049 }
1050 }
1051
Adrian Roos20d7df32016-01-12 18:59:43 +01001052 synchronized (mService) {
1053 mService.mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
1054
Tim Murrayf0f9a822016-07-13 13:33:28 -07001055 if (isSilentANR) {
Adrian Roos20d7df32016-01-12 18:59:43 +01001056 app.kill("bg anr", true);
1057 return;
1058 }
1059
1060 // Set the app's notResponding state, and look up the errorReportReceiver
1061 makeAppNotRespondingLocked(app,
1062 activity != null ? activity.shortComponentName : null,
1063 annotation != null ? "ANR " + annotation : "ANR",
1064 info.toString());
1065
1066 // Bring up the infamous App Not Responding dialog
1067 Message msg = Message.obtain();
1068 HashMap<String, Object> map = new HashMap<String, Object>();
1069 msg.what = ActivityManagerService.SHOW_NOT_RESPONDING_UI_MSG;
1070 msg.obj = map;
1071 msg.arg1 = aboveSystem ? 1 : 0;
1072 map.put("app", app);
1073 if (activity != null) {
1074 map.put("activity", activity);
1075 }
1076
1077 mService.mUiHandler.sendMessage(msg);
1078 }
1079 }
1080
1081 private void makeAppNotRespondingLocked(ProcessRecord app,
1082 String activity, String shortMsg, String longMsg) {
1083 app.notResponding = true;
1084 app.notRespondingReport = generateProcessError(app,
1085 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
1086 activity, shortMsg, longMsg, null);
1087 startAppProblemLocked(app);
1088 app.stopFreezingAllLocked();
1089 }
1090
1091 void handleShowAnrUi(Message msg) {
Phil Weaver445fd2a2016-03-17 17:26:24 -07001092 Dialog d = null;
Adrian Roos20d7df32016-01-12 18:59:43 +01001093 synchronized (mService) {
1094 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1095 ProcessRecord proc = (ProcessRecord)data.get("app");
1096 if (proc != null && proc.anrDialog != null) {
1097 Slog.e(TAG, "App already has anr dialog: " + proc);
Adrian Roos90462222016-02-17 15:45:09 -08001098 MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_ANR,
1099 AppNotRespondingDialog.ALREADY_SHOWING);
Adrian Roos20d7df32016-01-12 18:59:43 +01001100 return;
1101 }
1102
1103 Intent intent = new Intent("android.intent.action.ANR");
1104 if (!mService.mProcessesReady) {
1105 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1106 | Intent.FLAG_RECEIVER_FOREGROUND);
1107 }
1108 mService.broadcastIntentLocked(null, null, intent,
1109 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1110 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1111
Adrian Roos6a7e0892016-08-23 14:26:39 +02001112 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1113 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1114 if (mService.canShowErrorDialogs() || showBackground) {
Phil Weaver445fd2a2016-03-17 17:26:24 -07001115 d = new AppNotRespondingDialog(mService,
Adrian Roos20d7df32016-01-12 18:59:43 +01001116 mContext, proc, (ActivityRecord)data.get("activity"),
1117 msg.arg1 != 0);
Adrian Roos20d7df32016-01-12 18:59:43 +01001118 proc.anrDialog = d;
1119 } else {
Adrian Roos90462222016-02-17 15:45:09 -08001120 MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_ANR,
1121 AppNotRespondingDialog.CANT_SHOW);
Adrian Roos20d7df32016-01-12 18:59:43 +01001122 // Just kill the app if there is no dialog to be shown.
1123 mService.killAppAtUsersRequest(proc, null);
1124 }
1125 }
Phil Weaver445fd2a2016-03-17 17:26:24 -07001126 // If we've created a crash dialog, show it without the lock held
1127 if (d != null) {
1128 d.show();
1129 }
Adrian Roos20d7df32016-01-12 18:59:43 +01001130 }
1131
1132 /**
1133 * Information about a process that is currently marked as bad.
1134 */
1135 static final class BadProcessInfo {
1136 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
1137 this.time = time;
1138 this.shortMsg = shortMsg;
1139 this.longMsg = longMsg;
1140 this.stack = stack;
1141 }
1142
1143 final long time;
1144 final String shortMsg;
1145 final String longMsg;
1146 final String stack;
1147 }
1148
1149}