Loading services/java/com/android/server/Watchdog.java +17 −18 Original line number Diff line number Diff line Loading @@ -34,8 +34,10 @@ import android.os.SystemProperties; import android.provider.Settings; import android.util.Config; import android.util.EventLog; import android.util.Log; import android.util.Slog; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Calendar; Loading Loading @@ -804,19 +806,14 @@ public class Watchdog extends Thread { // 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(); do { while (timeout > 0 && !mForceKillSystem) { try { wait(timeout); wait(timeout); // notifyAll() is called when mForceKillSystem is set } catch (InterruptedException e) { if (SystemProperties.getBoolean("ro.secure", false)) { // If this is a secure build, just log the error. Slog.e("WatchDog", "Woof! Woof! Interrupter!"); } else { throw new AssertionError("Someone interrupted the watchdog"); } Log.wtf(TAG, e); } timeout = TIME_TO_WAIT - (SystemClock.uptimeMillis() - start); } while (timeout > 0 && !mForceKillSystem); } if (mCompleted && !mForceKillSystem) { // The monitors have returned. Loading @@ -825,22 +822,24 @@ public class Watchdog extends Thread { } // If we got here, that means that the system is most likely hung. // First send a SIGQUIT so that we can see where it was hung. Then // kill this process so that the system will restart. // First collect stack traces from all threads of the system process. // Then kill this process so that the system will restart. String name = (mCurrentMonitor != null) ? mCurrentMonitor.getClass().getName() : "null"; EventLog.writeEvent(EventLogTags.WATCHDOG, name); Process.sendSignal(Process.myPid(), Process.SIGNAL_QUIT); // Wait a bit longer before killing so we can make sure that the stacks are captured. try { Thread.sleep(10*1000); } catch (InterruptedException e) { } ArrayList pids = new ArrayList(); pids.add(Process.myPid()); File stack = ActivityManagerService.dumpStackTraces(pids); mActivity.addErrorToDropBox("watchdog", null, null, null, name, null, stack, null); // Only kill the process if the debugger is not attached. if (!Debug.isDebuggerConnected()) { Slog.i(TAG, "Watchdog is killing the system process"); Slog.w(TAG, "*** WATCHDOG KILLING SYSTEM PROCESS: " + name); Process.killProcess(Process.myPid()); System.exit(10); } else { Slog.w(TAG, "Debugger connected: Watchdog is *not* killing the system process"); } } } Loading services/java/com/android/server/am/ActivityManagerService.java +5 −2 Original line number Diff line number Diff line Loading @@ -4662,7 +4662,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen * @param pids of dalvik VM processes to dump stack traces for * @return file containing stack traces, or null if no dump file is configured */ private static File dumpStackTraces(ArrayList<Integer> pids) { public static File dumpStackTraces(ArrayList<Integer> pids) { String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); if (tracesPath == null || tracesPath.length() == 0) { return null; Loading Loading @@ -8958,10 +8958,13 @@ public final class ActivityManagerService extends ActivityManagerNative implemen * @param logFile to include in the report, null if none * @param crashInfo giving an application stack trace, null if absent */ private void addErrorToDropBox(String eventType, public void addErrorToDropBox(String eventType, ProcessRecord process, HistoryRecord activity, HistoryRecord parent, String subject, String report, File logFile, ApplicationErrorReport.CrashInfo crashInfo) { // NOTE -- this must never acquire the ActivityManagerService lock, // otherwise the watchdog may be prevented from resetting the system. String dropboxTag; if (process == null || process.pid == MY_PID) { dropboxTag = "system_server_" + eventType; Loading Loading
services/java/com/android/server/Watchdog.java +17 −18 Original line number Diff line number Diff line Loading @@ -34,8 +34,10 @@ import android.os.SystemProperties; import android.provider.Settings; import android.util.Config; import android.util.EventLog; import android.util.Log; import android.util.Slog; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Calendar; Loading Loading @@ -804,19 +806,14 @@ public class Watchdog extends Thread { // 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(); do { while (timeout > 0 && !mForceKillSystem) { try { wait(timeout); wait(timeout); // notifyAll() is called when mForceKillSystem is set } catch (InterruptedException e) { if (SystemProperties.getBoolean("ro.secure", false)) { // If this is a secure build, just log the error. Slog.e("WatchDog", "Woof! Woof! Interrupter!"); } else { throw new AssertionError("Someone interrupted the watchdog"); } Log.wtf(TAG, e); } timeout = TIME_TO_WAIT - (SystemClock.uptimeMillis() - start); } while (timeout > 0 && !mForceKillSystem); } if (mCompleted && !mForceKillSystem) { // The monitors have returned. Loading @@ -825,22 +822,24 @@ public class Watchdog extends Thread { } // If we got here, that means that the system is most likely hung. // First send a SIGQUIT so that we can see where it was hung. Then // kill this process so that the system will restart. // First collect stack traces from all threads of the system process. // Then kill this process so that the system will restart. String name = (mCurrentMonitor != null) ? mCurrentMonitor.getClass().getName() : "null"; EventLog.writeEvent(EventLogTags.WATCHDOG, name); Process.sendSignal(Process.myPid(), Process.SIGNAL_QUIT); // Wait a bit longer before killing so we can make sure that the stacks are captured. try { Thread.sleep(10*1000); } catch (InterruptedException e) { } ArrayList pids = new ArrayList(); pids.add(Process.myPid()); File stack = ActivityManagerService.dumpStackTraces(pids); mActivity.addErrorToDropBox("watchdog", null, null, null, name, null, stack, null); // Only kill the process if the debugger is not attached. if (!Debug.isDebuggerConnected()) { Slog.i(TAG, "Watchdog is killing the system process"); Slog.w(TAG, "*** WATCHDOG KILLING SYSTEM PROCESS: " + name); Process.killProcess(Process.myPid()); System.exit(10); } else { Slog.w(TAG, "Debugger connected: Watchdog is *not* killing the system process"); } } } Loading
services/java/com/android/server/am/ActivityManagerService.java +5 −2 Original line number Diff line number Diff line Loading @@ -4662,7 +4662,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen * @param pids of dalvik VM processes to dump stack traces for * @return file containing stack traces, or null if no dump file is configured */ private static File dumpStackTraces(ArrayList<Integer> pids) { public static File dumpStackTraces(ArrayList<Integer> pids) { String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); if (tracesPath == null || tracesPath.length() == 0) { return null; Loading Loading @@ -8958,10 +8958,13 @@ public final class ActivityManagerService extends ActivityManagerNative implemen * @param logFile to include in the report, null if none * @param crashInfo giving an application stack trace, null if absent */ private void addErrorToDropBox(String eventType, public void addErrorToDropBox(String eventType, ProcessRecord process, HistoryRecord activity, HistoryRecord parent, String subject, String report, File logFile, ApplicationErrorReport.CrashInfo crashInfo) { // NOTE -- this must never acquire the ActivityManagerService lock, // otherwise the watchdog may be prevented from resetting the system. String dropboxTag; if (process == null || process.pid == MY_PID) { dropboxTag = "system_server_" + eventType; Loading