Android 中的看门狗—Watchdog
一、SystemServer 进程中初始化、启动看门狗..................................................................... 1
二、AMS 实现接口Watchdog.Monitor.................................................................................... 3
三、Watchdog.java 的实现........................................................................................................4
四、常见问题分析.....................................................................................................................5
在android 系统中,看门狗可以分成以下两种类型。
1)、HW Watchdog:用于监测CPU 执行是否异常, 启用Kernel RT
thread tick HW watchdog 来达成, 如果异常, 则重启整个系统。
2)、System Server Watchdog:用于监测Android System Server 关键
线程和资源使用是否正常, 如果异常则重启android 上层。
今天我们主要分析的是SystemServer 进程中的看门狗:
一、SystemServer 进程中初始化、启动看门狗
1.1、初始化:
SystemServer 进程中,在开启otherservice 服务的方法中,会初始
化看门狗Watchdog 的实例对象。源码如下所示:
traceBeginAndSlog("InitWatchdog");
final Watchdog watchdog = Watchdog.getInstance();
watchdog.init(context, mActivityManagerService);
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
在这里我们可以自动切换到Watchdog.java 类中的init()方法查看
发现,首先,它会通过registerReceive(r )方法注册一个广播接收reboot
重启的请求; 其次, 通过ExceptionLog 的实例对象, 进行监护
SystemServer 进程。这也就是Watchdog 的主要作用。
1.2、启动:
在AMS 实例对象调用systemReady()函数中,有这么一句启动
看门狗的代码:Watchdog.getInstance().start();注意,systemReady()
方法主要是告知各个服务系统已经准备就绪,可以开始实现各自的职
责。
1.3、SystemServer 中被看门狗监控的三大服务:
1)、ActivityManagerService.java
path:./frameworks/base/services/core/java/com/android/server/am/
2)、PowerManagerService.java
path:./frameworks/base/services/core/java/com/android/server/power/
3)、WindowManagerService.java
path:./frameworks/base/services/core/java/com/android/server/wm/
因此,WatchDog 主要就是确保上述的服务发生死锁之后,退出
SystemServer 进程,让init 进程重启它,让系统回到可用状态。
由于上述服务实现看门狗的过程都类似,这里我们只以AMS 为例
进行分析。
二、AMS 实现接口Watchdog.Monitor
每个被监护的Service 服务必须实现看门狗的”Watchdog.Monitor”
接口。如`public final class ActivityManagerService extends
ActivityManagerNative implements Watchdog.Monitor,
BatteryStatsImpl.BatteryCallback` 。这个接口很简单, 就只有一个
monitor()方法。其次,在AMS 中实现的这个方法也只是锁一下对象,
什么都没有做,直接返回。如:
/** In this method we try to acquire our lock to make sure that we have
not deadlocked */
public void monitor() {
synchronized (this) { }
}
从它的注释中也可以看出来“在这个方法中,我们试图获得锁,以确
保我们没有死锁。”
Note:实现完接口之后,其实,它在AMS 的构造函数中有这么两行代
码:

Watchdog.getInstance().addMonitor(this);
Watchdog.getInstance().addThread(mHandler);
“ ,其作用是把AMS 注册到Watchdog 服务中。
三、Watchdog.java 的实现
1、由于Watchdog 是Thread 的子类,我们首先来看它的run()方法。
public void run() {
boolean waitedHalf = false;
boolean mSFHang = false;
while (true) {
.......
for (int i=0; iHandlerChecker hc = mHandlerCheckers.get(i);
hc.scheduleCheckLocked();
}
.......
while (timeout > 0) { //等待超时时间,判断是否退出循环
if (Debug.isDebuggerConnected()) {
debuggerWasConnected = 2;
}try { wait(timeout);
} catch (InterruptedException e) { }
if (Debug.isDebuggerConnected()) {
debuggerWasConnected = 2;
}
timeout = CHECK_INTERVAL - (SystemClock.uptimeMillis() - start);}
...........
// Only kill the process if the debugger is not attached.
if (Debug.isDebuggerConnected()) { //出现死锁,杀死SystemServer 进程
debuggerWasConnected = 2;
}
if (debuggerWasConnected >= 2) {
Slog.w(TAG, "Debugger connected: Watchdog is *not* killing the
system process");...............
Note:在Watchdog 的run()方法中会去调用子线程HandlerChecker 检查
各个Service 服务是否正常工作,此时的看门狗会不断的去检查并且等待它反馈
回来的结果,如果出现死锁的情况,立马杀掉SystemServer 进程。而且这其中如
果超时,会利用debuggerd 打印backtrace 到/proc/sysrq-trigger 当中。
2、HandlerChecker 的run()方法。源码如下所示:
public void run() {
final int size = mMonitors.size(); // 获取注册Watchdog 服务的
Services 数量
for (int i = 0 ; i < size ; i++) {
synchronized (Watchdog.this) {
mCurrentMonitor = mMonitors.get(i); //
}
mCurrentMonitor.monitor();
}
synchronized (Watchdog.this) { //如果没有死锁一般都会走到这里
mCompleted = true; //表示正常
mCurrentMonitor = null; //没有死锁
}
}
Note:如果被看门狗监护的服务对象发生了死锁,则线程会一直阻塞在这里。前
面提到了许多”死锁”,死锁?无非就是系统中各个进程互相抢占资源的过程中导
致的一种现象。对于死锁的产生原因非常多,比如说java 层死锁可能发生在调
用native 函数,而native 函数可能与硬件交互导致时间过长而没有返回,从而导
致长时间占用导致问题。具体问题具体分析。
最后,附上一张总时序图~:
SystemServer Watchdog Thread(this) HandlerChecker AMS
1 : addmonitor()
2 : new Watchdog()
3 : start()
4 : run()
5 : scheduleCheckLocked()
6 : timeout() 7 : mCurrentMonitor.monitor()
8 : mCompleted=true()
9 : Service is normal()
10 : Please Killing SystemService()
四、常见问题分析
注:抓取MTK3710 的开关机log,查看ksernerl log 对比下面的信息
看门狗在检查各个Service 的过程中,分下面三种情形做出一次举动,
第一种情形已经过验证,下面两种情形还未实验:
1)、正常情况下,tick 300s, 对应count=10.
[ 66.841723]: (0)[1147:watchdog]AEEIOCTL_RT_MON_Kick ( 300)
[ 66.841753]: (0)[1147:watchdog][Hang_Detect] hang_detect enabled 10
2)、在dump backtrace 时,tick 600s, 对应count=20.
[ 258.218145] (0)[1322:watchdog]AEEIOCTL_RT_MON_Kick ( 600)
[ 258.218171] (0)[1322:watchdog][Hang_Detect] hang_detect enabled 20
3)、在SWT 发生的情况下,tick 720s, 对应count=24.
[ 299.046542] (0)[1322:watchdog]AEEIOCTL_RT_MON_Kick ( 720)
[ 299.046572] (0)[1322:watchdog][Hang_Detect] hang_detect enabled 24
其次,一条可以快速定位是否是进程卡住的问题,正常情况下Kernel threrad
打印的信息:
[ 60.561702]: (0)[118:hang_detect][Hang_Detect] hang_detect thread counts down
10:10.

更多相关文章

  1. [Android(安卓)Pro] Android的5个进程等级
  2. android EditText 不自动弹出键盘的方法
  3. Flutter Android启动源码分析(一)
  4. Android文件存储总结
  5. Android(安卓)AsyncTask Download
  6. (收集)ListView中常用属性
  7. Android下ContentProvider 学习总结
  8. 浅谈Java中Collections.sort对List排序的两种方法
  9. Python list sort方法的具体使用

随机推荐

  1. Android四大组件的理解
  2. 【Android(安卓)开发教程】Toast通知
  3. GitHub 优秀的 Android(安卓)开源项目
  4. opengrok setup on ubuntu for android s
  5. Android(安卓)闹钟管理类的使用
  6. Android(安卓)P SystemUI之StatusBar UI
  7. Android学习篇之Menu的使用
  8. Android软键盘适配问题
  9. Android(安卓)Service AIDL
  10. android拍照与读取相册