summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/java/com/android/server/Watchdog.java45
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java1
-rw-r--r--services/java/com/android/server/pm/PackageManagerService.java2
-rw-r--r--services/java/com/android/server/power/PowerManagerService.java1
4 files changed, 37 insertions, 12 deletions
diff --git a/services/java/com/android/server/Watchdog.java b/services/java/com/android/server/Watchdog.java
index 070b8e59d09d..ec573f947a50 100644
--- a/services/java/com/android/server/Watchdog.java
+++ b/services/java/com/android/server/Watchdog.java
@@ -120,6 +120,14 @@ public class Watchdog extends Thread {
return mCompleted;
}
+ public Thread getThread() {
+ return mHandler.getLooper().getThread();
+ }
+
+ public String getName() {
+ return mName;
+ }
+
public String describeBlockedStateLocked() {
return mCurrentMonitor == null ? mName : mCurrentMonitor.getClass().getName();
}
@@ -256,17 +264,25 @@ public class Watchdog extends Thread {
return true;
}
- private String describeBlockedCheckersLocked() {
- StringBuilder builder = new StringBuilder(128);
+ private ArrayList<HandlerChecker> getBlockedCheckersLocked() {
+ ArrayList<HandlerChecker> checkers = new ArrayList<HandlerChecker>();
for (int i=0; i<mHandlerCheckers.size(); i++) {
HandlerChecker hc = mHandlerCheckers.get(i);
if (!hc.isCompletedLocked()) {
- if (builder.length() > 0) {
- builder.append(", ");
- }
- builder.append(hc.describeBlockedStateLocked());
+ checkers.add(hc);
}
}
+ return checkers;
+ }
+
+ private String describeCheckersLocked(ArrayList<HandlerChecker> checkers) {
+ StringBuilder builder = new StringBuilder(128);
+ for (int i=0; i<checkers.size(); i++) {
+ if (builder.length() > 0) {
+ builder.append(", ");
+ }
+ builder.append(checkers.get(i).describeBlockedStateLocked());
+ }
return builder.toString();
}
@@ -274,6 +290,7 @@ public class Watchdog extends Thread {
public void run() {
boolean waitedHalf = false;
while (true) {
+ final ArrayList<HandlerChecker> blockedCheckers;
final String name;
final boolean allowRestart;
synchronized (this) {
@@ -318,7 +335,8 @@ public class Watchdog extends Thread {
continue;
}
- name = describeBlockedCheckersLocked();
+ blockedCheckers = getBlockedCheckersLocked();
+ name = describeCheckersLocked(blockedCheckers);
allowRestart = mAllowRestart;
}
@@ -395,12 +413,15 @@ public class Watchdog extends Thread {
Slog.w(TAG, "Restart not allowed: Watchdog is *not* killing the system process");
} else {
Slog.w(TAG, "*** WATCHDOG KILLING SYSTEM PROCESS: " + name);
- Slog.w(TAG, "Main thread stack trace:");
- StackTraceElement[] stackTrace = Looper.getMainLooper().getThread().getStackTrace();
- for (StackTraceElement element: stackTrace) {
- Slog.w(TAG, "\tat " + element);
+ for (int i=0; i<blockedCheckers.size(); i++) {
+ Slog.w(TAG, blockedCheckers.get(i).getName() + " stack trace:");
+ StackTraceElement[] stackTrace
+ = blockedCheckers.get(i).getThread().getStackTrace();
+ for (StackTraceElement element: stackTrace) {
+ Slog.w(TAG, " at " + element);
+ }
}
- Slog.w(TAG, "<End of main thread stack trace>");
+ Slog.w(TAG, "*** GOODBYE!");
Process.killProcess(Process.myPid());
System.exit(10);
}
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 42e2b3a9b7eb..9d9d06d1cde2 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -1576,6 +1576,7 @@ public final class ActivityManagerService extends ActivityManagerNative
synchronized (this) {
mService = m;
mLooper = Looper.myLooper();
+ Watchdog.getInstance().addThread(new Handler(mLooper), getName());
notifyAll();
}
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 47282ba304da..8f512d33d9f4 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -41,6 +41,7 @@ import com.android.server.DeviceStorageMonitorService;
import com.android.server.EventLogTags;
import com.android.server.IntentResolver;
+import com.android.server.Watchdog;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
@@ -1093,6 +1094,7 @@ public class PackageManagerService extends IPackageManager.Stub {
synchronized (mPackages) {
mHandlerThread.start();
mHandler = new PackageHandler(mHandlerThread.getLooper());
+ Watchdog.getInstance().addThread(mHandler, mHandlerThread.getName());
File dataDir = Environment.getDataDirectory();
mAppDataDir = new File(dataDir, "data");
diff --git a/services/java/com/android/server/power/PowerManagerService.java b/services/java/com/android/server/power/PowerManagerService.java
index 198851c3dc1d..6c283faf7934 100644
--- a/services/java/com/android/server/power/PowerManagerService.java
+++ b/services/java/com/android/server/power/PowerManagerService.java
@@ -405,6 +405,7 @@ public final class PowerManagerService extends IPowerManager.Stub
mHandler = new PowerManagerHandler(mHandlerThread.getLooper());
Watchdog.getInstance().addMonitor(this);
+ Watchdog.getInstance().addThread(mHandler, mHandlerThread.getName());
// Forcibly turn the screen on at boot so that it is in a known power state.
// We do this in init() rather than in the constructor because setting the