diff options
author | Tim Murray <timmurray@google.com> | 2016-07-13 13:33:28 -0700 |
---|---|---|
committer | gitbuildkicker <android-build@google.com> | 2016-07-13 20:30:41 -0700 |
commit | 13eb2e20a30abcfa45f41cd11a1fc110717c7c2b (patch) | |
tree | f5613c1ffc14a1aa4b6f69c472f157b1aa8ea22d | |
parent | 2e4e3dbb02a8d2c7efbe8b06c30abc183accc75b (diff) | |
download | base-13eb2e20a30abcfa45f41cd11a1fc110717c7c2b.tar.gz |
Don't dump stack traces for background ANRs.
Dumping stack traces can be extremely expensive, and doing so for
background applications often has extremely negative side effects for
foreground applications. This can be exacerbated by resource-intensive
applications, because those may exhibit thermal throttling in the first
place. For such applications, the additional performance hit caused by
stack dumps may be catastrophic.
Instead, don't dump stack traces for background ANRs except for the app
that actually ANR'd.
bug 30112521
Change-Id: I8a05059343254861c436a193690cd1c50a95d674
-rw-r--r-- | services/core/java/com/android/server/am/AppErrors.java | 68 |
1 files changed, 41 insertions, 27 deletions
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java index 49106f42044e..cb37999b339e 100644 --- a/services/core/java/com/android/server/am/AppErrors.java +++ b/services/core/java/com/android/server/am/AppErrors.java @@ -742,6 +742,12 @@ class AppErrors { mService.updateCpuStatsNow(); } + // Unless configured otherwise, swallow ANRs in background processes & kill the process. + boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), + Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; + + boolean isSilentANR; + synchronized (mService) { // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. if (mService.mShuttingDown) { @@ -766,25 +772,29 @@ class AppErrors { // Dump thread traces as quickly as we can, starting with "interesting" processes. firstPids.add(app.pid); - int parentPid = app.pid; - if (parent != null && parent.app != null && parent.app.pid > 0) { - parentPid = parent.app.pid; - } - if (parentPid != app.pid) firstPids.add(parentPid); - - if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); - - for (int i = mService.mLruProcesses.size() - 1; i >= 0; i--) { - ProcessRecord r = mService.mLruProcesses.get(i); - if (r != null && r.thread != null) { - int pid = r.pid; - if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { - if (r.persistent) { - firstPids.add(pid); - if (DEBUG_ANR) Slog.i(TAG, "Adding persistent proc: " + r); - } else { - lastPids.put(pid, Boolean.TRUE); - if (DEBUG_ANR) Slog.i(TAG, "Adding ANR proc: " + r); + // Don't dump other PIDs if it's a background ANR + isSilentANR = !showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID; + if (!isSilentANR) { + int parentPid = app.pid; + if (parent != null && parent.app != null && parent.app.pid > 0) { + parentPid = parent.app.pid; + } + if (parentPid != app.pid) firstPids.add(parentPid); + + if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); + + for (int i = mService.mLruProcesses.size() - 1; i >= 0; i--) { + ProcessRecord r = mService.mLruProcesses.get(i); + if (r != null && r.thread != null) { + int pid = r.pid; + if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { + if (r.persistent) { + firstPids.add(pid); + if (DEBUG_ANR) Slog.i(TAG, "Adding persistent proc: " + r); + } else { + lastPids.put(pid, Boolean.TRUE); + if (DEBUG_ANR) Slog.i(TAG, "Adding ANR proc: " + r); + } } } } @@ -807,10 +817,18 @@ class AppErrors { info.append("Parent: ").append(parent.shortComponentName).append("\n"); } - final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); + ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); - File tracesFile = mService.dumpStackTraces(true, firstPids, processCpuTracker, lastPids, - NATIVE_STACKS_OF_INTEREST); + String[] nativeProcs = NATIVE_STACKS_OF_INTEREST; + // don't dump native PIDs for background ANRs + File tracesFile = null; + if (isSilentANR) { + tracesFile = mService.dumpStackTraces(true, firstPids, null, lastPids, + null); + } else { + tracesFile = mService.dumpStackTraces(true, firstPids, processCpuTracker, lastPids, + nativeProcs); + } String cpuInfo = null; if (ActivityManagerService.MONITOR_CPU_USAGE) { @@ -854,14 +872,10 @@ class AppErrors { } } - // Unless configured otherwise, swallow ANRs in background processes & kill the process. - boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), - Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; - synchronized (mService) { mService.mBatteryStatsService.noteProcessAnr(app.processName, app.uid); - if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { + if (isSilentANR) { app.kill("bg anr", true); return; } |