Watchdog.java revision d7fdd0228e6abdbc079f9cf08b780e4222dfe7c5
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage com.android.server; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 195b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackbornimport android.app.IActivityController; 205b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackbornimport android.os.Binder; 215b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackbornimport android.os.RemoteException; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.server.am.ActivityManagerService; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.BroadcastReceiver; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.ContentResolver; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Intent; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.IntentFilter; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Debug; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler; 316f357d3284a833cc50a990e14b39f389b8972254Jeff Brownimport android.os.IPowerManager; 32116415271b952ab9e842f3850faa1a44cb70bf6aJohn Michelauimport android.os.Looper; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Process; 346ffce2e9a3c57634bb73f8ff133ca680f8070d5dSuchi Amalapurapuimport android.os.ServiceManager; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.SystemClock; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.SystemProperties; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.EventLog; 389bdc94b7a42a07d7dafcdf2cbadbb9c736b979d2Dan Egnorimport android.util.Log; 398a9b22056b13477f59df934928c00c58b5871c95Joe Onoratoimport android.util.Slog; 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 419bdc94b7a42a07d7dafcdf2cbadbb9c736b979d2Dan Egnorimport java.io.File; 425df1d871feabee23b16a69ee48695fd892017517Colin Crossimport java.io.FileWriter; 435df1d871feabee23b16a69ee48695fd892017517Colin Crossimport java.io.IOException; 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** This class calls its monitor every minute. Killing this process if they don't return **/ 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class Watchdog extends Thread { 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final String TAG = "Watchdog"; 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Set this to true to use debug default values. 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final boolean DB = false; 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 53ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate // Set this to true to have the watchdog record kernel thread stacks when it fires 54ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate static final boolean RECORD_KERNEL_THREADS = true; 55ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate 56e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate static final long DEFAULT_TIMEOUT = DB ? 10*1000 : 60*1000; 57e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate static final long CHECK_INTERVAL = DEFAULT_TIMEOUT / 2; 58e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate 59e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate // These are temporally ordered: larger values as lateness increases 60e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate static final int COMPLETED = 0; 61e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate static final int WAITING = 1; 62e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate static final int WAITED_HALF = 2; 63e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate static final int OVERDUE = 3; 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6544d04aa0ace68e6164c5eb7b3536c0992aaf5a3aIgor Murashkin // Which native processes to dump into dropbox's stack traces 6644d04aa0ace68e6164c5eb7b3536c0992aaf5a3aIgor Murashkin public static final String[] NATIVE_STACKS_OF_INTEREST = new String[] { 67f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn "/system/bin/mediaserver", 68f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn "/system/bin/sdcard", 69f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn "/system/bin/surfaceflinger" 70f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn }; 71f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static Watchdog sWatchdog; 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* This handler will be used to post message back onto the main thread */ 75d7fdd0228e6abdbc079f9cf08b780e4222dfe7c5Wale Ogunwale final ArrayList<HandlerChecker> mHandlerCheckers = new ArrayList<>(); 768d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn final HandlerChecker mMonitorChecker; 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ContentResolver mResolver; 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ActivityManagerService mActivity; 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mPhonePid; 815b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn IActivityController mController; 828bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn boolean mAllowRestart = true; 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 858d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn * Used for checking status of handle threads and scheduling monitor callbacks. 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 878d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn public final class HandlerChecker implements Runnable { 888d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn private final Handler mHandler; 898d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn private final String mName; 90e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate private final long mWaitMax; 918d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn private final ArrayList<Monitor> mMonitors = new ArrayList<Monitor>(); 928d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn private boolean mCompleted; 938d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn private Monitor mCurrentMonitor; 94e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate private long mStartTime; 958d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn 96e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate HandlerChecker(Handler handler, String name, long waitMaxMillis) { 978d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn mHandler = handler; 988d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn mName = name; 99e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate mWaitMax = waitMaxMillis; 100e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate mCompleted = true; 1018d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn } 1028d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn 1038d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn public void addMonitor(Monitor monitor) { 1048d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn mMonitors.add(monitor); 1058d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn } 1068d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn 1078d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn public void scheduleCheckLocked() { 1086c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown if (mMonitors.size() == 0 && mHandler.getLooper().getQueue().isPolling()) { 1096c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown // If the target looper has recently been polling, then 110efa92b2182ab581873aa8e75d596e2e363bd5e6dDianne Hackborn // there is no reason to enqueue our checker on it since that 111efa92b2182ab581873aa8e75d596e2e363bd5e6dDianne Hackborn // is as good as it not being deadlocked. This avoid having 112efa92b2182ab581873aa8e75d596e2e363bd5e6dDianne Hackborn // to do a context switch to check the thread. Note that we 113efa92b2182ab581873aa8e75d596e2e363bd5e6dDianne Hackborn // only do this if mCheckReboot is false and we have no 114efa92b2182ab581873aa8e75d596e2e363bd5e6dDianne Hackborn // monitors, since those would need to be executed at this point. 115efa92b2182ab581873aa8e75d596e2e363bd5e6dDianne Hackborn mCompleted = true; 116efa92b2182ab581873aa8e75d596e2e363bd5e6dDianne Hackborn return; 117efa92b2182ab581873aa8e75d596e2e363bd5e6dDianne Hackborn } 118e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate 119e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate if (!mCompleted) { 120e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate // we already have a check in flight, so no need 121e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate return; 122e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate } 123e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate 1248d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn mCompleted = false; 1258d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn mCurrentMonitor = null; 126e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate mStartTime = SystemClock.uptimeMillis(); 1278d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn mHandler.postAtFrontOfQueue(this); 1288d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn } 1298d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn 130e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate public boolean isOverdueLocked() { 131e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate return (!mCompleted) && (SystemClock.uptimeMillis() > mStartTime + mWaitMax); 132e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate } 133e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate 134e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate public int getCompletionStateLocked() { 135e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate if (mCompleted) { 136e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate return COMPLETED; 137e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate } else { 138e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate long latency = SystemClock.uptimeMillis() - mStartTime; 139e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate if (latency < mWaitMax/2) { 140e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate return WAITING; 141e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate } else if (latency < mWaitMax) { 142e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate return WAITED_HALF; 143e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate } 144e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate } 145e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate return OVERDUE; 1468d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn } 1478d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn 148fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn public Thread getThread() { 149fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn return mHandler.getLooper().getThread(); 150fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn } 151fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn 152fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn public String getName() { 153fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn return mName; 154fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn } 155fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn 1568d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn public String describeBlockedStateLocked() { 1577dd2d19725bac29306900a06818edf2f205ca051Jeff Brown if (mCurrentMonitor == null) { 1587dd2d19725bac29306900a06818edf2f205ca051Jeff Brown return "Blocked in handler on " + mName + " (" + getThread().getName() + ")"; 1597dd2d19725bac29306900a06818edf2f205ca051Jeff Brown } else { 1607dd2d19725bac29306900a06818edf2f205ca051Jeff Brown return "Blocked in monitor " + mCurrentMonitor.getClass().getName() 1617dd2d19725bac29306900a06818edf2f205ca051Jeff Brown + " on " + mName + " (" + getThread().getName() + ")"; 1627dd2d19725bac29306900a06818edf2f205ca051Jeff Brown } 163116415271b952ab9e842f3850faa1a44cb70bf6aJohn Michelau } 164116415271b952ab9e842f3850faa1a44cb70bf6aJohn Michelau 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1668d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn public void run() { 1678d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn final int size = mMonitors.size(); 1688d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn for (int i = 0 ; i < size ; i++) { 1698d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn synchronized (Watchdog.this) { 1708d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn mCurrentMonitor = mMonitors.get(i); 1718d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn } 1728d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn mCurrentMonitor.monitor(); 1738d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn } 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1758d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn synchronized (Watchdog.this) { 1768d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn mCompleted = true; 1778d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn mCurrentMonitor = null; 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final class RebootRequestReceiver extends BroadcastReceiver { 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onReceive(Context c, Intent intent) { 185f6438b16ba81a0179b789ca4fc66e8016bf6a96dDianne Hackborn if (intent.getIntExtra("nowait", 0) != 0) { 186f6438b16ba81a0179b789ca4fc66e8016bf6a96dDianne Hackborn rebootSystem("Received ACTION_REBOOT broadcast"); 187f6438b16ba81a0179b789ca4fc66e8016bf6a96dDianne Hackborn return; 188f6438b16ba81a0179b789ca4fc66e8016bf6a96dDianne Hackborn } 189f6438b16ba81a0179b789ca4fc66e8016bf6a96dDianne Hackborn Slog.w(TAG, "Unsupported ACTION_REBOOT broadcast: " + intent); 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public interface Monitor { 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void monitor(); 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static Watchdog getInstance() { 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sWatchdog == null) { 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sWatchdog = new Watchdog(); 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return sWatchdog; 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Watchdog() { 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super("watchdog"); 2078d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn // Initialize handler checkers for each common thread we want to check. Note 2088d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn // that we are not currently checking the background thread, since it can 2098d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn // potentially hold longer running operations with no guarantees about the timeliness 2108d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn // of operations there. 2118d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn 2128d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn // The shared foreground thread is the main checker. It is where we 2138d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn // will also dispatch monitor checks and do other work. 214e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate mMonitorChecker = new HandlerChecker(FgThread.getHandler(), 215e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate "foreground thread", DEFAULT_TIMEOUT); 2168d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn mHandlerCheckers.add(mMonitorChecker); 2178d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn // Add checker for main thread. We only do a quick check since there 2188d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn // can be UI running on the thread. 2198d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn mHandlerCheckers.add(new HandlerChecker(new Handler(Looper.getMainLooper()), 220e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate "main thread", DEFAULT_TIMEOUT)); 2218d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn // Add checker for shared UI thread. 222e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate mHandlerCheckers.add(new HandlerChecker(UiThread.getHandler(), 223e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate "ui thread", DEFAULT_TIMEOUT)); 2248d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn // And also check IO thread. 225e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate mHandlerCheckers.add(new HandlerChecker(IoThread.getHandler(), 226e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate "i/o thread", DEFAULT_TIMEOUT)); 2274ccb823a9f62e57f9d221f83a97e82967e79a9e5Jeff Brown // And the display thread. 2284ccb823a9f62e57f9d221f83a97e82967e79a9e5Jeff Brown mHandlerCheckers.add(new HandlerChecker(DisplayThread.getHandler(), 2294ccb823a9f62e57f9d221f83a97e82967e79a9e5Jeff Brown "display thread", DEFAULT_TIMEOUT)); 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 232182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski public void init(Context context, ActivityManagerService activity) { 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mResolver = context.getContentResolver(); 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mActivity = activity; 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project context.registerReceiver(new RebootRequestReceiver(), 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new IntentFilter(Intent.ACTION_REBOOT), 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android.Manifest.permission.REBOOT, null); 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 241c27181c7f3e11170ec82807cfa416f0a906ff574Christopher Tate public void processStarted(String name, int pid) { 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ("com.android.phone".equals(name)) { 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPhonePid = pid; 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2495b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn public void setActivityController(IActivityController controller) { 2505b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn synchronized (this) { 2515b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn mController = controller; 2525b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn } 2535b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn } 2545b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn 2558bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn public void setAllowRestart(boolean allowRestart) { 2568bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn synchronized (this) { 2578bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn mAllowRestart = allowRestart; 2588bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn } 2598bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn } 2608bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void addMonitor(Monitor monitor) { 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isAlive()) { 2648d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn throw new RuntimeException("Monitors can't be added once the Watchdog is running"); 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2668d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn mMonitorChecker.addMonitor(monitor); 2678d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn } 2688d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn } 2698d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn 2706f357d3284a833cc50a990e14b39f389b8972254Jeff Brown public void addThread(Handler thread) { 2716f357d3284a833cc50a990e14b39f389b8972254Jeff Brown addThread(thread, DEFAULT_TIMEOUT); 272e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate } 273e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate 2746f357d3284a833cc50a990e14b39f389b8972254Jeff Brown public void addThread(Handler thread, long timeoutMillis) { 2758d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn synchronized (this) { 2768d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn if (isAlive()) { 2778d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn throw new RuntimeException("Threads can't be added once the Watchdog is running"); 2788d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn } 2796f357d3284a833cc50a990e14b39f389b8972254Jeff Brown final String name = thread.getLooper().getThread().getName(); 280e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate mHandlerCheckers.add(new HandlerChecker(thread, name, timeoutMillis)); 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Perform a full reboot of the system. 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void rebootSystem(String reason) { 2888a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.i(TAG, "Rebooting system because: " + reason); 2896f357d3284a833cc50a990e14b39f389b8972254Jeff Brown IPowerManager pms = (IPowerManager)ServiceManager.getService(Context.POWER_SERVICE); 2906f357d3284a833cc50a990e14b39f389b8972254Jeff Brown try { 2916f357d3284a833cc50a990e14b39f389b8972254Jeff Brown pms.reboot(false, reason, false); 2926f357d3284a833cc50a990e14b39f389b8972254Jeff Brown } catch (RemoteException ex) { 2936f357d3284a833cc50a990e14b39f389b8972254Jeff Brown } 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 296e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate private int evaluateCheckerCompletionLocked() { 297e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate int state = COMPLETED; 2988d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn for (int i=0; i<mHandlerCheckers.size(); i++) { 2998d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn HandlerChecker hc = mHandlerCheckers.get(i); 300e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate state = Math.max(state, hc.getCompletionStateLocked()); 3018d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn } 302e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate return state; 3038d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn } 3048d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn 305fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn private ArrayList<HandlerChecker> getBlockedCheckersLocked() { 306fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn ArrayList<HandlerChecker> checkers = new ArrayList<HandlerChecker>(); 3078d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn for (int i=0; i<mHandlerCheckers.size(); i++) { 3088d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn HandlerChecker hc = mHandlerCheckers.get(i); 309e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate if (hc.isOverdueLocked()) { 310fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn checkers.add(hc); 3118d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn } 3128d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn } 313fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn return checkers; 314fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn } 315fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn 316fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn private String describeCheckersLocked(ArrayList<HandlerChecker> checkers) { 317fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn StringBuilder builder = new StringBuilder(128); 318fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn for (int i=0; i<checkers.size(); i++) { 319fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn if (builder.length() > 0) { 320fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn builder.append(", "); 321fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn } 322fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn builder.append(checkers.get(i).describeBlockedStateLocked()); 323fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn } 3248d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn return builder.toString(); 3258d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn } 3268d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void run() { 3296ee412d51d8b601580cfb4b7be4f676b7ec76afdChristopher Tate boolean waitedHalf = false; 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (true) { 331fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn final ArrayList<HandlerChecker> blockedCheckers; 3327dd2d19725bac29306900a06818edf2f205ca051Jeff Brown final String subject; 3338bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn final boolean allowRestart; 33489ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn int debuggerWasConnected = 0; 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 336e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate long timeout = CHECK_INTERVAL; 337e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate // Make sure we (re)spin the checkers that have become idle within 338e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate // this wait-and-check interval 339e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate for (int i=0; i<mHandlerCheckers.size(); i++) { 340e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate HandlerChecker hc = mHandlerCheckers.get(i); 341e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate hc.scheduleCheckLocked(); 3428d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn } 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 34489ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn if (debuggerWasConnected > 0) { 34589ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn debuggerWasConnected--; 34689ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn } 34789ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // NOTE: We use uptimeMillis() here because we do not want to increment the time we 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // wait while asleep. If the device is asleep then the thing that we are waiting 3506ee412d51d8b601580cfb4b7be4f676b7ec76afdChristopher Tate // to timeout on is asleep as well and won't have a chance to run, causing a false 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // positive on when to kill things. 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long start = SystemClock.uptimeMillis(); 3538fa56f60a77f3e4eee38f2b107e3b2ef5b1f4e1eMichael Wright while (timeout > 0) { 35489ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn if (Debug.isDebuggerConnected()) { 35589ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn debuggerWasConnected = 2; 35689ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn } 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 3588fa56f60a77f3e4eee38f2b107e3b2ef5b1f4e1eMichael Wright wait(timeout); 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (InterruptedException e) { 3609bdc94b7a42a07d7dafcdf2cbadbb9c736b979d2Dan Egnor Log.wtf(TAG, e); 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 36289ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn if (Debug.isDebuggerConnected()) { 36389ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn debuggerWasConnected = 2; 36489ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn } 365e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate timeout = CHECK_INTERVAL - (SystemClock.uptimeMillis() - start); 3669bdc94b7a42a07d7dafcdf2cbadbb9c736b979d2Dan Egnor } 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 368e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate final int waitState = evaluateCheckerCompletionLocked(); 369e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate if (waitState == COMPLETED) { 370e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate // The monitors have returned; reset 3716ee412d51d8b601580cfb4b7be4f676b7ec76afdChristopher Tate waitedHalf = false; 3726ee412d51d8b601580cfb4b7be4f676b7ec76afdChristopher Tate continue; 373e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate } else if (waitState == WAITING) { 374e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate // still waiting but within their configured intervals; back off and recheck 375e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate continue; 376e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate } else if (waitState == WAITED_HALF) { 377e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate if (!waitedHalf) { 378e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate // We've waited half the deadlock-detection interval. Pull a stack 379e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate // trace and wait another half. 380e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate ArrayList<Integer> pids = new ArrayList<Integer>(); 381e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate pids.add(Process.myPid()); 382e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate ActivityManagerService.dumpStackTraces(true, pids, null, null, 383e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate NATIVE_STACKS_OF_INTEREST); 384e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate waitedHalf = true; 385e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate } 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3888fa56f60a77f3e4eee38f2b107e3b2ef5b1f4e1eMichael Wright 389e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate // something is overdue! 390fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn blockedCheckers = getBlockedCheckersLocked(); 3917dd2d19725bac29306900a06818edf2f205ca051Jeff Brown subject = describeCheckersLocked(blockedCheckers); 3928bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn allowRestart = mAllowRestart; 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If we got here, that means that the system is most likely hung. 396784827b27cf4cd82bf074b571e63cb5e660c54afJean-Baptiste Queru // First collect stack traces from all threads of the system process. 397784827b27cf4cd82bf074b571e63cb5e660c54afJean-Baptiste Queru // Then kill this process so that the system will restart. 3987dd2d19725bac29306900a06818edf2f205ca051Jeff Brown EventLog.writeEvent(EventLogTags.WATCHDOG, subject); 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4006b1afebdaca6c27d49a243c4283e5e2e4924de8cDianne Hackborn ArrayList<Integer> pids = new ArrayList<Integer>(); 4019bdc94b7a42a07d7dafcdf2cbadbb9c736b979d2Dan Egnor pids.add(Process.myPid()); 4024bded0744a07152c1e7ae4cb8110c74ec89a67b1Dan Egnor if (mPhonePid > 0) pids.add(mPhonePid); 4036ee412d51d8b601580cfb4b7be4f676b7ec76afdChristopher Tate // Pass !waitedHalf so that just in case we somehow wind up here without having 4046ee412d51d8b601580cfb4b7be4f676b7ec76afdChristopher Tate // dumped the halfway stacks, we properly re-initialize the trace file. 4059765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick final File stack = ActivityManagerService.dumpStackTraces( 406f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn !waitedHalf, pids, null, null, NATIVE_STACKS_OF_INTEREST); 4074bded0744a07152c1e7ae4cb8110c74ec89a67b1Dan Egnor 4084bded0744a07152c1e7ae4cb8110c74ec89a67b1Dan Egnor // Give some extra time to make sure the stack traces get written. 4094bded0744a07152c1e7ae4cb8110c74ec89a67b1Dan Egnor // The system's been hanging for a minute, another second or two won't hurt much. 4104bded0744a07152c1e7ae4cb8110c74ec89a67b1Dan Egnor SystemClock.sleep(2000); 4114bded0744a07152c1e7ae4cb8110c74ec89a67b1Dan Egnor 412ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate // Pull our own kernel thread stacks as well if we're configured for that 413ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate if (RECORD_KERNEL_THREADS) { 414ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate dumpKernelStackTraces(); 415ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate } 416ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate 4170620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu // Trigger the kernel to dump all blocked threads, and backtraces on all CPUs to the kernel log 4180620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu doSysRq('w'); 4190620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu doSysRq('l'); 4205df1d871feabee23b16a69ee48695fd892017517Colin Cross 4219765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick // Try to add the error to the dropbox, but assuming that the ActivityManager 4229765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick // itself may be deadlocked. (which has happened, causing this statement to 4239765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick // deadlock and the watchdog as a whole to be ineffective) 4249765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick Thread dropboxThread = new Thread("watchdogWriteToDropbox") { 4259765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick public void run() { 4269765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick mActivity.addErrorToDropBox( 427a353d2654a98b292469d2559cb4424b13d779924Jeff Sharkey "watchdog", null, "system_server", null, null, 4287dd2d19725bac29306900a06818edf2f205ca051Jeff Brown subject, null, stack, null); 4299765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick } 4309765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick }; 4319765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick dropboxThread.start(); 4329765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick try { 4339765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick dropboxThread.join(2000); // wait up to 2 seconds for it to return. 4349765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick } catch (InterruptedException ignored) {} 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4365b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn IActivityController controller; 4375b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn synchronized (this) { 4385b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn controller = mController; 4395b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn } 4405b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn if (controller != null) { 4415b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn Slog.i(TAG, "Reporting stuck state to activity controller"); 4425b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn try { 4435b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn Binder.setDumpDisabled("Service dumps disabled due to hung system process."); 4445b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn // 1 = keep waiting, -1 = kill system 4457dd2d19725bac29306900a06818edf2f205ca051Jeff Brown int res = controller.systemNotResponding(subject); 4465b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn if (res >= 0) { 4475b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn Slog.i(TAG, "Activity controller requested to coninue to wait"); 4485b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn waitedHalf = false; 4495b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn continue; 4505b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn } 4515b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn } catch (RemoteException e) { 4525b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn } 4535b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn } 4545b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn 455784827b27cf4cd82bf074b571e63cb5e660c54afJean-Baptiste Queru // Only kill the process if the debugger is not attached. 4568bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn if (Debug.isDebuggerConnected()) { 45789ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn debuggerWasConnected = 2; 45889ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn } 45989ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn if (debuggerWasConnected >= 2) { 4608bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn Slog.w(TAG, "Debugger connected: Watchdog is *not* killing the system process"); 46189ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn } else if (debuggerWasConnected > 0) { 46289ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn Slog.w(TAG, "Debugger was connected: Watchdog is *not* killing the system process"); 4638bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn } else if (!allowRestart) { 4648bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn Slog.w(TAG, "Restart not allowed: Watchdog is *not* killing the system process"); 4658bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn } else { 4667dd2d19725bac29306900a06818edf2f205ca051Jeff Brown Slog.w(TAG, "*** WATCHDOG KILLING SYSTEM PROCESS: " + subject); 467fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn for (int i=0; i<blockedCheckers.size(); i++) { 468fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn Slog.w(TAG, blockedCheckers.get(i).getName() + " stack trace:"); 469fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn StackTraceElement[] stackTrace 470fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn = blockedCheckers.get(i).getThread().getStackTrace(); 471fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn for (StackTraceElement element: stackTrace) { 472fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn Slog.w(TAG, " at " + element); 473fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn } 47456a6c66158b1ba26626a161ed782724fb1e3cea1Michael Wright } 475fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn Slog.w(TAG, "*** GOODBYE!"); 476784827b27cf4cd82bf074b571e63cb5e660c54afJean-Baptiste Queru Process.killProcess(Process.myPid()); 477784827b27cf4cd82bf074b571e63cb5e660c54afJean-Baptiste Queru System.exit(10); 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4796ee412d51d8b601580cfb4b7be4f676b7ec76afdChristopher Tate 4806ee412d51d8b601580cfb4b7be4f676b7ec76afdChristopher Tate waitedHalf = false; 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 483ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate 4840620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu private void doSysRq(char c) { 4850620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu try { 4860620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu FileWriter sysrq_trigger = new FileWriter("/proc/sysrq-trigger"); 4870620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu sysrq_trigger.write(c); 4880620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu sysrq_trigger.close(); 4890620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu } catch (IOException e) { 4900620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu Slog.w(TAG, "Failed to write to /proc/sysrq-trigger", e); 4910620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu } 4920620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu } 4930620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu 494ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate private File dumpKernelStackTraces() { 495ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 496ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate if (tracesPath == null || tracesPath.length() == 0) { 497ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate return null; 498ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate } 499ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate 500ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate native_dumpKernelStacks(tracesPath); 501ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate return new File(tracesPath); 502ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate } 503ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate 504ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate private native void native_dumpKernelStacks(String tracesPath); 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 506