blob: bd1000ac568cac9bcab37983449f04ef01d16245 [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;
25
Adrian Roos20d7df32016-01-12 18:59:43 +010026import android.app.ActivityManager;
27import android.app.ActivityOptions;
28import android.app.ActivityThread;
29import android.app.AppOpsManager;
30import android.app.ApplicationErrorReport;
31import android.app.Dialog;
32import android.content.ActivityNotFoundException;
33import android.content.Context;
34import android.content.Intent;
35import android.content.pm.ApplicationInfo;
Andrew Sapperstein5b679c42018-01-16 11:13:40 -080036import android.net.Uri;
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;
Chenjie Yu5caaa9d2018-03-06 15:48:54 -080050import android.util.StatsLog;
Adrian Roos20d7df32016-01-12 18:59:43 +010051import 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 {
Andrii Kulian8cc92ac62018-04-02 23:14:18 -0700745 final TaskRecord affectedTask =
746 mService.mStackSupervisor.finishTopCrashedActivitiesLocked(app, reason);
Adrian Roos20d7df32016-01-12 18:59:43 +0100747 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;
Adrian Roosc3a06e52018-02-16 18:33:17 +0100796
797 AppErrorDialog dialogToShow = null;
798 final String packageName;
799 final int userId;
Adrian Roos20d7df32016-01-12 18:59:43 +0100800 synchronized (mService) {
Adrian Roosc3a06e52018-02-16 18:33:17 +0100801 final ProcessRecord proc = data.proc;
802 final AppErrorResult res = data.result;
803 if (proc == null) {
804 Slog.e(TAG, "handleShowAppErrorUi: proc is null");
805 return;
806 }
807 packageName = proc.info.packageName;
808 userId = proc.userId;
809 if (proc.crashDialog != null) {
Adrian Roos20d7df32016-01-12 18:59:43 +0100810 Slog.e(TAG, "App already has crash dialog: " + proc);
811 if (res != null) {
Adrian Roos90462222016-02-17 15:45:09 -0800812 res.set(AppErrorDialog.ALREADY_SHOWING);
Adrian Roos20d7df32016-01-12 18:59:43 +0100813 }
814 return;
815 }
816 boolean isBackground = (UserHandle.getAppId(proc.uid)
817 >= Process.FIRST_APPLICATION_UID
818 && proc.pid != MY_PID);
Adrian Roosc3a06e52018-02-16 18:33:17 +0100819 for (int profileId : mService.mUserController.getCurrentProfileIds()) {
820 isBackground &= (userId != profileId);
Adrian Roos20d7df32016-01-12 18:59:43 +0100821 }
822 if (isBackground && !showBackground) {
823 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
824 if (res != null) {
Adrian Roos90462222016-02-17 15:45:09 -0800825 res.set(AppErrorDialog.BACKGROUND_USER);
Adrian Roos20d7df32016-01-12 18:59:43 +0100826 }
827 return;
828 }
Andrew Sapperstein43643ae2017-12-20 15:17:33 -0800829 final boolean showFirstCrash = Settings.Global.getInt(
830 mContext.getContentResolver(),
831 Settings.Global.SHOW_FIRST_CRASH_DIALOG, 0) != 0;
832 final boolean showFirstCrashDevOption = Settings.Secure.getIntForUser(
833 mContext.getContentResolver(),
834 Settings.Secure.SHOW_FIRST_CRASH_DIALOG_DEV_OPTION,
835 0,
Andrew Sappersteinfd5238c2018-01-21 09:45:05 -0800836 mService.mUserController.getCurrentUserId()) != 0;
Adrian Roos20d7df32016-01-12 18:59:43 +0100837 final boolean crashSilenced = mAppsNotReportingCrashes != null &&
838 mAppsNotReportingCrashes.contains(proc.info.packageName);
Andrew Sapperstein43643ae2017-12-20 15:17:33 -0800839 if ((mService.canShowErrorDialogs() || showBackground) && !crashSilenced
840 && (showFirstCrash || showFirstCrashDevOption || data.repeating)) {
Adrian Roosc3a06e52018-02-16 18:33:17 +0100841 proc.crashDialog = dialogToShow = new AppErrorDialog(mContext, mService, data);
Adrian Roos20d7df32016-01-12 18:59:43 +0100842 } else {
843 // The device is asleep, so just pretend that the user
844 // saw a crash dialog and hit "force quit".
845 if (res != null) {
Adrian Roos90462222016-02-17 15:45:09 -0800846 res.set(AppErrorDialog.CANT_SHOW);
Adrian Roos20d7df32016-01-12 18:59:43 +0100847 }
848 }
849 }
Phil Weaver445fd2a2016-03-17 17:26:24 -0700850 // If we've created a crash dialog, show it without the lock held
Adrian Roosc3a06e52018-02-16 18:33:17 +0100851 if (dialogToShow != null) {
852 Slog.i(TAG, "Showing crash dialog for package " + packageName + " u" + userId);
853 dialogToShow.show();
Phil Weaver445fd2a2016-03-17 17:26:24 -0700854 }
Adrian Roos20d7df32016-01-12 18:59:43 +0100855 }
856
857 void stopReportingCrashesLocked(ProcessRecord proc) {
858 if (mAppsNotReportingCrashes == null) {
859 mAppsNotReportingCrashes = new ArraySet<>();
860 }
861 mAppsNotReportingCrashes.add(proc.info.packageName);
862 }
863
Narayan Kamatha22d9fb2017-04-26 15:14:26 +0100864 static boolean isInterestingForBackgroundTraces(ProcessRecord app) {
865 // The system_server is always considered interesting.
866 if (app.pid == MY_PID) {
867 return true;
868 }
869
870 // A package is considered interesting if any of the following is true :
871 //
872 // - It's displaying an activity.
873 // - It's the SystemUI.
874 // - It has an overlay or a top UI visible.
875 //
876 // NOTE: The check whether a given ProcessRecord belongs to the systemui
877 // process is a bit of a kludge, but the same pattern seems repeated at
878 // several places in the system server.
879 return app.isInterestingToUserLocked() ||
880 (app.info != null && "com.android.systemui".equals(app.info.packageName)) ||
881 (app.hasTopUi || app.hasOverlayUi);
882 }
883
Adrian Roos20d7df32016-01-12 18:59:43 +0100884 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
885 ActivityRecord parent, boolean aboveSystem, final String annotation) {
886 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
887 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
888
889 if (mService.mController != null) {
890 try {
891 // 0 == continue, -1 = kill process immediately
Adrian Roosa85a2c62016-01-26 09:14:22 -0800892 int res = mService.mController.appEarlyNotResponding(
893 app.processName, app.pid, annotation);
Adrian Roos20d7df32016-01-12 18:59:43 +0100894 if (res < 0 && app.pid != MY_PID) {
895 app.kill("anr", true);
896 }
897 } catch (RemoteException e) {
898 mService.mController = null;
899 Watchdog.getInstance().setActivityController(null);
900 }
901 }
902
903 long anrTime = SystemClock.uptimeMillis();
904 if (ActivityManagerService.MONITOR_CPU_USAGE) {
905 mService.updateCpuStatsNow();
906 }
907
Tim Murrayf0f9a822016-07-13 13:33:28 -0700908 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
909 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
910 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
911
912 boolean isSilentANR;
913
Adrian Roos20d7df32016-01-12 18:59:43 +0100914 synchronized (mService) {
915 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
916 if (mService.mShuttingDown) {
917 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
918 return;
919 } else if (app.notResponding) {
920 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
921 return;
922 } else if (app.crashing) {
923 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
924 return;
Tobias Lindskog313177d2015-02-03 11:45:58 +0100925 } else if (app.killedByAm) {
926 Slog.i(TAG, "App already killed by AM skipping ANR: " + app + " " + annotation);
927 return;
Mark Lu41d65f22016-03-23 19:08:44 +0800928 } else if (app.killed) {
929 Slog.i(TAG, "Skipping died app ANR: " + app + " " + annotation);
930 return;
Adrian Roos20d7df32016-01-12 18:59:43 +0100931 }
932
933 // In case we come through here for the same app before completing
934 // this one, mark as anring now so we will bail out.
935 app.notResponding = true;
936
937 // Log the ANR to the event log.
938 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
939 app.processName, app.info.flags, annotation);
940
941 // Dump thread traces as quickly as we can, starting with "interesting" processes.
942 firstPids.add(app.pid);
943
Tim Murrayf0f9a822016-07-13 13:33:28 -0700944 // Don't dump other PIDs if it's a background ANR
Narayan Kamatha22d9fb2017-04-26 15:14:26 +0100945 isSilentANR = !showBackground && !isInterestingForBackgroundTraces(app);
Tim Murrayf0f9a822016-07-13 13:33:28 -0700946 if (!isSilentANR) {
947 int parentPid = app.pid;
948 if (parent != null && parent.app != null && parent.app.pid > 0) {
949 parentPid = parent.app.pid;
950 }
951 if (parentPid != app.pid) firstPids.add(parentPid);
Adrian Roos20d7df32016-01-12 18:59:43 +0100952
Tim Murrayf0f9a822016-07-13 13:33:28 -0700953 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
Adrian Roos20d7df32016-01-12 18:59:43 +0100954
Tim Murrayf0f9a822016-07-13 13:33:28 -0700955 for (int i = mService.mLruProcesses.size() - 1; i >= 0; i--) {
956 ProcessRecord r = mService.mLruProcesses.get(i);
957 if (r != null && r.thread != null) {
958 int pid = r.pid;
959 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
960 if (r.persistent) {
961 firstPids.add(pid);
962 if (DEBUG_ANR) Slog.i(TAG, "Adding persistent proc: " + r);
Brian Carlstrom90d1e362017-03-29 20:25:57 -0700963 } else if (r.treatLikeActivity) {
964 firstPids.add(pid);
965 if (DEBUG_ANR) Slog.i(TAG, "Adding likely IME: " + r);
Tim Murrayf0f9a822016-07-13 13:33:28 -0700966 } else {
967 lastPids.put(pid, Boolean.TRUE);
968 if (DEBUG_ANR) Slog.i(TAG, "Adding ANR proc: " + r);
969 }
Adrian Roos20d7df32016-01-12 18:59:43 +0100970 }
971 }
972 }
973 }
974 }
975
976 // Log the ANR to the main log.
977 StringBuilder info = new StringBuilder();
978 info.setLength(0);
979 info.append("ANR in ").append(app.processName);
980 if (activity != null && activity.shortComponentName != null) {
981 info.append(" (").append(activity.shortComponentName).append(")");
982 }
983 info.append("\n");
984 info.append("PID: ").append(app.pid).append("\n");
985 if (annotation != null) {
986 info.append("Reason: ").append(annotation).append("\n");
987 }
988 if (parent != null && parent != activity) {
989 info.append("Parent: ").append(parent.shortComponentName).append("\n");
990 }
991
Tim Murrayf0f9a822016-07-13 13:33:28 -0700992 ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
Adrian Roos20d7df32016-01-12 18:59:43 +0100993
Brian Carlstrom66524242017-03-11 00:14:13 -0800994 // don't dump native PIDs for background ANRs unless it is the process of interest
995 String[] nativeProcs = null;
Tim Murrayf0f9a822016-07-13 13:33:28 -0700996 if (isSilentANR) {
Brian Carlstrom66524242017-03-11 00:14:13 -0800997 for (int i = 0; i < NATIVE_STACKS_OF_INTEREST.length; i++) {
998 if (NATIVE_STACKS_OF_INTEREST[i].equals(app.processName)) {
999 nativeProcs = new String[] { app.processName };
1000 break;
1001 }
1002 }
Tim Murrayf0f9a822016-07-13 13:33:28 -07001003 } else {
Brian Carlstrom66524242017-03-11 00:14:13 -08001004 nativeProcs = NATIVE_STACKS_OF_INTEREST;
Tim Murrayf0f9a822016-07-13 13:33:28 -07001005 }
Adrian Roos20d7df32016-01-12 18:59:43 +01001006
Martijn Coenen94a0dcd2017-03-27 12:45:19 -07001007 int[] pids = nativeProcs == null ? null : Process.getPidsForCommands(nativeProcs);
Steven Moreland6b47c542017-03-21 12:52:16 -07001008 ArrayList<Integer> nativePids = null;
1009
1010 if (pids != null) {
1011 nativePids = new ArrayList<Integer>(pids.length);
1012 for (int i : pids) {
1013 nativePids.add(i);
1014 }
1015 }
1016
Brian Carlstrom66524242017-03-11 00:14:13 -08001017 // For background ANRs, don't pass the ProcessCpuTracker to
1018 // avoid spending 1/2 second collecting stats to rank lastPids.
Narayan Kamathf013daa2017-05-09 12:55:02 +01001019 File tracesFile = ActivityManagerService.dumpStackTraces(
1020 true, firstPids,
1021 (isSilentANR) ? null : processCpuTracker,
1022 (isSilentANR) ? null : lastPids,
1023 nativePids);
Brian Carlstrom66524242017-03-11 00:14:13 -08001024
Adrian Roos20d7df32016-01-12 18:59:43 +01001025 String cpuInfo = null;
1026 if (ActivityManagerService.MONITOR_CPU_USAGE) {
1027 mService.updateCpuStatsNow();
1028 synchronized (mService.mProcessCpuTracker) {
1029 cpuInfo = mService.mProcessCpuTracker.printCurrentState(anrTime);
1030 }
1031 info.append(processCpuTracker.printCurrentLoad());
1032 info.append(cpuInfo);
1033 }
1034
1035 info.append(processCpuTracker.printCurrentState(anrTime));
1036
1037 Slog.e(TAG, info.toString());
1038 if (tracesFile == null) {
1039 // There is no trace file, so dump (only) the alleged culprit's threads to the log
1040 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
1041 }
1042
Chenjie Yu5caaa9d2018-03-06 15:48:54 -08001043 StatsLog.write(StatsLog.ANR_OCCURRED, app.uid, app.processName,
Chenjie Yuf17bf622018-04-02 14:22:19 -07001044 activity == null ? "unknown": activity.shortComponentName, annotation,
1045 (app.info != null) ? (app.info.isInstantApp()
1046 ? StatsLog.ANROCCURRED__IS_INSTANT_APP__TRUE
1047 : StatsLog.ANROCCURRED__IS_INSTANT_APP__FALSE)
1048 : StatsLog.ANROCCURRED__IS_INSTANT_APP__UNAVAILABLE,
1049 app != null ? (app.isInterestingToUserLocked()
1050 ? StatsLog.ANROCCURRED__FOREGROUND_STATE__FOREGROUND
1051 : StatsLog.ANROCCURRED__FOREGROUND_STATE__BACKGROUND)
1052 : StatsLog.ANROCCURRED__FOREGROUND_STATE__UNKNOWN);
Adrian Roos20d7df32016-01-12 18:59:43 +01001053 mService.addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
1054 cpuInfo, tracesFile, null);
1055
1056 if (mService.mController != null) {
1057 try {
1058 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
1059 int res = mService.mController.appNotResponding(
1060 app.processName, app.pid, info.toString());
1061 if (res != 0) {
1062 if (res < 0 && app.pid != MY_PID) {
1063 app.kill("anr", true);
1064 } else {
1065 synchronized (mService) {
1066 mService.mServices.scheduleServiceTimeoutLocked(app);
1067 }
1068 }
1069 return;
1070 }
1071 } catch (RemoteException e) {
1072 mService.mController = null;
1073 Watchdog.getInstance().setActivityController(null);
1074 }
1075 }
1076
Adrian Roos20d7df32016-01-12 18:59:43 +01001077 synchronized (mService) {
1078 mService.mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
1079
Tim Murrayf0f9a822016-07-13 13:33:28 -07001080 if (isSilentANR) {
Adrian Roos20d7df32016-01-12 18:59:43 +01001081 app.kill("bg anr", true);
1082 return;
1083 }
1084
1085 // Set the app's notResponding state, and look up the errorReportReceiver
1086 makeAppNotRespondingLocked(app,
1087 activity != null ? activity.shortComponentName : null,
1088 annotation != null ? "ANR " + annotation : "ANR",
1089 info.toString());
1090
1091 // Bring up the infamous App Not Responding dialog
1092 Message msg = Message.obtain();
Adrian Roos20d7df32016-01-12 18:59:43 +01001093 msg.what = ActivityManagerService.SHOW_NOT_RESPONDING_UI_MSG;
Adrian Roosc3a06e52018-02-16 18:33:17 +01001094 msg.obj = new AppNotRespondingDialog.Data(app, activity, aboveSystem);
Adrian Roos20d7df32016-01-12 18:59:43 +01001095
1096 mService.mUiHandler.sendMessage(msg);
1097 }
1098 }
1099
1100 private void makeAppNotRespondingLocked(ProcessRecord app,
1101 String activity, String shortMsg, String longMsg) {
1102 app.notResponding = true;
1103 app.notRespondingReport = generateProcessError(app,
1104 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
1105 activity, shortMsg, longMsg, null);
1106 startAppProblemLocked(app);
1107 app.stopFreezingAllLocked();
1108 }
1109
1110 void handleShowAnrUi(Message msg) {
Adrian Roosc3a06e52018-02-16 18:33:17 +01001111 Dialog dialogToShow = null;
Adrian Roos20d7df32016-01-12 18:59:43 +01001112 synchronized (mService) {
Adrian Roosc3a06e52018-02-16 18:33:17 +01001113 AppNotRespondingDialog.Data data = (AppNotRespondingDialog.Data) msg.obj;
1114 final ProcessRecord proc = data.proc;
1115 if (proc == null) {
1116 Slog.e(TAG, "handleShowAnrUi: proc is null");
1117 return;
1118 }
1119 if (proc.anrDialog != null) {
Adrian Roos20d7df32016-01-12 18:59:43 +01001120 Slog.e(TAG, "App already has anr dialog: " + proc);
Adrian Roos90462222016-02-17 15:45:09 -08001121 MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_ANR,
1122 AppNotRespondingDialog.ALREADY_SHOWING);
Adrian Roos20d7df32016-01-12 18:59:43 +01001123 return;
1124 }
1125
1126 Intent intent = new Intent("android.intent.action.ANR");
1127 if (!mService.mProcessesReady) {
1128 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1129 | Intent.FLAG_RECEIVER_FOREGROUND);
1130 }
1131 mService.broadcastIntentLocked(null, null, intent,
1132 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1133 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1134
Adrian Roos6a7e0892016-08-23 14:26:39 +02001135 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1136 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1137 if (mService.canShowErrorDialogs() || showBackground) {
Adrian Roosc3a06e52018-02-16 18:33:17 +01001138 dialogToShow = new AppNotRespondingDialog(mService, mContext, data);
1139 proc.anrDialog = dialogToShow;
Adrian Roos20d7df32016-01-12 18:59:43 +01001140 } else {
Adrian Roos90462222016-02-17 15:45:09 -08001141 MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_ANR,
1142 AppNotRespondingDialog.CANT_SHOW);
Adrian Roos20d7df32016-01-12 18:59:43 +01001143 // Just kill the app if there is no dialog to be shown.
1144 mService.killAppAtUsersRequest(proc, null);
1145 }
1146 }
Phil Weaver445fd2a2016-03-17 17:26:24 -07001147 // If we've created a crash dialog, show it without the lock held
Adrian Roosc3a06e52018-02-16 18:33:17 +01001148 if (dialogToShow != null) {
1149 dialogToShow.show();
Phil Weaver445fd2a2016-03-17 17:26:24 -07001150 }
Adrian Roos20d7df32016-01-12 18:59:43 +01001151 }
1152
1153 /**
1154 * Information about a process that is currently marked as bad.
1155 */
1156 static final class BadProcessInfo {
1157 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
1158 this.time = time;
1159 this.shortMsg = shortMsg;
1160 this.longMsg = longMsg;
1161 this.stack = stack;
1162 }
1163
1164 final long time;
1165 final String shortMsg;
1166 final String longMsg;
1167 final String stack;
1168 }
1169
1170}