blob: 9776c4d2f947174fdb17fa7932d483f920b1bfde [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;
Andrew Sapperstein5b679c42018-01-16 11:13:40 -080037import android.net.Uri;
Adrian Roos20d7df32016-01-12 18:59:43 +010038import android.os.Binder;
Adrian Roos20d7df32016-01-12 18:59:43 +010039import android.os.Message;
40import android.os.Process;
41import android.os.RemoteException;
42import android.os.SystemClock;
43import android.os.SystemProperties;
44import android.os.UserHandle;
45import android.provider.Settings;
46import android.util.ArrayMap;
47import android.util.ArraySet;
48import android.util.EventLog;
49import android.util.Log;
50import android.util.Slog;
51import android.util.SparseArray;
52import android.util.TimeUtils;
Yi Jin148d7f42017-11-28 14:23:56 -080053import android.util.proto.ProtoOutputStream;
Adrian Roos20d7df32016-01-12 18:59:43 +010054
55import java.io.File;
56import java.io.FileDescriptor;
57import java.io.PrintWriter;
58import java.util.ArrayList;
59import java.util.Collections;
60import java.util.HashMap;
Dianne Hackborn4d895942016-07-12 13:36:02 -070061import java.util.Set;
Adrian Roos20d7df32016-01-12 18:59:43 +010062
63import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
Dianne Hackborn9369efd2016-03-02 15:49:58 -080064import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
Adrian Roos20d7df32016-01-12 18:59:43 +010065import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
66import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
67import static com.android.server.am.ActivityManagerService.MY_PID;
68import static com.android.server.am.ActivityManagerService.SYSTEM_DEBUGGABLE;
69
70/**
71 * Controls error conditions in applications.
72 */
73class AppErrors {
74
75 private static final String TAG = TAG_WITH_CLASS_NAME ? "AppErrors" : TAG_AM;
76
77 private final ActivityManagerService mService;
78 private final Context mContext;
79
80 private ArraySet<String> mAppsNotReportingCrashes;
81
82 /**
83 * The last time that various processes have crashed since they were last explicitly started.
84 */
85 private final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<>();
86
87 /**
88 * The last time that various processes have crashed (not reset even when explicitly started).
89 */
90 private final ProcessMap<Long> mProcessCrashTimesPersistent = new ProcessMap<>();
91
92 /**
93 * Set of applications that we consider to be bad, and will reject
94 * incoming broadcasts from (which the user has no control over).
95 * Processes are added to this set when they have crashed twice within
96 * a minimum amount of time; they are removed from it when they are
97 * later restarted (hopefully due to some user action). The value is the
98 * time it was added to the list.
99 */
100 private final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<>();
101
102
103 AppErrors(Context context, ActivityManagerService service) {
Adam Lesinskia82b6262017-03-21 16:56:17 -0700104 context.assertRuntimeOverlayThemable();
Adrian Roos20d7df32016-01-12 18:59:43 +0100105 mService = service;
106 mContext = context;
107 }
108
Yi Jin148d7f42017-11-28 14:23:56 -0800109 void writeToProto(ProtoOutputStream proto, long fieldId, String dumpPackage) {
110 if (mProcessCrashTimes.getMap().isEmpty() && mBadProcesses.getMap().isEmpty()) {
111 return;
112 }
113
114 final long token = proto.start(fieldId);
115 final long now = SystemClock.uptimeMillis();
116 proto.write(AppErrorsProto.NOW_UPTIME_MS, now);
117
118 if (!mProcessCrashTimes.getMap().isEmpty()) {
119 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
120 final int procCount = pmap.size();
121 for (int ip = 0; ip < procCount; ip++) {
122 final long ctoken = proto.start(AppErrorsProto.PROCESS_CRASH_TIMES);
123 final String pname = pmap.keyAt(ip);
124 final SparseArray<Long> uids = pmap.valueAt(ip);
125 final int uidCount = uids.size();
126
127 proto.write(AppErrorsProto.ProcessCrashTime.PROCESS_NAME, pname);
128 for (int i = 0; i < uidCount; i++) {
129 final int puid = uids.keyAt(i);
130 final ProcessRecord r = mService.mProcessNames.get(pname, puid);
131 if (dumpPackage != null && (r == null || !r.pkgList.containsKey(dumpPackage))) {
132 continue;
133 }
134 final long etoken = proto.start(AppErrorsProto.ProcessCrashTime.ENTRIES);
135 proto.write(AppErrorsProto.ProcessCrashTime.Entry.UID, puid);
136 proto.write(AppErrorsProto.ProcessCrashTime.Entry.LAST_CRASHED_AT_MS,
137 uids.valueAt(i));
138 proto.end(etoken);
139 }
140 proto.end(ctoken);
141 }
142
143 }
144
145 if (!mBadProcesses.getMap().isEmpty()) {
146 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
147 final int processCount = pmap.size();
148 for (int ip = 0; ip < processCount; ip++) {
149 final long btoken = proto.start(AppErrorsProto.BAD_PROCESSES);
150 final String pname = pmap.keyAt(ip);
151 final SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
152 final int uidCount = uids.size();
153
154 proto.write(AppErrorsProto.BadProcess.PROCESS_NAME, pname);
155 for (int i = 0; i < uidCount; i++) {
156 final int puid = uids.keyAt(i);
157 final ProcessRecord r = mService.mProcessNames.get(pname, puid);
158 if (dumpPackage != null && (r == null
159 || !r.pkgList.containsKey(dumpPackage))) {
160 continue;
161 }
162 final BadProcessInfo info = uids.valueAt(i);
163 final long etoken = proto.start(AppErrorsProto.BadProcess.ENTRIES);
164 proto.write(AppErrorsProto.BadProcess.Entry.UID, puid);
165 proto.write(AppErrorsProto.BadProcess.Entry.CRASHED_AT_MS, info.time);
166 proto.write(AppErrorsProto.BadProcess.Entry.SHORT_MSG, info.shortMsg);
167 proto.write(AppErrorsProto.BadProcess.Entry.LONG_MSG, info.longMsg);
168 proto.write(AppErrorsProto.BadProcess.Entry.STACK, info.stack);
169 proto.end(etoken);
170 }
171 proto.end(btoken);
172 }
173 }
174
175 proto.end(token);
176 }
177
178 boolean dumpLocked(FileDescriptor fd, PrintWriter pw, boolean needSep, String dumpPackage) {
Adrian Roos20d7df32016-01-12 18:59:43 +0100179 if (!mProcessCrashTimes.getMap().isEmpty()) {
180 boolean printed = false;
181 final long now = SystemClock.uptimeMillis();
182 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
183 final int processCount = pmap.size();
184 for (int ip = 0; ip < processCount; ip++) {
185 final String pname = pmap.keyAt(ip);
186 final SparseArray<Long> uids = pmap.valueAt(ip);
187 final int uidCount = uids.size();
188 for (int i = 0; i < uidCount; i++) {
189 final int puid = uids.keyAt(i);
190 final ProcessRecord r = mService.mProcessNames.get(pname, puid);
191 if (dumpPackage != null && (r == null
192 || !r.pkgList.containsKey(dumpPackage))) {
193 continue;
194 }
195 if (!printed) {
196 if (needSep) pw.println();
197 needSep = true;
198 pw.println(" Time since processes crashed:");
199 printed = true;
200 }
201 pw.print(" Process "); pw.print(pname);
202 pw.print(" uid "); pw.print(puid);
203 pw.print(": last crashed ");
204 TimeUtils.formatDuration(now-uids.valueAt(i), pw);
205 pw.println(" ago");
206 }
207 }
208 }
209
210 if (!mBadProcesses.getMap().isEmpty()) {
211 boolean printed = false;
212 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
213 final int processCount = pmap.size();
214 for (int ip = 0; ip < processCount; ip++) {
215 final String pname = pmap.keyAt(ip);
216 final SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
217 final int uidCount = uids.size();
218 for (int i = 0; i < uidCount; i++) {
219 final int puid = uids.keyAt(i);
220 final ProcessRecord r = mService.mProcessNames.get(pname, puid);
221 if (dumpPackage != null && (r == null
222 || !r.pkgList.containsKey(dumpPackage))) {
223 continue;
224 }
225 if (!printed) {
226 if (needSep) pw.println();
227 needSep = true;
228 pw.println(" Bad processes:");
229 printed = true;
230 }
231 final BadProcessInfo info = uids.valueAt(i);
232 pw.print(" Bad process "); pw.print(pname);
233 pw.print(" uid "); pw.print(puid);
234 pw.print(": crashed at time "); pw.println(info.time);
235 if (info.shortMsg != null) {
236 pw.print(" Short msg: "); pw.println(info.shortMsg);
237 }
238 if (info.longMsg != null) {
239 pw.print(" Long msg: "); pw.println(info.longMsg);
240 }
241 if (info.stack != null) {
242 pw.println(" Stack:");
243 int lastPos = 0;
244 for (int pos = 0; pos < info.stack.length(); pos++) {
245 if (info.stack.charAt(pos) == '\n') {
246 pw.print(" ");
247 pw.write(info.stack, lastPos, pos-lastPos);
248 pw.println();
249 lastPos = pos+1;
250 }
251 }
252 if (lastPos < info.stack.length()) {
253 pw.print(" ");
254 pw.write(info.stack, lastPos, info.stack.length()-lastPos);
255 pw.println();
256 }
257 }
258 }
259 }
260 }
261 return needSep;
262 }
263
264 boolean isBadProcessLocked(ApplicationInfo info) {
265 return mBadProcesses.get(info.processName, info.uid) != null;
266 }
267
268 void clearBadProcessLocked(ApplicationInfo info) {
269 mBadProcesses.remove(info.processName, info.uid);
270 }
271
272 void resetProcessCrashTimeLocked(ApplicationInfo info) {
273 mProcessCrashTimes.remove(info.processName, info.uid);
274 }
275
276 void resetProcessCrashTimeLocked(boolean resetEntireUser, int appId, int userId) {
277 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
278 for (int ip = pmap.size() - 1; ip >= 0; ip--) {
279 SparseArray<Long> ba = pmap.valueAt(ip);
280 for (int i = ba.size() - 1; i >= 0; i--) {
281 boolean remove = false;
282 final int entUid = ba.keyAt(i);
283 if (!resetEntireUser) {
284 if (userId == UserHandle.USER_ALL) {
285 if (UserHandle.getAppId(entUid) == appId) {
286 remove = true;
287 }
288 } else {
289 if (entUid == UserHandle.getUid(userId, appId)) {
290 remove = true;
291 }
292 }
293 } else if (UserHandle.getUserId(entUid) == userId) {
294 remove = true;
295 }
296 if (remove) {
297 ba.removeAt(i);
298 }
299 }
300 if (ba.size() == 0) {
301 pmap.removeAt(ip);
302 }
303 }
304 }
305
306 void loadAppsNotReportingCrashesFromConfigLocked(String appsNotReportingCrashesConfig) {
307 if (appsNotReportingCrashesConfig != null) {
308 final String[] split = appsNotReportingCrashesConfig.split(",");
309 if (split.length > 0) {
310 mAppsNotReportingCrashes = new ArraySet<>();
311 Collections.addAll(mAppsNotReportingCrashes, split);
312 }
313 }
314 }
315
316 void killAppAtUserRequestLocked(ProcessRecord app, Dialog fromDialog) {
317 app.crashing = false;
318 app.crashingReport = null;
319 app.notResponding = false;
320 app.notRespondingReport = null;
321 if (app.anrDialog == fromDialog) {
322 app.anrDialog = null;
323 }
324 if (app.waitDialog == fromDialog) {
325 app.waitDialog = null;
326 }
327 if (app.pid > 0 && app.pid != MY_PID) {
328 handleAppCrashLocked(app, "user-terminated" /*reason*/,
329 null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/, null /*data*/);
330 app.kill("user request after error", true);
331 }
332 }
333
Christopher Tate8aa8fe12017-01-20 17:50:32 -0800334 /**
335 * Induce a crash in the given app.
336 *
337 * @param uid if nonnegative, the required matching uid of the target to crash
338 * @param initialPid fast-path match for the target to crash
339 * @param packageName fallback match if the stated pid is not found or doesn't match uid
340 * @param userId If nonnegative, required to identify a match by package name
341 * @param message
342 */
343 void scheduleAppCrashLocked(int uid, int initialPid, String packageName, int userId,
Adrian Roos20d7df32016-01-12 18:59:43 +0100344 String message) {
345 ProcessRecord proc = null;
346
347 // Figure out which process to kill. We don't trust that initialPid
348 // still has any relation to current pids, so must scan through the
349 // list.
350
351 synchronized (mService.mPidsSelfLocked) {
352 for (int i=0; i<mService.mPidsSelfLocked.size(); i++) {
353 ProcessRecord p = mService.mPidsSelfLocked.valueAt(i);
Christopher Tate8aa8fe12017-01-20 17:50:32 -0800354 if (uid >= 0 && p.uid != uid) {
Adrian Roos20d7df32016-01-12 18:59:43 +0100355 continue;
356 }
357 if (p.pid == initialPid) {
358 proc = p;
359 break;
360 }
Christopher Tate8aa8fe12017-01-20 17:50:32 -0800361 if (p.pkgList.containsKey(packageName)
362 && (userId < 0 || p.userId == userId)) {
Adrian Roos20d7df32016-01-12 18:59:43 +0100363 proc = p;
364 }
365 }
366 }
367
368 if (proc == null) {
369 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
370 + " initialPid=" + initialPid
Christopher Tate8aa8fe12017-01-20 17:50:32 -0800371 + " packageName=" + packageName
372 + " userId=" + userId);
Adrian Roos20d7df32016-01-12 18:59:43 +0100373 return;
374 }
375
Joe Onorato57190282016-04-20 15:37:49 -0700376 proc.scheduleCrash(message);
Adrian Roos20d7df32016-01-12 18:59:43 +0100377 }
378
379 /**
380 * Bring up the "unexpected error" dialog box for a crashing app.
381 * Deal with edge cases (intercepts from instrumented applications,
382 * ActivityController, error intent receivers, that sort of thing).
383 * @param r the application crashing
384 * @param crashInfo describing the failure
385 */
386 void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
Mark Lub5e24992016-11-21 15:38:13 +0800387 final int callingPid = Binder.getCallingPid();
388 final int callingUid = Binder.getCallingUid();
389
Andrii Kulianfa3991a2016-04-28 14:18:37 -0700390 final long origId = Binder.clearCallingIdentity();
391 try {
Mark Lub5e24992016-11-21 15:38:13 +0800392 crashApplicationInner(r, crashInfo, callingPid, callingUid);
Andrii Kulianfa3991a2016-04-28 14:18:37 -0700393 } finally {
394 Binder.restoreCallingIdentity(origId);
395 }
396 }
397
Mark Lub5e24992016-11-21 15:38:13 +0800398 void crashApplicationInner(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo,
399 int callingPid, int callingUid) {
Adrian Roos20d7df32016-01-12 18:59:43 +0100400 long timeMillis = System.currentTimeMillis();
401 String shortMsg = crashInfo.exceptionClassName;
402 String longMsg = crashInfo.exceptionMessage;
403 String stackTrace = crashInfo.stackTrace;
404 if (shortMsg != null && longMsg != null) {
405 longMsg = shortMsg + ": " + longMsg;
406 } else if (shortMsg != null) {
407 longMsg = shortMsg;
408 }
409
Jeff Sharkeyfe6f85c2017-01-20 10:42:57 -0700410 // If a persistent app is stuck in a crash loop, the device isn't very
411 // usable, so we want to consider sending out a rescue party.
412 if (r != null && r.persistent) {
413 RescueParty.notePersistentAppCrash(mContext, r.uid);
414 }
415
Adrian Roos20d7df32016-01-12 18:59:43 +0100416 AppErrorResult result = new AppErrorResult();
417 TaskRecord task;
418 synchronized (mService) {
Andrii Kulianfa3991a2016-04-28 14:18:37 -0700419 /**
420 * If crash is handled by instance of {@link android.app.IActivityController},
421 * finish now and don't show the app error dialog.
422 */
423 if (handleAppCrashInActivityController(r, crashInfo, shortMsg, longMsg, stackTrace,
Mark Lub5e24992016-11-21 15:38:13 +0800424 timeMillis, callingPid, callingUid)) {
Andrii Kulianfa3991a2016-04-28 14:18:37 -0700425 return;
Adrian Roos20d7df32016-01-12 18:59:43 +0100426 }
427
Andrii Kulianfa3991a2016-04-28 14:18:37 -0700428 /**
429 * If this process was running instrumentation, finish now - it will be handled in
430 * {@link ActivityManagerService#handleAppDiedLocked}.
431 */
Dianne Hackborn34041732017-01-31 15:27:13 -0800432 if (r != null && r.instr != null) {
Adrian Roos20d7df32016-01-12 18:59:43 +0100433 return;
434 }
435
436 // Log crash in battery stats.
437 if (r != null) {
438 mService.mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
439 }
440
441 AppErrorDialog.Data data = new AppErrorDialog.Data();
442 data.result = result;
443 data.proc = r;
444
445 // If we can't identify the process or it's already exceeded its crash quota,
446 // quit right away without showing a crash dialog.
447 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace, data)) {
Adrian Roos20d7df32016-01-12 18:59:43 +0100448 return;
449 }
450
Wale Ogunwale9645b0f2016-09-12 10:49:35 -0700451 final Message msg = Message.obtain();
Adrian Roos20d7df32016-01-12 18:59:43 +0100452 msg.what = ActivityManagerService.SHOW_ERROR_UI_MSG;
453
454 task = data.task;
455 msg.obj = data;
456 mService.mUiHandler.sendMessage(msg);
Adrian Roos20d7df32016-01-12 18:59:43 +0100457 }
458
459 int res = result.get();
460
461 Intent appErrorIntent = null;
Andrii Kulianfa3991a2016-04-28 14:18:37 -0700462 MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_CRASH, res);
Adrian Roosad028c12016-05-17 14:30:42 -0700463 if (res == AppErrorDialog.TIMEOUT || res == AppErrorDialog.CANCEL) {
Andrii Kulianfa3991a2016-04-28 14:18:37 -0700464 res = AppErrorDialog.FORCE_QUIT;
465 }
Andrii Kulianfa3991a2016-04-28 14:18:37 -0700466 synchronized (mService) {
467 if (res == AppErrorDialog.MUTE) {
468 stopReportingCrashesLocked(r);
469 }
470 if (res == AppErrorDialog.RESTART) {
471 mService.removeProcessLocked(r, false, true, "crash");
472 if (task != null) {
473 try {
474 mService.startActivityFromRecents(task.taskId,
475 ActivityOptions.makeBasic().toBundle());
476 } catch (IllegalArgumentException e) {
477 // Hmm, that didn't work, app might have crashed before creating a
478 // recents entry. Let's see if we have a safe-to-restart intent.
Dianne Hackborn4d895942016-07-12 13:36:02 -0700479 final Set<String> cats = task.intent.getCategories();
480 if (cats != null && cats.contains(Intent.CATEGORY_LAUNCHER)) {
Bryce Leed3624e12017-11-30 08:51:45 -0800481 mService.getActivityStartController().startActivityInPackage(
Jorim Jaggi4d8d32c2018-01-19 15:57:41 +0100482 task.mCallingUid, callingPid, callingUid, task.mCallingPackage,
483 task.intent, null, null, null, 0, 0,
484 new SafeActivityOptions(ActivityOptions.makeBasic()),
485 task.userId, null,
486 "AppErrors");
Andrii Kulianfa3991a2016-04-28 14:18:37 -0700487 }
488 }
489 }
490 }
491 if (res == AppErrorDialog.FORCE_QUIT) {
492 long orig = Binder.clearCallingIdentity();
493 try {
494 // Kill it with fire!
495 mService.mStackSupervisor.handleAppCrashLocked(r);
496 if (!r.persistent) {
497 mService.removeProcessLocked(r, false, false, "crash");
498 mService.mStackSupervisor.resumeFocusedStackTopActivityLocked();
499 }
500 } finally {
501 Binder.restoreCallingIdentity(orig);
502 }
503 }
Andrew Sapperstein5b679c42018-01-16 11:13:40 -0800504 if (res == AppErrorDialog.APP_INFO) {
505 appErrorIntent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
506 appErrorIntent.setData(Uri.parse("package:" + r.info.packageName));
507 appErrorIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
508 }
Andrii Kulianfa3991a2016-04-28 14:18:37 -0700509 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
510 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
511 }
512 if (r != null && !r.isolated && res != AppErrorDialog.RESTART) {
513 // XXX Can't keep track of crash time for isolated processes,
514 // since they don't have a persistent identity.
515 mProcessCrashTimes.put(r.info.processName, r.uid,
516 SystemClock.uptimeMillis());
517 }
Adrian Roos20d7df32016-01-12 18:59:43 +0100518 }
519
520 if (appErrorIntent != null) {
521 try {
522 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
523 } catch (ActivityNotFoundException e) {
524 Slog.w(TAG, "bug report receiver dissappeared", e);
525 }
526 }
527 }
528
Andrii Kulianfa3991a2016-04-28 14:18:37 -0700529 private boolean handleAppCrashInActivityController(ProcessRecord r,
530 ApplicationErrorReport.CrashInfo crashInfo,
531 String shortMsg, String longMsg,
Mark Lub5e24992016-11-21 15:38:13 +0800532 String stackTrace, long timeMillis,
533 int callingPid, int callingUid) {
Andrii Kulianfa3991a2016-04-28 14:18:37 -0700534 if (mService.mController == null) {
535 return false;
536 }
537
538 try {
539 String name = r != null ? r.processName : null;
Mark Lub5e24992016-11-21 15:38:13 +0800540 int pid = r != null ? r.pid : callingPid;
541 int uid = r != null ? r.info.uid : callingUid;
Andrii Kulianfa3991a2016-04-28 14:18:37 -0700542 if (!mService.mController.appCrashed(name, pid,
543 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
544 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
545 && "Native crash".equals(crashInfo.exceptionClassName)) {
546 Slog.w(TAG, "Skip killing native crashed app " + name
547 + "(" + pid + ") during testing");
548 } else {
549 Slog.w(TAG, "Force-killing crashed app " + name
550 + " at watcher's request");
551 if (r != null) {
552 if (!makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace, null))
553 {
554 r.kill("crash", true);
555 }
556 } else {
557 // Huh.
558 Process.killProcess(pid);
559 ActivityManagerService.killProcessGroup(uid, pid);
560 }
561 }
562 return true;
563 }
564 } catch (RemoteException e) {
565 mService.mController = null;
566 Watchdog.getInstance().setActivityController(null);
567 }
568 return false;
569 }
570
Adrian Roos20d7df32016-01-12 18:59:43 +0100571 private boolean makeAppCrashingLocked(ProcessRecord app,
572 String shortMsg, String longMsg, String stackTrace, AppErrorDialog.Data data) {
573 app.crashing = true;
574 app.crashingReport = generateProcessError(app,
575 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
576 startAppProblemLocked(app);
577 app.stopFreezingAllLocked();
578 return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace,
579 data);
580 }
581
582 void startAppProblemLocked(ProcessRecord app) {
583 // If this app is not running under the current user, then we
584 // can't give it a report button because that would require
585 // launching the report UI under a different user.
586 app.errorReportReceiver = null;
587
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700588 for (int userId : mService.mUserController.getCurrentProfileIds()) {
Adrian Roos20d7df32016-01-12 18:59:43 +0100589 if (app.userId == userId) {
590 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
591 mContext, app.info.packageName, app.info.flags);
592 }
593 }
594 mService.skipCurrentReceiverLocked(app);
595 }
596
597 /**
598 * Generate a process error record, suitable for attachment to a ProcessRecord.
599 *
600 * @param app The ProcessRecord in which the error occurred.
601 * @param condition Crashing, Application Not Responding, etc. Values are defined in
Sudheer Shankaf6690102017-10-16 10:20:32 -0700602 * ActivityManager.ProcessErrorStateInfo
Adrian Roos20d7df32016-01-12 18:59:43 +0100603 * @param activity The activity associated with the crash, if known.
604 * @param shortMsg Short message describing the crash.
605 * @param longMsg Long message describing the crash.
606 * @param stackTrace Full crash stack trace, may be null.
607 *
Sudheer Shankaf6690102017-10-16 10:20:32 -0700608 * @return Returns a fully-formed ProcessErrorStateInfo record.
Adrian Roos20d7df32016-01-12 18:59:43 +0100609 */
610 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
611 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
612 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
613
614 report.condition = condition;
615 report.processName = app.processName;
616 report.pid = app.pid;
617 report.uid = app.info.uid;
618 report.tag = activity;
619 report.shortMsg = shortMsg;
620 report.longMsg = longMsg;
621 report.stackTrace = stackTrace;
622
623 return report;
624 }
625
626 Intent createAppErrorIntentLocked(ProcessRecord r,
627 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
628 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
629 if (report == null) {
630 return null;
631 }
632 Intent result = new Intent(Intent.ACTION_APP_ERROR);
633 result.setComponent(r.errorReportReceiver);
634 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
635 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
636 return result;
637 }
638
639 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
640 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
641 if (r.errorReportReceiver == null) {
642 return null;
643 }
644
645 if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
646 return null;
647 }
648
649 ApplicationErrorReport report = new ApplicationErrorReport();
650 report.packageName = r.info.packageName;
651 report.installerPackageName = r.errorReportReceiver.getPackageName();
652 report.processName = r.processName;
653 report.time = timeMillis;
654 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
655
656 if (r.crashing || r.forceCrashReport) {
657 report.type = ApplicationErrorReport.TYPE_CRASH;
658 report.crashInfo = crashInfo;
659 } else if (r.notResponding) {
660 report.type = ApplicationErrorReport.TYPE_ANR;
661 report.anrInfo = new ApplicationErrorReport.AnrInfo();
662
663 report.anrInfo.activity = r.notRespondingReport.tag;
664 report.anrInfo.cause = r.notRespondingReport.shortMsg;
665 report.anrInfo.info = r.notRespondingReport.longMsg;
666 }
667
668 return report;
669 }
670
671 boolean handleAppCrashLocked(ProcessRecord app, String reason,
672 String shortMsg, String longMsg, String stackTrace, AppErrorDialog.Data data) {
Amith Yamasanib0c8a882017-08-28 09:36:42 -0700673 final long now = SystemClock.uptimeMillis();
674 final boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
Adrian Roos6a7e0892016-08-23 14:26:39 +0200675 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
Adrian Roos20d7df32016-01-12 18:59:43 +0100676
Amith Yamasanib0c8a882017-08-28 09:36:42 -0700677 final boolean procIsBoundForeground =
678 (app.curProcState == ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
679
Adrian Roos20d7df32016-01-12 18:59:43 +0100680 Long crashTime;
681 Long crashTimePersistent;
Amith Yamasanib0c8a882017-08-28 09:36:42 -0700682 boolean tryAgain = false;
683
Adrian Roos20d7df32016-01-12 18:59:43 +0100684 if (!app.isolated) {
685 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
686 crashTimePersistent = mProcessCrashTimesPersistent.get(app.info.processName, app.uid);
687 } else {
688 crashTime = crashTimePersistent = null;
689 }
Amith Yamasanib0c8a882017-08-28 09:36:42 -0700690
691 // Bump up the crash count of any services currently running in the proc.
692 for (int i = app.services.size() - 1; i >= 0; i--) {
693 // Any services running in the application need to be placed
694 // back in the pending list.
695 ServiceRecord sr = app.services.valueAt(i);
696 // If the service was restarted a while ago, then reset crash count, else increment it.
697 if (now > sr.restartTime + ProcessList.MIN_CRASH_INTERVAL) {
698 sr.crashCount = 1;
699 } else {
700 sr.crashCount++;
701 }
702 // Allow restarting for started or bound foreground services that are crashing.
703 // This includes wallpapers.
704 if (sr.crashCount < mService.mConstants.BOUND_SERVICE_MAX_CRASH_RETRY
705 && (sr.isForeground || procIsBoundForeground)) {
706 tryAgain = true;
707 }
708 }
709
710 if (crashTime != null && now < crashTime + ProcessList.MIN_CRASH_INTERVAL) {
711 // The process crashed again very quickly. If it was a bound foreground service, let's
712 // try to restart again in a while, otherwise the process loses!
Adrian Roos20d7df32016-01-12 18:59:43 +0100713 Slog.w(TAG, "Process " + app.info.processName
714 + " has crashed too many times: killing!");
715 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
716 app.userId, app.info.processName, app.uid);
717 mService.mStackSupervisor.handleAppCrashLocked(app);
718 if (!app.persistent) {
719 // We don't want to start this process again until the user
720 // explicitly does so... but for persistent process, we really
721 // need to keep it running. If a persistent process is actually
722 // repeatedly crashing, then badness for everyone.
723 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
724 app.info.processName);
725 if (!app.isolated) {
726 // XXX We don't have a way to mark isolated processes
727 // as bad, since they don't have a peristent identity.
728 mBadProcesses.put(app.info.processName, app.uid,
729 new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
730 mProcessCrashTimes.remove(app.info.processName, app.uid);
731 }
732 app.bad = true;
733 app.removed = true;
734 // Don't let services in this process be restarted and potentially
735 // annoy the user repeatedly. Unless it is persistent, since those
736 // processes run critical code.
Amith Yamasanib0c8a882017-08-28 09:36:42 -0700737 mService.removeProcessLocked(app, false, tryAgain, "crash");
Adrian Roos20d7df32016-01-12 18:59:43 +0100738 mService.mStackSupervisor.resumeFocusedStackTopActivityLocked();
Adrian Roos6a7e0892016-08-23 14:26:39 +0200739 if (!showBackground) {
740 return false;
741 }
Adrian Roos20d7df32016-01-12 18:59:43 +0100742 }
743 mService.mStackSupervisor.resumeFocusedStackTopActivityLocked();
744 } else {
745 TaskRecord affectedTask =
746 mService.mStackSupervisor.finishTopRunningActivityLocked(app, reason);
747 if (data != null) {
748 data.task = affectedTask;
749 }
750 if (data != null && crashTimePersistent != null
751 && now < crashTimePersistent + ProcessList.MIN_CRASH_INTERVAL) {
752 data.repeating = true;
753 }
754 }
755
Amith Yamasanib0c8a882017-08-28 09:36:42 -0700756 if (data != null && tryAgain) {
757 data.isRestartableForService = true;
Adrian Roos20d7df32016-01-12 18:59:43 +0100758 }
759
760 // If the crashing process is what we consider to be the "home process" and it has been
761 // replaced by a third-party app, clear the package preferred activities from packages
762 // with a home activity running in the process to prevent a repeatedly crashing app
763 // from blocking the user to manually clear the list.
764 final ArrayList<ActivityRecord> activities = app.activities;
765 if (app == mService.mHomeProcess && activities.size() > 0
766 && (mService.mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
767 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
768 final ActivityRecord r = activities.get(activityNdx);
Wale Ogunwale6fbde9f2017-08-24 07:24:12 -0700769 if (r.isActivityTypeHome()) {
Adrian Roos20d7df32016-01-12 18:59:43 +0100770 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
771 try {
772 ActivityThread.getPackageManager()
773 .clearPackagePreferredActivities(r.packageName);
774 } catch (RemoteException c) {
775 // pm is in same process, this will never happen.
776 }
777 }
778 }
779 }
780
781 if (!app.isolated) {
782 // XXX Can't keep track of crash times for isolated processes,
Amith Yamasanib0c8a882017-08-28 09:36:42 -0700783 // because they don't have a persistent identity.
Adrian Roos20d7df32016-01-12 18:59:43 +0100784 mProcessCrashTimes.put(app.info.processName, app.uid, now);
785 mProcessCrashTimesPersistent.put(app.info.processName, app.uid, now);
786 }
787
788 if (app.crashHandler != null) mService.mHandler.post(app.crashHandler);
789 return true;
790 }
791
792 void handleShowAppErrorUi(Message msg) {
793 AppErrorDialog.Data data = (AppErrorDialog.Data) msg.obj;
794 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
795 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
796 synchronized (mService) {
797 ProcessRecord proc = data.proc;
798 AppErrorResult res = data.result;
799 if (proc != null && proc.crashDialog != null) {
800 Slog.e(TAG, "App already has crash dialog: " + proc);
801 if (res != null) {
Adrian Roos90462222016-02-17 15:45:09 -0800802 res.set(AppErrorDialog.ALREADY_SHOWING);
Adrian Roos20d7df32016-01-12 18:59:43 +0100803 }
804 return;
805 }
806 boolean isBackground = (UserHandle.getAppId(proc.uid)
807 >= Process.FIRST_APPLICATION_UID
808 && proc.pid != MY_PID);
Fyodor Kupolov1b3edac2017-09-19 15:48:06 -0700809 for (int userId : mService.mUserController.getCurrentProfileIds()) {
Adrian Roos20d7df32016-01-12 18:59:43 +0100810 isBackground &= (proc.userId != userId);
811 }
812 if (isBackground && !showBackground) {
813 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
814 if (res != null) {
Adrian Roos90462222016-02-17 15:45:09 -0800815 res.set(AppErrorDialog.BACKGROUND_USER);
Adrian Roos20d7df32016-01-12 18:59:43 +0100816 }
817 return;
818 }
Andrew Sapperstein43643ae2017-12-20 15:17:33 -0800819 final boolean showFirstCrash = Settings.Global.getInt(
820 mContext.getContentResolver(),
821 Settings.Global.SHOW_FIRST_CRASH_DIALOG, 0) != 0;
822 final boolean showFirstCrashDevOption = Settings.Secure.getIntForUser(
823 mContext.getContentResolver(),
824 Settings.Secure.SHOW_FIRST_CRASH_DIALOG_DEV_OPTION,
825 0,
Andrew Sappersteinfd5238c2018-01-21 09:45:05 -0800826 mService.mUserController.getCurrentUserId()) != 0;
Adrian Roos20d7df32016-01-12 18:59:43 +0100827 final boolean crashSilenced = mAppsNotReportingCrashes != null &&
828 mAppsNotReportingCrashes.contains(proc.info.packageName);
Andrew Sapperstein43643ae2017-12-20 15:17:33 -0800829 if ((mService.canShowErrorDialogs() || showBackground) && !crashSilenced
830 && (showFirstCrash || showFirstCrashDevOption || data.repeating)) {
Phil Weaver445fd2a2016-03-17 17:26:24 -0700831 proc.crashDialog = new AppErrorDialog(mContext, mService, data);
Adrian Roos20d7df32016-01-12 18:59:43 +0100832 } else {
833 // The device is asleep, so just pretend that the user
834 // saw a crash dialog and hit "force quit".
835 if (res != null) {
Adrian Roos90462222016-02-17 15:45:09 -0800836 res.set(AppErrorDialog.CANT_SHOW);
Adrian Roos20d7df32016-01-12 18:59:43 +0100837 }
838 }
839 }
Phil Weaver445fd2a2016-03-17 17:26:24 -0700840 // If we've created a crash dialog, show it without the lock held
841 if(data.proc.crashDialog != null) {
Fyodor Kupolov5ddcca72017-04-28 17:38:10 -0700842 Slog.i(TAG, "Showing crash dialog for package " + data.proc.info.packageName
843 + " u" + data.proc.userId);
Phil Weaver445fd2a2016-03-17 17:26:24 -0700844 data.proc.crashDialog.show();
845 }
Adrian Roos20d7df32016-01-12 18:59:43 +0100846 }
847
848 void stopReportingCrashesLocked(ProcessRecord proc) {
849 if (mAppsNotReportingCrashes == null) {
850 mAppsNotReportingCrashes = new ArraySet<>();
851 }
852 mAppsNotReportingCrashes.add(proc.info.packageName);
853 }
854
Narayan Kamatha22d9fb2017-04-26 15:14:26 +0100855 static boolean isInterestingForBackgroundTraces(ProcessRecord app) {
856 // The system_server is always considered interesting.
857 if (app.pid == MY_PID) {
858 return true;
859 }
860
861 // A package is considered interesting if any of the following is true :
862 //
863 // - It's displaying an activity.
864 // - It's the SystemUI.
865 // - It has an overlay or a top UI visible.
866 //
867 // NOTE: The check whether a given ProcessRecord belongs to the systemui
868 // process is a bit of a kludge, but the same pattern seems repeated at
869 // several places in the system server.
870 return app.isInterestingToUserLocked() ||
871 (app.info != null && "com.android.systemui".equals(app.info.packageName)) ||
872 (app.hasTopUi || app.hasOverlayUi);
873 }
874
Adrian Roos20d7df32016-01-12 18:59:43 +0100875 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
876 ActivityRecord parent, boolean aboveSystem, final String annotation) {
877 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
878 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
879
880 if (mService.mController != null) {
881 try {
882 // 0 == continue, -1 = kill process immediately
Adrian Roosa85a2c62016-01-26 09:14:22 -0800883 int res = mService.mController.appEarlyNotResponding(
884 app.processName, app.pid, annotation);
Adrian Roos20d7df32016-01-12 18:59:43 +0100885 if (res < 0 && app.pid != MY_PID) {
886 app.kill("anr", true);
887 }
888 } catch (RemoteException e) {
889 mService.mController = null;
890 Watchdog.getInstance().setActivityController(null);
891 }
892 }
893
894 long anrTime = SystemClock.uptimeMillis();
895 if (ActivityManagerService.MONITOR_CPU_USAGE) {
896 mService.updateCpuStatsNow();
897 }
898
Tim Murrayf0f9a822016-07-13 13:33:28 -0700899 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
900 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
901 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
902
903 boolean isSilentANR;
904
Adrian Roos20d7df32016-01-12 18:59:43 +0100905 synchronized (mService) {
906 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
907 if (mService.mShuttingDown) {
908 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
909 return;
910 } else if (app.notResponding) {
911 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
912 return;
913 } else if (app.crashing) {
914 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
915 return;
Tobias Lindskog313177d2015-02-03 11:45:58 +0100916 } else if (app.killedByAm) {
917 Slog.i(TAG, "App already killed by AM skipping ANR: " + app + " " + annotation);
918 return;
Mark Lu41d65f22016-03-23 19:08:44 +0800919 } else if (app.killed) {
920 Slog.i(TAG, "Skipping died app ANR: " + app + " " + annotation);
921 return;
Adrian Roos20d7df32016-01-12 18:59:43 +0100922 }
923
924 // In case we come through here for the same app before completing
925 // this one, mark as anring now so we will bail out.
926 app.notResponding = true;
927
928 // Log the ANR to the event log.
929 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
930 app.processName, app.info.flags, annotation);
931
932 // Dump thread traces as quickly as we can, starting with "interesting" processes.
933 firstPids.add(app.pid);
934
Tim Murrayf0f9a822016-07-13 13:33:28 -0700935 // Don't dump other PIDs if it's a background ANR
Narayan Kamatha22d9fb2017-04-26 15:14:26 +0100936 isSilentANR = !showBackground && !isInterestingForBackgroundTraces(app);
Tim Murrayf0f9a822016-07-13 13:33:28 -0700937 if (!isSilentANR) {
938 int parentPid = app.pid;
939 if (parent != null && parent.app != null && parent.app.pid > 0) {
940 parentPid = parent.app.pid;
941 }
942 if (parentPid != app.pid) firstPids.add(parentPid);
Adrian Roos20d7df32016-01-12 18:59:43 +0100943
Tim Murrayf0f9a822016-07-13 13:33:28 -0700944 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
Adrian Roos20d7df32016-01-12 18:59:43 +0100945
Tim Murrayf0f9a822016-07-13 13:33:28 -0700946 for (int i = mService.mLruProcesses.size() - 1; i >= 0; i--) {
947 ProcessRecord r = mService.mLruProcesses.get(i);
948 if (r != null && r.thread != null) {
949 int pid = r.pid;
950 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
951 if (r.persistent) {
952 firstPids.add(pid);
953 if (DEBUG_ANR) Slog.i(TAG, "Adding persistent proc: " + r);
Brian Carlstrom90d1e362017-03-29 20:25:57 -0700954 } else if (r.treatLikeActivity) {
955 firstPids.add(pid);
956 if (DEBUG_ANR) Slog.i(TAG, "Adding likely IME: " + r);
Tim Murrayf0f9a822016-07-13 13:33:28 -0700957 } else {
958 lastPids.put(pid, Boolean.TRUE);
959 if (DEBUG_ANR) Slog.i(TAG, "Adding ANR proc: " + r);
960 }
Adrian Roos20d7df32016-01-12 18:59:43 +0100961 }
962 }
963 }
964 }
965 }
966
967 // Log the ANR to the main log.
968 StringBuilder info = new StringBuilder();
969 info.setLength(0);
970 info.append("ANR in ").append(app.processName);
971 if (activity != null && activity.shortComponentName != null) {
972 info.append(" (").append(activity.shortComponentName).append(")");
973 }
974 info.append("\n");
975 info.append("PID: ").append(app.pid).append("\n");
976 if (annotation != null) {
977 info.append("Reason: ").append(annotation).append("\n");
978 }
979 if (parent != null && parent != activity) {
980 info.append("Parent: ").append(parent.shortComponentName).append("\n");
981 }
982
Tim Murrayf0f9a822016-07-13 13:33:28 -0700983 ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
Adrian Roos20d7df32016-01-12 18:59:43 +0100984
Brian Carlstrom66524242017-03-11 00:14:13 -0800985 // don't dump native PIDs for background ANRs unless it is the process of interest
986 String[] nativeProcs = null;
Tim Murrayf0f9a822016-07-13 13:33:28 -0700987 if (isSilentANR) {
Brian Carlstrom66524242017-03-11 00:14:13 -0800988 for (int i = 0; i < NATIVE_STACKS_OF_INTEREST.length; i++) {
989 if (NATIVE_STACKS_OF_INTEREST[i].equals(app.processName)) {
990 nativeProcs = new String[] { app.processName };
991 break;
992 }
993 }
Tim Murrayf0f9a822016-07-13 13:33:28 -0700994 } else {
Brian Carlstrom66524242017-03-11 00:14:13 -0800995 nativeProcs = NATIVE_STACKS_OF_INTEREST;
Tim Murrayf0f9a822016-07-13 13:33:28 -0700996 }
Adrian Roos20d7df32016-01-12 18:59:43 +0100997
Martijn Coenen94a0dcd2017-03-27 12:45:19 -0700998 int[] pids = nativeProcs == null ? null : Process.getPidsForCommands(nativeProcs);
Steven Moreland6b47c542017-03-21 12:52:16 -0700999 ArrayList<Integer> nativePids = null;
1000
1001 if (pids != null) {
1002 nativePids = new ArrayList<Integer>(pids.length);
1003 for (int i : pids) {
1004 nativePids.add(i);
1005 }
1006 }
1007
Brian Carlstrom66524242017-03-11 00:14:13 -08001008 // For background ANRs, don't pass the ProcessCpuTracker to
1009 // avoid spending 1/2 second collecting stats to rank lastPids.
Narayan Kamathf013daa2017-05-09 12:55:02 +01001010 File tracesFile = ActivityManagerService.dumpStackTraces(
1011 true, firstPids,
1012 (isSilentANR) ? null : processCpuTracker,
1013 (isSilentANR) ? null : lastPids,
1014 nativePids);
Brian Carlstrom66524242017-03-11 00:14:13 -08001015
Adrian Roos20d7df32016-01-12 18:59:43 +01001016 String cpuInfo = null;
1017 if (ActivityManagerService.MONITOR_CPU_USAGE) {
1018 mService.updateCpuStatsNow();
1019 synchronized (mService.mProcessCpuTracker) {
1020 cpuInfo = mService.mProcessCpuTracker.printCurrentState(anrTime);
1021 }
1022 info.append(processCpuTracker.printCurrentLoad());
1023 info.append(cpuInfo);
1024 }
1025
1026 info.append(processCpuTracker.printCurrentState(anrTime));
1027
1028 Slog.e(TAG, info.toString());
1029 if (tracesFile == null) {
1030 // There is no trace file, so dump (only) the alleged culprit's threads to the log
1031 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
1032 }
1033
1034 mService.addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
1035 cpuInfo, tracesFile, null);
1036
1037 if (mService.mController != null) {
1038 try {
1039 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
1040 int res = mService.mController.appNotResponding(
1041 app.processName, app.pid, info.toString());
1042 if (res != 0) {
1043 if (res < 0 && app.pid != MY_PID) {
1044 app.kill("anr", true);
1045 } else {
1046 synchronized (mService) {
1047 mService.mServices.scheduleServiceTimeoutLocked(app);
1048 }
1049 }
1050 return;
1051 }
1052 } catch (RemoteException e) {
1053 mService.mController = null;
1054 Watchdog.getInstance().setActivityController(null);
1055 }
1056 }
1057
Adrian Roos20d7df32016-01-12 18:59:43 +01001058 synchronized (mService) {
1059 mService.mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
1060
Tim Murrayf0f9a822016-07-13 13:33:28 -07001061 if (isSilentANR) {
Adrian Roos20d7df32016-01-12 18:59:43 +01001062 app.kill("bg anr", true);
1063 return;
1064 }
1065
1066 // Set the app's notResponding state, and look up the errorReportReceiver
1067 makeAppNotRespondingLocked(app,
1068 activity != null ? activity.shortComponentName : null,
1069 annotation != null ? "ANR " + annotation : "ANR",
1070 info.toString());
1071
1072 // Bring up the infamous App Not Responding dialog
1073 Message msg = Message.obtain();
1074 HashMap<String, Object> map = new HashMap<String, Object>();
1075 msg.what = ActivityManagerService.SHOW_NOT_RESPONDING_UI_MSG;
1076 msg.obj = map;
1077 msg.arg1 = aboveSystem ? 1 : 0;
1078 map.put("app", app);
1079 if (activity != null) {
1080 map.put("activity", activity);
1081 }
1082
1083 mService.mUiHandler.sendMessage(msg);
1084 }
1085 }
1086
1087 private void makeAppNotRespondingLocked(ProcessRecord app,
1088 String activity, String shortMsg, String longMsg) {
1089 app.notResponding = true;
1090 app.notRespondingReport = generateProcessError(app,
1091 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
1092 activity, shortMsg, longMsg, null);
1093 startAppProblemLocked(app);
1094 app.stopFreezingAllLocked();
1095 }
1096
1097 void handleShowAnrUi(Message msg) {
Phil Weaver445fd2a2016-03-17 17:26:24 -07001098 Dialog d = null;
Adrian Roos20d7df32016-01-12 18:59:43 +01001099 synchronized (mService) {
1100 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1101 ProcessRecord proc = (ProcessRecord)data.get("app");
1102 if (proc != null && proc.anrDialog != null) {
1103 Slog.e(TAG, "App already has anr dialog: " + proc);
Adrian Roos90462222016-02-17 15:45:09 -08001104 MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_ANR,
1105 AppNotRespondingDialog.ALREADY_SHOWING);
Adrian Roos20d7df32016-01-12 18:59:43 +01001106 return;
1107 }
1108
1109 Intent intent = new Intent("android.intent.action.ANR");
1110 if (!mService.mProcessesReady) {
1111 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1112 | Intent.FLAG_RECEIVER_FOREGROUND);
1113 }
1114 mService.broadcastIntentLocked(null, null, intent,
1115 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1116 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1117
Adrian Roos6a7e0892016-08-23 14:26:39 +02001118 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1119 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1120 if (mService.canShowErrorDialogs() || showBackground) {
Phil Weaver445fd2a2016-03-17 17:26:24 -07001121 d = new AppNotRespondingDialog(mService,
Adrian Roos20d7df32016-01-12 18:59:43 +01001122 mContext, proc, (ActivityRecord)data.get("activity"),
1123 msg.arg1 != 0);
Adrian Roos20d7df32016-01-12 18:59:43 +01001124 proc.anrDialog = d;
1125 } else {
Adrian Roos90462222016-02-17 15:45:09 -08001126 MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_ANR,
1127 AppNotRespondingDialog.CANT_SHOW);
Adrian Roos20d7df32016-01-12 18:59:43 +01001128 // Just kill the app if there is no dialog to be shown.
1129 mService.killAppAtUsersRequest(proc, null);
1130 }
1131 }
Phil Weaver445fd2a2016-03-17 17:26:24 -07001132 // If we've created a crash dialog, show it without the lock held
1133 if (d != null) {
1134 d.show();
1135 }
Adrian Roos20d7df32016-01-12 18:59:43 +01001136 }
1137
1138 /**
1139 * Information about a process that is currently marked as bad.
1140 */
1141 static final class BadProcessInfo {
1142 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
1143 this.time = time;
1144 this.shortMsg = shortMsg;
1145 this.longMsg = longMsg;
1146 this.stack = stack;
1147 }
1148
1149 final long time;
1150 final String shortMsg;
1151 final String longMsg;
1152 final String stack;
1153 }
1154
1155}