Skip to content

Commit 6ee412d

Browse files
author
Christopher Tate
committed
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
1 parent 94f1751 commit 6ee412d

File tree

2 files changed

+26
-6
lines changed

2 files changed

+26
-6
lines changed

services/java/com/android/server/Watchdog.java

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ public class Watchdog extends Thread {
5454
static final int MONITOR = 2718;
5555
static final int GLOBAL_PSS = 2719;
5656

57-
static final int TIME_TO_WAIT = DB ? 15*1000 : 60*1000;
57+
static final int TIME_TO_RESTART = DB ? 15*1000 : 60*1000;
58+
static final int TIME_TO_WAIT = TIME_TO_RESTART / 2;
5859

5960
static final int MEMCHECK_DEFAULT_INTERVAL = DB ? 30 : 30*60; // 30 minutes
6061
static final int MEMCHECK_DEFAULT_LOG_REALTIME_INTERVAL = DB ? 60 : 2*60*60; // 2 hours
@@ -792,6 +793,7 @@ static long computeCalendarTime(Calendar c, long curTime,
792793

793794
@Override
794795
public void run() {
796+
boolean waitedHalf = false;
795797
while (true) {
796798
mCompleted = false;
797799
mHandler.sendEmptyMessage(MONITOR);
@@ -801,7 +803,7 @@ public void run() {
801803

802804
// NOTE: We use uptimeMillis() here because we do not want to increment the time we
803805
// wait while asleep. If the device is asleep then the thing that we are waiting
804-
// to timeout on is asleep as well and won't have a chance to run. Causing a false
806+
// to timeout on is asleep as well and won't have a chance to run, causing a false
805807
// positive on when to kill things.
806808
long start = SystemClock.uptimeMillis();
807809
while (timeout > 0 && !mForceKillSystem) {
@@ -815,6 +817,17 @@ public void run() {
815817

816818
if (mCompleted && !mForceKillSystem) {
817819
// The monitors have returned.
820+
waitedHalf = false;
821+
continue;
822+
}
823+
824+
if (!waitedHalf) {
825+
// We've waited half the deadlock-detection interval. Pull a stack
826+
// trace and wait another half.
827+
ArrayList pids = new ArrayList();
828+
pids.add(Process.myPid());
829+
File stack = ActivityManagerService.dumpStackTraces(true, pids);
830+
waitedHalf = true;
818831
continue;
819832
}
820833
}
@@ -829,7 +842,9 @@ public void run() {
829842
ArrayList pids = new ArrayList();
830843
pids.add(Process.myPid());
831844
if (mPhonePid > 0) pids.add(mPhonePid);
832-
File stack = ActivityManagerService.dumpStackTraces(pids);
845+
// Pass !waitedHalf so that just in case we somehow wind up here without having
846+
// dumped the halfway stacks, we properly re-initialize the trace file.
847+
File stack = ActivityManagerService.dumpStackTraces(!waitedHalf, pids);
833848

834849
// Give some extra time to make sure the stack traces get written.
835850
// The system's been hanging for a minute, another second or two won't hurt much.
@@ -845,6 +860,8 @@ public void run() {
845860
} else {
846861
Slog.w(TAG, "Debugger connected: Watchdog is *not* killing the system process");
847862
}
863+
864+
waitedHalf = false;
848865
}
849866
}
850867
}

services/java/com/android/server/am/ActivityManagerService.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4779,10 +4779,13 @@ private final void appDiedLocked(ProcessRecord app, int pid,
47794779

47804780
/**
47814781
* If a stack trace dump file is configured, dump process stack traces.
4782+
* @param clearTraces causes the dump file to be erased prior to the new
4783+
* traces being written, if true; when false, the new traces will be
4784+
* appended to any existing file content.
47824785
* @param pids of dalvik VM processes to dump stack traces for
47834786
* @return file containing stack traces, or null if no dump file is configured
47844787
*/
4785-
public static File dumpStackTraces(ArrayList<Integer> pids) {
4788+
public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> pids) {
47864789
String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
47874790
if (tracesPath == null || tracesPath.length() == 0) {
47884791
return null;
@@ -4794,7 +4797,7 @@ public static File dumpStackTraces(ArrayList<Integer> pids) {
47944797
if (!tracesDir.exists()) tracesFile.mkdirs();
47954798
FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
47964799

4797-
if (tracesFile.exists()) tracesFile.delete();
4800+
if (clearTraces && tracesFile.exists()) tracesFile.delete();
47984801
tracesFile.createNewFile();
47994802
FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
48004803
} catch (IOException e) {
@@ -4869,7 +4872,7 @@ final void appNotResponding(ProcessRecord app, HistoryRecord activity,
48694872
}
48704873
}
48714874

4872-
File tracesFile = dumpStackTraces(pids);
4875+
File tracesFile = dumpStackTraces(true, pids);
48734876

48744877
// Log the ANR to the main log.
48754878
StringBuilder info = mStringBuilder;

0 commit comments

Comments
 (0)