Also dump system process threads halfway through the watchdog interval
This gives us a snapshot of what the system process was doing after 30 seconds
of apparent inactivity as well as after 1 minute, to help distinguishing actual
deadlocks from too-slow progress, livelock, etc.
Change-Id: I19758861d1b25f298e88788e8f1c7ec7bf828823
diff --git a/services/java/com/android/server/Watchdog.java b/services/java/com/android/server/Watchdog.java
index be1d1c4..5eaadbc 100644
--- a/services/java/com/android/server/Watchdog.java
+++ b/services/java/com/android/server/Watchdog.java
@@ -54,7 +54,8 @@
static final int MONITOR = 2718;
static final int GLOBAL_PSS = 2719;
- static final int TIME_TO_WAIT = DB ? 15*1000 : 60*1000;
+ static final int TIME_TO_RESTART = DB ? 15*1000 : 60*1000;
+ static final int TIME_TO_WAIT = TIME_TO_RESTART / 2;
static final int MEMCHECK_DEFAULT_INTERVAL = DB ? 30 : 30*60; // 30 minutes
static final int MEMCHECK_DEFAULT_LOG_REALTIME_INTERVAL = DB ? 60 : 2*60*60; // 2 hours
@@ -792,6 +793,7 @@
@Override
public void run() {
+ boolean waitedHalf = false;
while (true) {
mCompleted = false;
mHandler.sendEmptyMessage(MONITOR);
@@ -801,7 +803,7 @@
// NOTE: We use uptimeMillis() here because we do not want to increment the time we
// wait while asleep. If the device is asleep then the thing that we are waiting
- // to timeout on is asleep as well and won't have a chance to run. Causing a false
+ // to timeout on is asleep as well and won't have a chance to run, causing a false
// positive on when to kill things.
long start = SystemClock.uptimeMillis();
while (timeout > 0 && !mForceKillSystem) {
@@ -815,6 +817,17 @@
if (mCompleted && !mForceKillSystem) {
// The monitors have returned.
+ waitedHalf = false;
+ continue;
+ }
+
+ if (!waitedHalf) {
+ // We've waited half the deadlock-detection interval. Pull a stack
+ // trace and wait another half.
+ ArrayList pids = new ArrayList();
+ pids.add(Process.myPid());
+ File stack = ActivityManagerService.dumpStackTraces(true, pids);
+ waitedHalf = true;
continue;
}
}
@@ -829,7 +842,9 @@
ArrayList pids = new ArrayList();
pids.add(Process.myPid());
if (mPhonePid > 0) pids.add(mPhonePid);
- File stack = ActivityManagerService.dumpStackTraces(pids);
+ // Pass !waitedHalf so that just in case we somehow wind up here without having
+ // dumped the halfway stacks, we properly re-initialize the trace file.
+ File stack = ActivityManagerService.dumpStackTraces(!waitedHalf, pids);
// Give some extra time to make sure the stack traces get written.
// The system's been hanging for a minute, another second or two won't hurt much.
@@ -845,6 +860,8 @@
} else {
Slog.w(TAG, "Debugger connected: Watchdog is *not* killing the system process");
}
+
+ waitedHalf = false;
}
}
}