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[] { 673a64ecb7fdb67e7fe8c565fa972140d2c0f7c4e2Andy Hung "/system/bin/audioserver", 68689574ad4a3cebe5ad6993621fa19554fb392674Andy Hung "/system/bin/cameraserver", 69689574ad4a3cebe5ad6993621fa19554fb392674Andy Hung "/system/bin/drmserver", 70689574ad4a3cebe5ad6993621fa19554fb392674Andy Hung "/system/bin/mediadrmserver", 71f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn "/system/bin/mediaserver", 72f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn "/system/bin/sdcard", 7305d4e35c8e9cf67127630a2ee4376295f275b682Eric Laurent "/system/bin/surfaceflinger", 74689574ad4a3cebe5ad6993621fa19554fb392674Andy Hung "media.codec", // system/bin/mediacodec 75689574ad4a3cebe5ad6993621fa19554fb392674Andy Hung "media.extractor", // system/bin/mediaextractor 76cf9e79b90192d1a1ece3264b021d3256a2fffefeAndreas Gampe "com.android.bluetooth", // Bluetooth service 77f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn }; 78f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static Watchdog sWatchdog; 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* This handler will be used to post message back onto the main thread */ 82d7fdd0228e6abdbc079f9cf08b780e4222dfe7c5Wale Ogunwale final ArrayList<HandlerChecker> mHandlerCheckers = new ArrayList<>(); 838d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn final HandlerChecker mMonitorChecker; 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ContentResolver mResolver; 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ActivityManagerService mActivity; 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mPhonePid; 885b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn IActivityController mController; 898bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn boolean mAllowRestart = true; 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 928d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn * Used for checking status of handle threads and scheduling monitor callbacks. 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 948d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn public final class HandlerChecker implements Runnable { 958d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn private final Handler mHandler; 968d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn private final String mName; 97e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate private final long mWaitMax; 988d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn private final ArrayList<Monitor> mMonitors = new ArrayList<Monitor>(); 998d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn private boolean mCompleted; 1008d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn private Monitor mCurrentMonitor; 101e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate private long mStartTime; 1028d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn 103e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate HandlerChecker(Handler handler, String name, long waitMaxMillis) { 1048d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn mHandler = handler; 1058d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn mName = name; 106e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate mWaitMax = waitMaxMillis; 107e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate mCompleted = true; 1088d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn } 1098d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn 1108d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn public void addMonitor(Monitor monitor) { 1118d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn mMonitors.add(monitor); 1128d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn } 1138d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn 1148d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn public void scheduleCheckLocked() { 1156c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown if (mMonitors.size() == 0 && mHandler.getLooper().getQueue().isPolling()) { 1166c7b41adf9e937a66880b8906389760f3fc82a08Jeff Brown // If the target looper has recently been polling, then 117efa92b2182ab581873aa8e75d596e2e363bd5e6dDianne Hackborn // there is no reason to enqueue our checker on it since that 118efa92b2182ab581873aa8e75d596e2e363bd5e6dDianne Hackborn // is as good as it not being deadlocked. This avoid having 119efa92b2182ab581873aa8e75d596e2e363bd5e6dDianne Hackborn // to do a context switch to check the thread. Note that we 120efa92b2182ab581873aa8e75d596e2e363bd5e6dDianne Hackborn // only do this if mCheckReboot is false and we have no 121efa92b2182ab581873aa8e75d596e2e363bd5e6dDianne Hackborn // monitors, since those would need to be executed at this point. 122efa92b2182ab581873aa8e75d596e2e363bd5e6dDianne Hackborn mCompleted = true; 123efa92b2182ab581873aa8e75d596e2e363bd5e6dDianne Hackborn return; 124efa92b2182ab581873aa8e75d596e2e363bd5e6dDianne Hackborn } 125e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate 126e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate if (!mCompleted) { 127e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate // we already have a check in flight, so no need 128e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate return; 129e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate } 130e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate 1318d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn mCompleted = false; 1328d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn mCurrentMonitor = null; 133e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate mStartTime = SystemClock.uptimeMillis(); 1348d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn mHandler.postAtFrontOfQueue(this); 1358d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn } 1368d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn 137e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate public boolean isOverdueLocked() { 138e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate return (!mCompleted) && (SystemClock.uptimeMillis() > mStartTime + mWaitMax); 139e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate } 140e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate 141e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate public int getCompletionStateLocked() { 142e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate if (mCompleted) { 143e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate return COMPLETED; 144e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate } else { 145e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate long latency = SystemClock.uptimeMillis() - mStartTime; 146e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate if (latency < mWaitMax/2) { 147e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate return WAITING; 148e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate } else if (latency < mWaitMax) { 149e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate return WAITED_HALF; 150e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate } 151e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate } 152e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate return OVERDUE; 1538d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn } 1548d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn 155fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn public Thread getThread() { 156fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn return mHandler.getLooper().getThread(); 157fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn } 158fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn 159fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn public String getName() { 160fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn return mName; 161fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn } 162fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn 1638d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn public String describeBlockedStateLocked() { 1647dd2d19725bac29306900a06818edf2f205ca051Jeff Brown if (mCurrentMonitor == null) { 1657dd2d19725bac29306900a06818edf2f205ca051Jeff Brown return "Blocked in handler on " + mName + " (" + getThread().getName() + ")"; 1667dd2d19725bac29306900a06818edf2f205ca051Jeff Brown } else { 1677dd2d19725bac29306900a06818edf2f205ca051Jeff Brown return "Blocked in monitor " + mCurrentMonitor.getClass().getName() 1687dd2d19725bac29306900a06818edf2f205ca051Jeff Brown + " on " + mName + " (" + getThread().getName() + ")"; 1697dd2d19725bac29306900a06818edf2f205ca051Jeff Brown } 170116415271b952ab9e842f3850faa1a44cb70bf6aJohn Michelau } 171116415271b952ab9e842f3850faa1a44cb70bf6aJohn Michelau 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1738d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn public void run() { 1748d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn final int size = mMonitors.size(); 1758d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn for (int i = 0 ; i < size ; i++) { 1768d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn synchronized (Watchdog.this) { 1778d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn mCurrentMonitor = mMonitors.get(i); 1788d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn } 1798d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn mCurrentMonitor.monitor(); 1808d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn } 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1828d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn synchronized (Watchdog.this) { 1838d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn mCompleted = true; 1848d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn mCurrentMonitor = null; 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final class RebootRequestReceiver extends BroadcastReceiver { 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onReceive(Context c, Intent intent) { 192f6438b16ba81a0179b789ca4fc66e8016bf6a96dDianne Hackborn if (intent.getIntExtra("nowait", 0) != 0) { 193f6438b16ba81a0179b789ca4fc66e8016bf6a96dDianne Hackborn rebootSystem("Received ACTION_REBOOT broadcast"); 194f6438b16ba81a0179b789ca4fc66e8016bf6a96dDianne Hackborn return; 195f6438b16ba81a0179b789ca4fc66e8016bf6a96dDianne Hackborn } 196f6438b16ba81a0179b789ca4fc66e8016bf6a96dDianne Hackborn Slog.w(TAG, "Unsupported ACTION_REBOOT broadcast: " + intent); 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 200517daeccb29ce42b1ec4b366e7807088cad3f5edWale Ogunwale /** Monitor for checking the availability of binder threads. The monitor will block until 201517daeccb29ce42b1ec4b366e7807088cad3f5edWale Ogunwale * there is a binder thread available to process in coming IPCs to make sure other processes 202517daeccb29ce42b1ec4b366e7807088cad3f5edWale Ogunwale * can still communicate with the service. 203517daeccb29ce42b1ec4b366e7807088cad3f5edWale Ogunwale */ 204517daeccb29ce42b1ec4b366e7807088cad3f5edWale Ogunwale private static final class BinderThreadMonitor implements Watchdog.Monitor { 205517daeccb29ce42b1ec4b366e7807088cad3f5edWale Ogunwale @Override 206517daeccb29ce42b1ec4b366e7807088cad3f5edWale Ogunwale public void monitor() { 207517daeccb29ce42b1ec4b366e7807088cad3f5edWale Ogunwale Binder.blockUntilThreadAvailable(); 208517daeccb29ce42b1ec4b366e7807088cad3f5edWale Ogunwale } 209517daeccb29ce42b1ec4b366e7807088cad3f5edWale Ogunwale } 210517daeccb29ce42b1ec4b366e7807088cad3f5edWale Ogunwale 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public interface Monitor { 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void monitor(); 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static Watchdog getInstance() { 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sWatchdog == null) { 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sWatchdog = new Watchdog(); 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return sWatchdog; 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Watchdog() { 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super("watchdog"); 2258d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn // Initialize handler checkers for each common thread we want to check. Note 2268d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn // that we are not currently checking the background thread, since it can 2278d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn // potentially hold longer running operations with no guarantees about the timeliness 2288d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn // of operations there. 2298d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn 2308d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn // The shared foreground thread is the main checker. It is where we 2318d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn // will also dispatch monitor checks and do other work. 232e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate mMonitorChecker = new HandlerChecker(FgThread.getHandler(), 233e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate "foreground thread", DEFAULT_TIMEOUT); 2348d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn mHandlerCheckers.add(mMonitorChecker); 2358d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn // Add checker for main thread. We only do a quick check since there 2368d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn // can be UI running on the thread. 2378d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn mHandlerCheckers.add(new HandlerChecker(new Handler(Looper.getMainLooper()), 238e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate "main thread", DEFAULT_TIMEOUT)); 2398d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn // Add checker for shared UI thread. 240e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate mHandlerCheckers.add(new HandlerChecker(UiThread.getHandler(), 241e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate "ui thread", DEFAULT_TIMEOUT)); 2428d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn // And also check IO thread. 243e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate mHandlerCheckers.add(new HandlerChecker(IoThread.getHandler(), 244e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate "i/o thread", DEFAULT_TIMEOUT)); 2454ccb823a9f62e57f9d221f83a97e82967e79a9e5Jeff Brown // And the display thread. 2464ccb823a9f62e57f9d221f83a97e82967e79a9e5Jeff Brown mHandlerCheckers.add(new HandlerChecker(DisplayThread.getHandler(), 2474ccb823a9f62e57f9d221f83a97e82967e79a9e5Jeff Brown "display thread", DEFAULT_TIMEOUT)); 248517daeccb29ce42b1ec4b366e7807088cad3f5edWale Ogunwale 249517daeccb29ce42b1ec4b366e7807088cad3f5edWale Ogunwale // Initialize monitor for Binder threads. 250517daeccb29ce42b1ec4b366e7807088cad3f5edWale Ogunwale addMonitor(new BinderThreadMonitor()); 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 253182f73fc4da13a6417e5086ec9ecce80eb8423caAdam Lesinski public void init(Context context, ActivityManagerService activity) { 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mResolver = context.getContentResolver(); 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mActivity = activity; 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project context.registerReceiver(new RebootRequestReceiver(), 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new IntentFilter(Intent.ACTION_REBOOT), 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android.Manifest.permission.REBOOT, null); 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 262c27181c7f3e11170ec82807cfa416f0a906ff574Christopher Tate public void processStarted(String name, int pid) { 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ("com.android.phone".equals(name)) { 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPhonePid = pid; 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2705b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn public void setActivityController(IActivityController controller) { 2715b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn synchronized (this) { 2725b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn mController = controller; 2735b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn } 2745b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn } 2755b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn 2768bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn public void setAllowRestart(boolean allowRestart) { 2778bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn synchronized (this) { 2788bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn mAllowRestart = allowRestart; 2798bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn } 2808bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn } 2818bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void addMonitor(Monitor monitor) { 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isAlive()) { 2858d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn throw new RuntimeException("Monitors can't be added once the Watchdog is running"); 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2878d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn mMonitorChecker.addMonitor(monitor); 2888d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn } 2898d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn } 2908d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn 2916f357d3284a833cc50a990e14b39f389b8972254Jeff Brown public void addThread(Handler thread) { 2926f357d3284a833cc50a990e14b39f389b8972254Jeff Brown addThread(thread, DEFAULT_TIMEOUT); 293e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate } 294e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate 2956f357d3284a833cc50a990e14b39f389b8972254Jeff Brown public void addThread(Handler thread, long timeoutMillis) { 2968d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn synchronized (this) { 2978d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn if (isAlive()) { 2988d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn throw new RuntimeException("Threads can't be added once the Watchdog is running"); 2998d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn } 3006f357d3284a833cc50a990e14b39f389b8972254Jeff Brown final String name = thread.getLooper().getThread().getName(); 301e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate mHandlerCheckers.add(new HandlerChecker(thread, name, timeoutMillis)); 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Perform a full reboot of the system. 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void rebootSystem(String reason) { 3098a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.i(TAG, "Rebooting system because: " + reason); 3106f357d3284a833cc50a990e14b39f389b8972254Jeff Brown IPowerManager pms = (IPowerManager)ServiceManager.getService(Context.POWER_SERVICE); 3116f357d3284a833cc50a990e14b39f389b8972254Jeff Brown try { 3126f357d3284a833cc50a990e14b39f389b8972254Jeff Brown pms.reboot(false, reason, false); 3136f357d3284a833cc50a990e14b39f389b8972254Jeff Brown } catch (RemoteException ex) { 3146f357d3284a833cc50a990e14b39f389b8972254Jeff Brown } 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 317e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate private int evaluateCheckerCompletionLocked() { 318e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate int state = COMPLETED; 3198d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn for (int i=0; i<mHandlerCheckers.size(); i++) { 3208d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn HandlerChecker hc = mHandlerCheckers.get(i); 321e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate state = Math.max(state, hc.getCompletionStateLocked()); 3228d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn } 323e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate return state; 3248d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn } 3258d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn 326fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn private ArrayList<HandlerChecker> getBlockedCheckersLocked() { 327fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn ArrayList<HandlerChecker> checkers = new ArrayList<HandlerChecker>(); 3288d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn for (int i=0; i<mHandlerCheckers.size(); i++) { 3298d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn HandlerChecker hc = mHandlerCheckers.get(i); 330e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate if (hc.isOverdueLocked()) { 331fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn checkers.add(hc); 3328d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn } 3338d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn } 334fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn return checkers; 335fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn } 336fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn 337fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn private String describeCheckersLocked(ArrayList<HandlerChecker> checkers) { 338fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn StringBuilder builder = new StringBuilder(128); 339fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn for (int i=0; i<checkers.size(); i++) { 340fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn if (builder.length() > 0) { 341fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn builder.append(", "); 342fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn } 343fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn builder.append(checkers.get(i).describeBlockedStateLocked()); 344fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn } 3458d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn return builder.toString(); 3468d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn } 3478d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void run() { 3506ee412d51d8b601580cfb4b7be4f676b7ec76afdChristopher Tate boolean waitedHalf = false; 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (true) { 352fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn final ArrayList<HandlerChecker> blockedCheckers; 3537dd2d19725bac29306900a06818edf2f205ca051Jeff Brown final String subject; 3548bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn final boolean allowRestart; 35589ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn int debuggerWasConnected = 0; 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 357e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate long timeout = CHECK_INTERVAL; 358e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate // Make sure we (re)spin the checkers that have become idle within 359e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate // this wait-and-check interval 360e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate for (int i=0; i<mHandlerCheckers.size(); i++) { 361e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate HandlerChecker hc = mHandlerCheckers.get(i); 362e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate hc.scheduleCheckLocked(); 3638d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn } 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 36589ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn if (debuggerWasConnected > 0) { 36689ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn debuggerWasConnected--; 36789ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn } 36889ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // NOTE: We use uptimeMillis() here because we do not want to increment the time we 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // wait while asleep. If the device is asleep then the thing that we are waiting 3716ee412d51d8b601580cfb4b7be4f676b7ec76afdChristopher Tate // to timeout on is asleep as well and won't have a chance to run, causing a false 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // positive on when to kill things. 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long start = SystemClock.uptimeMillis(); 3748fa56f60a77f3e4eee38f2b107e3b2ef5b1f4e1eMichael Wright while (timeout > 0) { 37589ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn if (Debug.isDebuggerConnected()) { 37689ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn debuggerWasConnected = 2; 37789ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn } 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 3798fa56f60a77f3e4eee38f2b107e3b2ef5b1f4e1eMichael Wright wait(timeout); 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (InterruptedException e) { 3819bdc94b7a42a07d7dafcdf2cbadbb9c736b979d2Dan Egnor Log.wtf(TAG, e); 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 38389ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn if (Debug.isDebuggerConnected()) { 38489ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn debuggerWasConnected = 2; 38589ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn } 386e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate timeout = CHECK_INTERVAL - (SystemClock.uptimeMillis() - start); 3879bdc94b7a42a07d7dafcdf2cbadbb9c736b979d2Dan Egnor } 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 389e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate final int waitState = evaluateCheckerCompletionLocked(); 390e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate if (waitState == COMPLETED) { 391e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate // The monitors have returned; reset 3926ee412d51d8b601580cfb4b7be4f676b7ec76afdChristopher Tate waitedHalf = false; 3936ee412d51d8b601580cfb4b7be4f676b7ec76afdChristopher Tate continue; 394e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate } else if (waitState == WAITING) { 395e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate // still waiting but within their configured intervals; back off and recheck 396e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate continue; 397e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate } else if (waitState == WAITED_HALF) { 398e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate if (!waitedHalf) { 399e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate // We've waited half the deadlock-detection interval. Pull a stack 400e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate // trace and wait another half. 401e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate ArrayList<Integer> pids = new ArrayList<Integer>(); 402e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate pids.add(Process.myPid()); 403e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate ActivityManagerService.dumpStackTraces(true, pids, null, null, 404e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate NATIVE_STACKS_OF_INTEREST); 405e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate waitedHalf = true; 406e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate } 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4098fa56f60a77f3e4eee38f2b107e3b2ef5b1f4e1eMichael Wright 410e6f81cf1f69e0683f969238f921950befba8e6c3Christopher Tate // something is overdue! 411fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn blockedCheckers = getBlockedCheckersLocked(); 4127dd2d19725bac29306900a06818edf2f205ca051Jeff Brown subject = describeCheckersLocked(blockedCheckers); 4138bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn allowRestart = mAllowRestart; 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If we got here, that means that the system is most likely hung. 417784827b27cf4cd82bf074b571e63cb5e660c54afJean-Baptiste Queru // First collect stack traces from all threads of the system process. 418784827b27cf4cd82bf074b571e63cb5e660c54afJean-Baptiste Queru // Then kill this process so that the system will restart. 4197dd2d19725bac29306900a06818edf2f205ca051Jeff Brown EventLog.writeEvent(EventLogTags.WATCHDOG, subject); 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4216b1afebdaca6c27d49a243c4283e5e2e4924de8cDianne Hackborn ArrayList<Integer> pids = new ArrayList<Integer>(); 4229bdc94b7a42a07d7dafcdf2cbadbb9c736b979d2Dan Egnor pids.add(Process.myPid()); 4234bded0744a07152c1e7ae4cb8110c74ec89a67b1Dan Egnor if (mPhonePid > 0) pids.add(mPhonePid); 4246ee412d51d8b601580cfb4b7be4f676b7ec76afdChristopher Tate // Pass !waitedHalf so that just in case we somehow wind up here without having 4256ee412d51d8b601580cfb4b7be4f676b7ec76afdChristopher Tate // dumped the halfway stacks, we properly re-initialize the trace file. 4269765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick final File stack = ActivityManagerService.dumpStackTraces( 427f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn !waitedHalf, pids, null, null, NATIVE_STACKS_OF_INTEREST); 4284bded0744a07152c1e7ae4cb8110c74ec89a67b1Dan Egnor 4294bded0744a07152c1e7ae4cb8110c74ec89a67b1Dan Egnor // Give some extra time to make sure the stack traces get written. 4304bded0744a07152c1e7ae4cb8110c74ec89a67b1Dan Egnor // The system's been hanging for a minute, another second or two won't hurt much. 4314bded0744a07152c1e7ae4cb8110c74ec89a67b1Dan Egnor SystemClock.sleep(2000); 4324bded0744a07152c1e7ae4cb8110c74ec89a67b1Dan Egnor 433ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate // Pull our own kernel thread stacks as well if we're configured for that 434ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate if (RECORD_KERNEL_THREADS) { 435ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate dumpKernelStackTraces(); 436ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate } 437ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate 4380620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu // Trigger the kernel to dump all blocked threads, and backtraces on all CPUs to the kernel log 4390620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu doSysRq('w'); 4400620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu doSysRq('l'); 4415df1d871feabee23b16a69ee48695fd892017517Colin Cross 4429765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick // Try to add the error to the dropbox, but assuming that the ActivityManager 4439765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick // itself may be deadlocked. (which has happened, causing this statement to 4449765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick // deadlock and the watchdog as a whole to be ineffective) 4459765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick Thread dropboxThread = new Thread("watchdogWriteToDropbox") { 4469765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick public void run() { 4479765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick mActivity.addErrorToDropBox( 448a353d2654a98b292469d2559cb4424b13d779924Jeff Sharkey "watchdog", null, "system_server", null, null, 4497dd2d19725bac29306900a06818edf2f205ca051Jeff Brown subject, null, stack, null); 4509765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick } 4519765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick }; 4529765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick dropboxThread.start(); 4539765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick try { 4549765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick dropboxThread.join(2000); // wait up to 2 seconds for it to return. 4559765c72eeaba9ed0f704dd992e7a954f38f20abdBrad Fitzpatrick } catch (InterruptedException ignored) {} 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4575b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn IActivityController controller; 4585b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn synchronized (this) { 4595b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn controller = mController; 4605b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn } 4615b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn if (controller != null) { 4625b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn Slog.i(TAG, "Reporting stuck state to activity controller"); 4635b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn try { 4645b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn Binder.setDumpDisabled("Service dumps disabled due to hung system process."); 4655b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn // 1 = keep waiting, -1 = kill system 4667dd2d19725bac29306900a06818edf2f205ca051Jeff Brown int res = controller.systemNotResponding(subject); 4675b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn if (res >= 0) { 4685b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn Slog.i(TAG, "Activity controller requested to coninue to wait"); 4695b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn waitedHalf = false; 4705b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn continue; 4715b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn } 4725b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn } catch (RemoteException e) { 4735b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn } 4745b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn } 4755b88a2fd7b77880f6e09ae4a1de509bebe28bc3aDianne Hackborn 476784827b27cf4cd82bf074b571e63cb5e660c54afJean-Baptiste Queru // Only kill the process if the debugger is not attached. 4778bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn if (Debug.isDebuggerConnected()) { 47889ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn debuggerWasConnected = 2; 47989ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn } 48089ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn if (debuggerWasConnected >= 2) { 4818bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn Slog.w(TAG, "Debugger connected: Watchdog is *not* killing the system process"); 48289ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn } else if (debuggerWasConnected > 0) { 48389ad456ea49cb62615ebdcac83a2515743bbe5faDianne Hackborn Slog.w(TAG, "Debugger was connected: Watchdog is *not* killing the system process"); 4848bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn } else if (!allowRestart) { 4858bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn Slog.w(TAG, "Restart not allowed: Watchdog is *not* killing the system process"); 4868bd64df2adb26fe9547ae3961a58631e241b613eDianne Hackborn } else { 4877dd2d19725bac29306900a06818edf2f205ca051Jeff Brown Slog.w(TAG, "*** WATCHDOG KILLING SYSTEM PROCESS: " + subject); 488fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn for (int i=0; i<blockedCheckers.size(); i++) { 489fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn Slog.w(TAG, blockedCheckers.get(i).getName() + " stack trace:"); 490fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn StackTraceElement[] stackTrace 491fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn = blockedCheckers.get(i).getThread().getStackTrace(); 492fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn for (StackTraceElement element: stackTrace) { 493fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn Slog.w(TAG, " at " + element); 494fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn } 49556a6c66158b1ba26626a161ed782724fb1e3cea1Michael Wright } 496fa012b35b8d51889c8b0239ef9894bc7ebf92de8Dianne Hackborn Slog.w(TAG, "*** GOODBYE!"); 497784827b27cf4cd82bf074b571e63cb5e660c54afJean-Baptiste Queru Process.killProcess(Process.myPid()); 498784827b27cf4cd82bf074b571e63cb5e660c54afJean-Baptiste Queru System.exit(10); 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5006ee412d51d8b601580cfb4b7be4f676b7ec76afdChristopher Tate 5016ee412d51d8b601580cfb4b7be4f676b7ec76afdChristopher Tate waitedHalf = false; 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 504ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate 5050620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu private void doSysRq(char c) { 5060620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu try { 5070620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu FileWriter sysrq_trigger = new FileWriter("/proc/sysrq-trigger"); 5080620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu sysrq_trigger.write(c); 5090620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu sysrq_trigger.close(); 5100620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu } catch (IOException e) { 5110620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu Slog.w(TAG, "Failed to write to /proc/sysrq-trigger", e); 5120620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu } 5130620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu } 5140620c451da6728e7a2e78c2dc921a76490d7b7d8Guang Zhu 515ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate private File dumpKernelStackTraces() { 516ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 517ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate if (tracesPath == null || tracesPath.length() == 0) { 518ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate return null; 519ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate } 520ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate 521ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate native_dumpKernelStacks(tracesPath); 522ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate return new File(tracesPath); 523ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate } 524ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate 525ecaa7b41ca49154ceaa9a7504eb0a86b89a96026Christopher Tate private native void native_dumpKernelStacks(String tracesPath); 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 527