blob: feb9ce49bf0835a7b3d2f1273d5776b6e822296e [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server;
18
Dianne Hackborn5b88a2f2013-05-03 16:25:11 -070019import android.app.IActivityController;
20import android.os.Binder;
21import android.os.RemoteException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022import com.android.server.am.ActivityManagerService;
23
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080024import android.content.BroadcastReceiver;
25import android.content.ContentResolver;
26import android.content.Context;
27import android.content.Intent;
28import android.content.IntentFilter;
Steven Moreland6b47c542017-03-21 12:52:16 -070029import android.hidl.manager.V1_0.IServiceManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030import android.os.Debug;
31import android.os.Handler;
Jeff Brown6f357d32014-01-15 20:40:55 -080032import android.os.IPowerManager;
John Michelau11641522013-03-18 18:28:23 -050033import android.os.Looper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080034import android.os.Process;
Suchi Amalapurapu6ffce2e2010-03-08 14:48:40 -080035import android.os.ServiceManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080036import android.os.SystemClock;
37import android.os.SystemProperties;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080038import android.util.EventLog;
Dan Egnor9bdc94b2010-03-04 14:20:31 -080039import android.util.Log;
Joe Onorato8a9b2202010-02-26 18:56:32 -080040import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041
Dan Egnor9bdc94b2010-03-04 14:20:31 -080042import java.io.File;
Colin Cross5df1d872012-11-29 11:42:11 -080043import java.io.FileWriter;
44import java.io.IOException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080045import java.util.ArrayList;
Steven Moreland6b47c542017-03-21 12:52:16 -070046import java.util.Arrays;
47import java.util.HashSet;
48import java.util.List;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080049
50/** This class calls its monitor every minute. Killing this process if they don't return **/
51public class Watchdog extends Thread {
52 static final String TAG = "Watchdog";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080053
54 // Set this to true to use debug default values.
55 static final boolean DB = false;
56
Christopher Tateecaa7b42010-06-04 14:55:02 -070057 // Set this to true to have the watchdog record kernel thread stacks when it fires
58 static final boolean RECORD_KERNEL_THREADS = true;
59
Christopher Tatee6f81cf2013-10-23 17:28:27 -070060 static final long DEFAULT_TIMEOUT = DB ? 10*1000 : 60*1000;
61 static final long CHECK_INTERVAL = DEFAULT_TIMEOUT / 2;
62
63 // These are temporally ordered: larger values as lateness increases
64 static final int COMPLETED = 0;
65 static final int WAITING = 1;
66 static final int WAITED_HALF = 2;
67 static final int OVERDUE = 3;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080068
Igor Murashkin44d04aa2013-10-23 10:56:02 -070069 // Which native processes to dump into dropbox's stack traces
70 public static final String[] NATIVE_STACKS_OF_INTEREST = new String[] {
Andy Hung3a64ecb2016-03-09 13:55:58 -080071 "/system/bin/audioserver",
Andy Hung689574a2016-04-13 19:27:43 -070072 "/system/bin/cameraserver",
73 "/system/bin/drmserver",
74 "/system/bin/mediadrmserver",
Dianne Hackbornf72467a2012-06-08 17:23:59 -070075 "/system/bin/mediaserver",
76 "/system/bin/sdcard",
Eric Laurent05d4e352016-03-14 18:49:08 -070077 "/system/bin/surfaceflinger",
Andy Hung689574a2016-04-13 19:27:43 -070078 "media.extractor", // system/bin/mediaextractor
Andreas Gampecf9e79b2016-05-11 18:41:25 -070079 "com.android.bluetooth", // Bluetooth service
Dianne Hackbornf72467a2012-06-08 17:23:59 -070080 };
81
Steven Moreland6b47c542017-03-21 12:52:16 -070082 public static final List<String> HAL_INTERFACES_OF_INTEREST = Arrays.asList(
83 "android.hardware.audio@2.0::IDevicesFactory",
84 "android.hardware.bluetooth@1.0::IBluetoothHci",
85 "android.hardware.camera.provider@2.4::ICameraProvider",
Chia-I Wu74debcd2017-04-21 11:14:22 -070086 "android.hardware.graphics.composer@2.1::IComposer",
Steven Moreland6b47c542017-03-21 12:52:16 -070087 "android.hardware.vr@1.0::IVr",
88 "android.hardware.media.omx@1.0::IOmx"
89 );
90
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080091 static Watchdog sWatchdog;
92
93 /* This handler will be used to post message back onto the main thread */
Wale Ogunwaled7fdd022015-04-13 16:22:38 -070094 final ArrayList<HandlerChecker> mHandlerCheckers = new ArrayList<>();
Dianne Hackborn8d044e82013-04-30 17:24:15 -070095 final HandlerChecker mMonitorChecker;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080096 ContentResolver mResolver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080097 ActivityManagerService mActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080098
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080099 int mPhonePid;
Dianne Hackborn5b88a2f2013-05-03 16:25:11 -0700100 IActivityController mController;
Dianne Hackborn8bd64df2013-05-06 16:07:26 -0700101 boolean mAllowRestart = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800102
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800103 /**
Dianne Hackborn8d044e82013-04-30 17:24:15 -0700104 * Used for checking status of handle threads and scheduling monitor callbacks.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105 */
Dianne Hackborn8d044e82013-04-30 17:24:15 -0700106 public final class HandlerChecker implements Runnable {
107 private final Handler mHandler;
108 private final String mName;
Christopher Tatee6f81cf2013-10-23 17:28:27 -0700109 private final long mWaitMax;
Dianne Hackborn8d044e82013-04-30 17:24:15 -0700110 private final ArrayList<Monitor> mMonitors = new ArrayList<Monitor>();
Dianne Hackborn8d044e82013-04-30 17:24:15 -0700111 private boolean mCompleted;
112 private Monitor mCurrentMonitor;
Christopher Tatee6f81cf2013-10-23 17:28:27 -0700113 private long mStartTime;
Dianne Hackborn8d044e82013-04-30 17:24:15 -0700114
Christopher Tatee6f81cf2013-10-23 17:28:27 -0700115 HandlerChecker(Handler handler, String name, long waitMaxMillis) {
Dianne Hackborn8d044e82013-04-30 17:24:15 -0700116 mHandler = handler;
117 mName = name;
Christopher Tatee6f81cf2013-10-23 17:28:27 -0700118 mWaitMax = waitMaxMillis;
119 mCompleted = true;
Dianne Hackborn8d044e82013-04-30 17:24:15 -0700120 }
121
122 public void addMonitor(Monitor monitor) {
123 mMonitors.add(monitor);
124 }
125
126 public void scheduleCheckLocked() {
Jeff Brown6c7b41a2015-02-26 14:43:53 -0800127 if (mMonitors.size() == 0 && mHandler.getLooper().getQueue().isPolling()) {
128 // If the target looper has recently been polling, then
Dianne Hackbornefa92b22013-05-03 14:11:43 -0700129 // there is no reason to enqueue our checker on it since that
130 // is as good as it not being deadlocked. This avoid having
131 // to do a context switch to check the thread. Note that we
132 // only do this if mCheckReboot is false and we have no
133 // monitors, since those would need to be executed at this point.
134 mCompleted = true;
135 return;
136 }
Christopher Tatee6f81cf2013-10-23 17:28:27 -0700137
138 if (!mCompleted) {
139 // we already have a check in flight, so no need
140 return;
141 }
142
Dianne Hackborn8d044e82013-04-30 17:24:15 -0700143 mCompleted = false;
144 mCurrentMonitor = null;
Christopher Tatee6f81cf2013-10-23 17:28:27 -0700145 mStartTime = SystemClock.uptimeMillis();
Dianne Hackborn8d044e82013-04-30 17:24:15 -0700146 mHandler.postAtFrontOfQueue(this);
147 }
148
Christopher Tatee6f81cf2013-10-23 17:28:27 -0700149 public boolean isOverdueLocked() {
150 return (!mCompleted) && (SystemClock.uptimeMillis() > mStartTime + mWaitMax);
151 }
152
153 public int getCompletionStateLocked() {
154 if (mCompleted) {
155 return COMPLETED;
156 } else {
157 long latency = SystemClock.uptimeMillis() - mStartTime;
158 if (latency < mWaitMax/2) {
159 return WAITING;
160 } else if (latency < mWaitMax) {
161 return WAITED_HALF;
162 }
163 }
164 return OVERDUE;
Dianne Hackborn8d044e82013-04-30 17:24:15 -0700165 }
166
Dianne Hackbornfa012b32013-05-10 15:23:28 -0700167 public Thread getThread() {
168 return mHandler.getLooper().getThread();
169 }
170
171 public String getName() {
172 return mName;
173 }
174
Dianne Hackborn8d044e82013-04-30 17:24:15 -0700175 public String describeBlockedStateLocked() {
Jeff Brown7dd2d192013-09-06 15:05:23 -0700176 if (mCurrentMonitor == null) {
177 return "Blocked in handler on " + mName + " (" + getThread().getName() + ")";
178 } else {
179 return "Blocked in monitor " + mCurrentMonitor.getClass().getName()
180 + " on " + mName + " (" + getThread().getName() + ")";
181 }
John Michelau11641522013-03-18 18:28:23 -0500182 }
183
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800184 @Override
Dianne Hackborn8d044e82013-04-30 17:24:15 -0700185 public void run() {
Dianne Hackborn8d044e82013-04-30 17:24:15 -0700186 final int size = mMonitors.size();
187 for (int i = 0 ; i < size ; i++) {
188 synchronized (Watchdog.this) {
189 mCurrentMonitor = mMonitors.get(i);
190 }
191 mCurrentMonitor.monitor();
192 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800193
Dianne Hackborn8d044e82013-04-30 17:24:15 -0700194 synchronized (Watchdog.this) {
195 mCompleted = true;
196 mCurrentMonitor = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800197 }
198 }
199 }
200
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800201 final class RebootRequestReceiver extends BroadcastReceiver {
202 @Override
203 public void onReceive(Context c, Intent intent) {
Dianne Hackbornf6438b12013-05-09 18:53:48 -0700204 if (intent.getIntExtra("nowait", 0) != 0) {
205 rebootSystem("Received ACTION_REBOOT broadcast");
206 return;
207 }
208 Slog.w(TAG, "Unsupported ACTION_REBOOT broadcast: " + intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800209 }
210 }
211
Wale Ogunwale517daec2015-04-15 10:27:24 -0700212 /** Monitor for checking the availability of binder threads. The monitor will block until
213 * there is a binder thread available to process in coming IPCs to make sure other processes
214 * can still communicate with the service.
215 */
216 private static final class BinderThreadMonitor implements Watchdog.Monitor {
217 @Override
218 public void monitor() {
219 Binder.blockUntilThreadAvailable();
220 }
221 }
222
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800223 public interface Monitor {
224 void monitor();
225 }
226
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800227 public static Watchdog getInstance() {
228 if (sWatchdog == null) {
229 sWatchdog = new Watchdog();
230 }
231
232 return sWatchdog;
233 }
234
235 private Watchdog() {
236 super("watchdog");
Dianne Hackborn8d044e82013-04-30 17:24:15 -0700237 // Initialize handler checkers for each common thread we want to check. Note
238 // that we are not currently checking the background thread, since it can
239 // potentially hold longer running operations with no guarantees about the timeliness
240 // of operations there.
241
242 // The shared foreground thread is the main checker. It is where we
243 // will also dispatch monitor checks and do other work.
Christopher Tatee6f81cf2013-10-23 17:28:27 -0700244 mMonitorChecker = new HandlerChecker(FgThread.getHandler(),
245 "foreground thread", DEFAULT_TIMEOUT);
Dianne Hackborn8d044e82013-04-30 17:24:15 -0700246 mHandlerCheckers.add(mMonitorChecker);
247 // Add checker for main thread. We only do a quick check since there
248 // can be UI running on the thread.
249 mHandlerCheckers.add(new HandlerChecker(new Handler(Looper.getMainLooper()),
Christopher Tatee6f81cf2013-10-23 17:28:27 -0700250 "main thread", DEFAULT_TIMEOUT));
Dianne Hackborn8d044e82013-04-30 17:24:15 -0700251 // Add checker for shared UI thread.
Christopher Tatee6f81cf2013-10-23 17:28:27 -0700252 mHandlerCheckers.add(new HandlerChecker(UiThread.getHandler(),
253 "ui thread", DEFAULT_TIMEOUT));
Dianne Hackborn8d044e82013-04-30 17:24:15 -0700254 // And also check IO thread.
Christopher Tatee6f81cf2013-10-23 17:28:27 -0700255 mHandlerCheckers.add(new HandlerChecker(IoThread.getHandler(),
256 "i/o thread", DEFAULT_TIMEOUT));
Jeff Brown4ccb8232014-01-16 22:16:42 -0800257 // And the display thread.
258 mHandlerCheckers.add(new HandlerChecker(DisplayThread.getHandler(),
259 "display thread", DEFAULT_TIMEOUT));
Wale Ogunwale517daec2015-04-15 10:27:24 -0700260
261 // Initialize monitor for Binder threads.
262 addMonitor(new BinderThreadMonitor());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800263 }
264
Adam Lesinski182f73f2013-12-05 16:48:06 -0800265 public void init(Context context, ActivityManagerService activity) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800266 mResolver = context.getContentResolver();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800267 mActivity = activity;
268
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800269 context.registerReceiver(new RebootRequestReceiver(),
270 new IntentFilter(Intent.ACTION_REBOOT),
271 android.Manifest.permission.REBOOT, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800272 }
273
Christopher Tatec27181c2010-06-30 14:41:09 -0700274 public void processStarted(String name, int pid) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800275 synchronized (this) {
276 if ("com.android.phone".equals(name)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800277 mPhonePid = pid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800278 }
279 }
280 }
281
Dianne Hackborn5b88a2f2013-05-03 16:25:11 -0700282 public void setActivityController(IActivityController controller) {
283 synchronized (this) {
284 mController = controller;
285 }
286 }
287
Dianne Hackborn8bd64df2013-05-06 16:07:26 -0700288 public void setAllowRestart(boolean allowRestart) {
289 synchronized (this) {
290 mAllowRestart = allowRestart;
291 }
292 }
293
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800294 public void addMonitor(Monitor monitor) {
295 synchronized (this) {
296 if (isAlive()) {
Dianne Hackborn8d044e82013-04-30 17:24:15 -0700297 throw new RuntimeException("Monitors can't be added once the Watchdog is running");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800298 }
Dianne Hackborn8d044e82013-04-30 17:24:15 -0700299 mMonitorChecker.addMonitor(monitor);
300 }
301 }
302
Jeff Brown6f357d32014-01-15 20:40:55 -0800303 public void addThread(Handler thread) {
304 addThread(thread, DEFAULT_TIMEOUT);
Christopher Tatee6f81cf2013-10-23 17:28:27 -0700305 }
306
Jeff Brown6f357d32014-01-15 20:40:55 -0800307 public void addThread(Handler thread, long timeoutMillis) {
Dianne Hackborn8d044e82013-04-30 17:24:15 -0700308 synchronized (this) {
309 if (isAlive()) {
310 throw new RuntimeException("Threads can't be added once the Watchdog is running");
311 }
Jeff Brown6f357d32014-01-15 20:40:55 -0800312 final String name = thread.getLooper().getThread().getName();
Christopher Tatee6f81cf2013-10-23 17:28:27 -0700313 mHandlerCheckers.add(new HandlerChecker(thread, name, timeoutMillis));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800314 }
315 }
316
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800317 /**
318 * Perform a full reboot of the system.
319 */
320 void rebootSystem(String reason) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800321 Slog.i(TAG, "Rebooting system because: " + reason);
Jeff Brown6f357d32014-01-15 20:40:55 -0800322 IPowerManager pms = (IPowerManager)ServiceManager.getService(Context.POWER_SERVICE);
323 try {
324 pms.reboot(false, reason, false);
325 } catch (RemoteException ex) {
326 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800327 }
328
Christopher Tatee6f81cf2013-10-23 17:28:27 -0700329 private int evaluateCheckerCompletionLocked() {
330 int state = COMPLETED;
Dianne Hackborn8d044e82013-04-30 17:24:15 -0700331 for (int i=0; i<mHandlerCheckers.size(); i++) {
332 HandlerChecker hc = mHandlerCheckers.get(i);
Christopher Tatee6f81cf2013-10-23 17:28:27 -0700333 state = Math.max(state, hc.getCompletionStateLocked());
Dianne Hackborn8d044e82013-04-30 17:24:15 -0700334 }
Christopher Tatee6f81cf2013-10-23 17:28:27 -0700335 return state;
Dianne Hackborn8d044e82013-04-30 17:24:15 -0700336 }
337
Dianne Hackbornfa012b32013-05-10 15:23:28 -0700338 private ArrayList<HandlerChecker> getBlockedCheckersLocked() {
339 ArrayList<HandlerChecker> checkers = new ArrayList<HandlerChecker>();
Dianne Hackborn8d044e82013-04-30 17:24:15 -0700340 for (int i=0; i<mHandlerCheckers.size(); i++) {
341 HandlerChecker hc = mHandlerCheckers.get(i);
Christopher Tatee6f81cf2013-10-23 17:28:27 -0700342 if (hc.isOverdueLocked()) {
Dianne Hackbornfa012b32013-05-10 15:23:28 -0700343 checkers.add(hc);
Dianne Hackborn8d044e82013-04-30 17:24:15 -0700344 }
345 }
Dianne Hackbornfa012b32013-05-10 15:23:28 -0700346 return checkers;
347 }
348
349 private String describeCheckersLocked(ArrayList<HandlerChecker> checkers) {
350 StringBuilder builder = new StringBuilder(128);
351 for (int i=0; i<checkers.size(); i++) {
352 if (builder.length() > 0) {
353 builder.append(", ");
354 }
355 builder.append(checkers.get(i).describeBlockedStateLocked());
356 }
Dianne Hackborn8d044e82013-04-30 17:24:15 -0700357 return builder.toString();
358 }
359
Steven Moreland6b47c542017-03-21 12:52:16 -0700360 private ArrayList<Integer> getInterestingHalPids() {
361 try {
362 IServiceManager serviceManager = IServiceManager.getService();
363 ArrayList<IServiceManager.InstanceDebugInfo> dump =
364 serviceManager.debugDump();
365 HashSet<Integer> pids = new HashSet<>();
366 for (IServiceManager.InstanceDebugInfo info : dump) {
367 if (info.pid == IServiceManager.PidConstant.NO_PID) {
368 continue;
369 }
370
371 if (!HAL_INTERFACES_OF_INTEREST.contains(info.interfaceName)) {
372 continue;
373 }
374
375 pids.add(info.pid);
376 }
377 return new ArrayList<Integer>(pids);
378 } catch (RemoteException e) {
379 return new ArrayList<Integer>();
380 }
381 }
382
383 private ArrayList<Integer> getInterestingNativePids() {
384 ArrayList<Integer> pids = getInterestingHalPids();
385
386 int[] nativePids = Process.getPidsForCommands(NATIVE_STACKS_OF_INTEREST);
387 if (nativePids != null) {
388 pids.ensureCapacity(pids.size() + nativePids.length);
389 for (int i : nativePids) {
390 pids.add(i);
391 }
392 }
393
394 return pids;
395 }
396
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800397 @Override
398 public void run() {
Christopher Tate6ee412d2010-05-28 12:01:56 -0700399 boolean waitedHalf = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800400 while (true) {
Dianne Hackbornfa012b32013-05-10 15:23:28 -0700401 final ArrayList<HandlerChecker> blockedCheckers;
Jeff Brown7dd2d192013-09-06 15:05:23 -0700402 final String subject;
Dianne Hackborn8bd64df2013-05-06 16:07:26 -0700403 final boolean allowRestart;
Dianne Hackborn89ad4562014-08-24 16:45:38 -0700404 int debuggerWasConnected = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800405 synchronized (this) {
Christopher Tatee6f81cf2013-10-23 17:28:27 -0700406 long timeout = CHECK_INTERVAL;
407 // Make sure we (re)spin the checkers that have become idle within
408 // this wait-and-check interval
409 for (int i=0; i<mHandlerCheckers.size(); i++) {
410 HandlerChecker hc = mHandlerCheckers.get(i);
411 hc.scheduleCheckLocked();
Dianne Hackborn8d044e82013-04-30 17:24:15 -0700412 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800413
Dianne Hackborn89ad4562014-08-24 16:45:38 -0700414 if (debuggerWasConnected > 0) {
415 debuggerWasConnected--;
416 }
417
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800418 // NOTE: We use uptimeMillis() here because we do not want to increment the time we
419 // wait while asleep. If the device is asleep then the thing that we are waiting
Christopher Tate6ee412d2010-05-28 12:01:56 -0700420 // to timeout on is asleep as well and won't have a chance to run, causing a false
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800421 // positive on when to kill things.
422 long start = SystemClock.uptimeMillis();
Michael Wright8fa56f62013-04-01 16:36:05 -0700423 while (timeout > 0) {
Dianne Hackborn89ad4562014-08-24 16:45:38 -0700424 if (Debug.isDebuggerConnected()) {
425 debuggerWasConnected = 2;
426 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800427 try {
Michael Wright8fa56f62013-04-01 16:36:05 -0700428 wait(timeout);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800429 } catch (InterruptedException e) {
Dan Egnor9bdc94b2010-03-04 14:20:31 -0800430 Log.wtf(TAG, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800431 }
Dianne Hackborn89ad4562014-08-24 16:45:38 -0700432 if (Debug.isDebuggerConnected()) {
433 debuggerWasConnected = 2;
434 }
Christopher Tatee6f81cf2013-10-23 17:28:27 -0700435 timeout = CHECK_INTERVAL - (SystemClock.uptimeMillis() - start);
Dan Egnor9bdc94b2010-03-04 14:20:31 -0800436 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800437
Christopher Tatee6f81cf2013-10-23 17:28:27 -0700438 final int waitState = evaluateCheckerCompletionLocked();
439 if (waitState == COMPLETED) {
440 // The monitors have returned; reset
Christopher Tate6ee412d2010-05-28 12:01:56 -0700441 waitedHalf = false;
442 continue;
Christopher Tatee6f81cf2013-10-23 17:28:27 -0700443 } else if (waitState == WAITING) {
444 // still waiting but within their configured intervals; back off and recheck
445 continue;
446 } else if (waitState == WAITED_HALF) {
447 if (!waitedHalf) {
448 // We've waited half the deadlock-detection interval. Pull a stack
449 // trace and wait another half.
450 ArrayList<Integer> pids = new ArrayList<Integer>();
451 pids.add(Process.myPid());
452 ActivityManagerService.dumpStackTraces(true, pids, null, null,
Steven Moreland6b47c542017-03-21 12:52:16 -0700453 getInterestingNativePids());
Christopher Tatee6f81cf2013-10-23 17:28:27 -0700454 waitedHalf = true;
455 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800456 continue;
457 }
Michael Wright8fa56f62013-04-01 16:36:05 -0700458
Christopher Tatee6f81cf2013-10-23 17:28:27 -0700459 // something is overdue!
Dianne Hackbornfa012b32013-05-10 15:23:28 -0700460 blockedCheckers = getBlockedCheckersLocked();
Jeff Brown7dd2d192013-09-06 15:05:23 -0700461 subject = describeCheckersLocked(blockedCheckers);
Dianne Hackborn8bd64df2013-05-06 16:07:26 -0700462 allowRestart = mAllowRestart;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800463 }
464
465 // If we got here, that means that the system is most likely hung.
Jean-Baptiste Queru784827b2012-09-04 13:35:12 -0700466 // First collect stack traces from all threads of the system process.
467 // Then kill this process so that the system will restart.
Jeff Brown7dd2d192013-09-06 15:05:23 -0700468 EventLog.writeEvent(EventLogTags.WATCHDOG, subject);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800469
Steven Moreland6b47c542017-03-21 12:52:16 -0700470 ArrayList<Integer> pids = new ArrayList<>();
Dan Egnor9bdc94b2010-03-04 14:20:31 -0800471 pids.add(Process.myPid());
Dan Egnor4bded072010-03-11 22:00:47 -0800472 if (mPhonePid > 0) pids.add(mPhonePid);
Christopher Tate6ee412d2010-05-28 12:01:56 -0700473 // Pass !waitedHalf so that just in case we somehow wind up here without having
474 // dumped the halfway stacks, we properly re-initialize the trace file.
Brad Fitzpatrick9765c722011-01-14 11:28:22 -0800475 final File stack = ActivityManagerService.dumpStackTraces(
Steven Moreland6b47c542017-03-21 12:52:16 -0700476 !waitedHalf, pids, null, null, getInterestingNativePids());
Dan Egnor4bded072010-03-11 22:00:47 -0800477
478 // Give some extra time to make sure the stack traces get written.
479 // The system's been hanging for a minute, another second or two won't hurt much.
480 SystemClock.sleep(2000);
481
Christopher Tateecaa7b42010-06-04 14:55:02 -0700482 // Pull our own kernel thread stacks as well if we're configured for that
483 if (RECORD_KERNEL_THREADS) {
484 dumpKernelStackTraces();
485 }
486
Guang Zhu0620c452014-10-29 14:31:48 -0700487 // Trigger the kernel to dump all blocked threads, and backtraces on all CPUs to the kernel log
488 doSysRq('w');
489 doSysRq('l');
Colin Cross5df1d872012-11-29 11:42:11 -0800490
Brad Fitzpatrick9765c722011-01-14 11:28:22 -0800491 // Try to add the error to the dropbox, but assuming that the ActivityManager
492 // itself may be deadlocked. (which has happened, causing this statement to
493 // deadlock and the watchdog as a whole to be ineffective)
494 Thread dropboxThread = new Thread("watchdogWriteToDropbox") {
495 public void run() {
496 mActivity.addErrorToDropBox(
Jeff Sharkeya353d262011-10-28 11:12:06 -0700497 "watchdog", null, "system_server", null, null,
Jeff Brown7dd2d192013-09-06 15:05:23 -0700498 subject, null, stack, null);
Brad Fitzpatrick9765c722011-01-14 11:28:22 -0800499 }
500 };
501 dropboxThread.start();
502 try {
503 dropboxThread.join(2000); // wait up to 2 seconds for it to return.
504 } catch (InterruptedException ignored) {}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800505
Dianne Hackborn5b88a2f2013-05-03 16:25:11 -0700506 IActivityController controller;
507 synchronized (this) {
508 controller = mController;
509 }
510 if (controller != null) {
511 Slog.i(TAG, "Reporting stuck state to activity controller");
512 try {
513 Binder.setDumpDisabled("Service dumps disabled due to hung system process.");
514 // 1 = keep waiting, -1 = kill system
Jeff Brown7dd2d192013-09-06 15:05:23 -0700515 int res = controller.systemNotResponding(subject);
Dianne Hackborn5b88a2f2013-05-03 16:25:11 -0700516 if (res >= 0) {
517 Slog.i(TAG, "Activity controller requested to coninue to wait");
518 waitedHalf = false;
519 continue;
520 }
521 } catch (RemoteException e) {
522 }
523 }
524
Jean-Baptiste Queru784827b2012-09-04 13:35:12 -0700525 // Only kill the process if the debugger is not attached.
Dianne Hackborn8bd64df2013-05-06 16:07:26 -0700526 if (Debug.isDebuggerConnected()) {
Dianne Hackborn89ad4562014-08-24 16:45:38 -0700527 debuggerWasConnected = 2;
528 }
529 if (debuggerWasConnected >= 2) {
Dianne Hackborn8bd64df2013-05-06 16:07:26 -0700530 Slog.w(TAG, "Debugger connected: Watchdog is *not* killing the system process");
Dianne Hackborn89ad4562014-08-24 16:45:38 -0700531 } else if (debuggerWasConnected > 0) {
532 Slog.w(TAG, "Debugger was connected: Watchdog is *not* killing the system process");
Dianne Hackborn8bd64df2013-05-06 16:07:26 -0700533 } else if (!allowRestart) {
534 Slog.w(TAG, "Restart not allowed: Watchdog is *not* killing the system process");
535 } else {
Jeff Brown7dd2d192013-09-06 15:05:23 -0700536 Slog.w(TAG, "*** WATCHDOG KILLING SYSTEM PROCESS: " + subject);
Dianne Hackbornfa012b32013-05-10 15:23:28 -0700537 for (int i=0; i<blockedCheckers.size(); i++) {
538 Slog.w(TAG, blockedCheckers.get(i).getName() + " stack trace:");
539 StackTraceElement[] stackTrace
540 = blockedCheckers.get(i).getThread().getStackTrace();
541 for (StackTraceElement element: stackTrace) {
542 Slog.w(TAG, " at " + element);
543 }
Michael Wright56a6c662013-04-30 20:13:07 -0700544 }
Dianne Hackbornfa012b32013-05-10 15:23:28 -0700545 Slog.w(TAG, "*** GOODBYE!");
Jean-Baptiste Queru784827b2012-09-04 13:35:12 -0700546 Process.killProcess(Process.myPid());
547 System.exit(10);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800548 }
Christopher Tate6ee412d2010-05-28 12:01:56 -0700549
550 waitedHalf = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800551 }
552 }
Christopher Tateecaa7b42010-06-04 14:55:02 -0700553
Guang Zhu0620c452014-10-29 14:31:48 -0700554 private void doSysRq(char c) {
555 try {
556 FileWriter sysrq_trigger = new FileWriter("/proc/sysrq-trigger");
557 sysrq_trigger.write(c);
558 sysrq_trigger.close();
559 } catch (IOException e) {
560 Slog.w(TAG, "Failed to write to /proc/sysrq-trigger", e);
561 }
562 }
563
Christopher Tateecaa7b42010-06-04 14:55:02 -0700564 private File dumpKernelStackTraces() {
565 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
566 if (tracesPath == null || tracesPath.length() == 0) {
567 return null;
568 }
569
570 native_dumpKernelStacks(tracesPath);
571 return new File(tracesPath);
572 }
573
574 private native void native_dumpKernelStacks(String tracesPath);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800575}