diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java index b698272147d17..6b0c5780215e8 100644 --- a/services/core/java/com/android/server/Watchdog.java +++ b/services/core/java/com/android/server/Watchdog.java @@ -69,21 +69,21 @@ public class Watchdog extends Thread { public static final boolean DEBUG = false; // Set this to true to use debug default values. - static final boolean DB = false; + private static final boolean DB = false; // Note 1: Do not lower this value below thirty seconds without tightening the invoke-with // timeout in com.android.internal.os.ZygoteConnection, or wrapped applications // can trigger the watchdog. // Note 2: The debug value is already below the wait time in ZygoteConnection. Wrapped // applications may not work with a debug build. CTS will fail. - static final long DEFAULT_TIMEOUT = DB ? 10*1000 : 60*1000; - static final long CHECK_INTERVAL = DEFAULT_TIMEOUT / 2; + private static final long DEFAULT_TIMEOUT = DB ? 10 * 1000 : 60 * 1000; + private static final long CHECK_INTERVAL = DEFAULT_TIMEOUT / 2; // These are temporally ordered: larger values as lateness increases - static final int COMPLETED = 0; - static final int WAITING = 1; - static final int WAITED_HALF = 2; - static final int OVERDUE = 3; + private static final int COMPLETED = 0; + private static final int WAITING = 1; + private static final int WAITED_HALF = 2; + private static final int OVERDUE = 3; // Which native processes to dump into dropbox's stack traces public static final String[] NATIVE_STACKS_OF_INTEREST = new String[] { @@ -125,17 +125,17 @@ public class Watchdog extends Thread { "android.system.suspend@1.0::ISystemSuspend" ); - static Watchdog sWatchdog; + private static Watchdog sWatchdog; /* This handler will be used to post message back onto the main thread */ - final ArrayList mHandlerCheckers = new ArrayList<>(); - final HandlerChecker mMonitorChecker; - ActivityManagerService mActivity; + private final ArrayList mHandlerCheckers = new ArrayList<>(); + private final HandlerChecker mMonitorChecker; + private ActivityManagerService mActivity; - int mPhonePid; - IActivityController mController; - boolean mAllowRestart = true; - final OpenFdMonitor mOpenFdMonitor; + private IActivityController mController; + private boolean mAllowRestart = true; + private final OpenFdMonitor mOpenFdMonitor; + private final List mInterestingJavaPids = new ArrayList<>(); /** * Used for checking status of handle threads and scheduling monitor callbacks. @@ -342,6 +342,8 @@ public class Watchdog extends Thread { mOpenFdMonitor = OpenFdMonitor.create(); + mInterestingJavaPids.add(Process.myPid()); + // See the notes on DEFAULT_TIMEOUT. assert DB || DEFAULT_TIMEOUT > ZygoteConnectionConstants.WRAPPED_PID_TIMEOUT_MILLIS; @@ -359,10 +361,31 @@ public class Watchdog extends Thread { android.Manifest.permission.REBOOT, null); } - public void processStarted(String name, int pid) { - synchronized (this) { - if ("com.android.phone".equals(name)) { - mPhonePid = pid; + private static boolean isInterestingJavaProcess(String processName) { + return processName.equals("com.android.phone"); + } + + /** + * Notifies the watchdog when a Java process with {@code pid} is started. + * This process may have its stack trace dumped during an ANR. + */ + public void processStarted(String processName, int pid) { + if (isInterestingJavaProcess(processName)) { + Slog.i(TAG, "Interesting Java process " + processName + " started. Pid " + pid); + synchronized (this) { + mInterestingJavaPids.add(pid); + } + } + } + + /** + * Notifies the watchdog when a Java process with {@code pid} dies. + */ + public void processDied(String processName, int pid) { + if (isInterestingJavaProcess(processName)) { + Slog.i(TAG, "Interesting Java process " + processName + " died. Pid " + pid); + synchronized (this) { + mInterestingJavaPids.remove(Integer.valueOf(pid)); } } } @@ -582,8 +605,7 @@ public class Watchdog extends Thread { Slog.i(TAG, "WAITED_HALF"); // We've waited half the deadlock-detection interval. Pull a stack // trace and wait another half. - ArrayList pids = new ArrayList(); - pids.add(Process.myPid()); + ArrayList pids = new ArrayList<>(mInterestingJavaPids); ActivityManagerService.dumpStackTraces(pids, null, null, getInterestingNativePids(), null); waitedHalf = true; @@ -606,9 +628,7 @@ public class Watchdog extends Thread { // Then kill this process so that the system will restart. EventLog.writeEvent(EventLogTags.WATCHDOG, subject); - ArrayList pids = new ArrayList<>(); - pids.add(Process.myPid()); - if (mPhonePid > 0) pids.add(mPhonePid); + ArrayList pids = new ArrayList<>(mInterestingJavaPids); long anrTime = SystemClock.uptimeMillis(); StringBuilder report = new StringBuilder(); diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index 5d1b0e3924ea1..3a5447edfdf0a 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -2396,9 +2396,7 @@ public final class ProcessList { // Ignore } - if (app.isPersistent()) { - Watchdog.getInstance().processStarted(app.processName, pid); - } + Watchdog.getInstance().processStarted(app.processName, pid); checkSlow(app.startTime, "startProcess: building log message"); StringBuilder buf = mStringBuilder; @@ -3769,6 +3767,7 @@ public final class ProcessList { Slog.i(TAG, "note: " + app + " died, saving the exit info"); } + Watchdog.getInstance().processDied(app.processName, app.pid); mAppExitInfoTracker.scheduleNoteProcessDiedLocked(app); }