分类:【Android 系统分析】 706人阅读 评论(0) 收藏 举报 Android Watchdog SystemServer 看门狗

目录(?)[+]

在Android系统中,所有的系统服务都运行在SystemServer进程中,如果实时监测系统所有服务是否正常运行呢?Android软 Watchdog就是用来胜任这个工作的,WatchDog的作用:

1).接收系统内部reboot请求,重启系统。

2).监护SystemServer进程,防止系统死锁。

Android watchdog类图:

Android软Watchdog源码分析_第1张图片

Watchdog本身继承Thread,是一个线程类,监控任务运行在独立的线程中,但是Watchdog线程并没有自己的消息队列,该线程共用SystemServer主线程的消息队列。Watchdog有一个mMonitors成员变量,该变量是一个monitor类型的动态数组,用于保存所有Watchdog监测对象。Monitor定义为接口类型,需要加入Watchdog监控的服务必须实现Monitor接口。HeartbeatHandler类为WatchDog的核心,负责对各个监护对象进行监护。

Watchdog启动


WatchDog是在SystemServer进程中被初始化和启动的。在SystemServer 被Start时,各种Android服务被注册和启动,其中也包括了WatchDog的初始化和启动。
[java] view plain copy
  1. Slog.i(TAG,"InitWatchdog");
  2. Watchdog.getInstance().init(context,battery,power,alarm,ActivityManagerService.self());
  3. Watchdog.getInstance().start();
Watchdog采用单例模式构造对象 [java] view plain copy
  1. publicstaticWatchdoggetInstance(){
  2. if(sWatchdog==null){
  3. sWatchdog=newWatchdog();
  4. }
  5. returnsWatchdog;
  6. }
Watchdog构造过程 [java] view plain copy
  1. privateWatchdog(){
  2. super("watchdog");
  3. mHandler=newHeartbeatHandler();
  4. }
在构造Watchdog时创建了一个心跳HeartbeatHandler,用于处理Watchdog线程发送的MONITOR消息。接着调用Watchdog的init函数来初始化Watchdog对象: [java] view plain copy
  1. publicvoidinit(Contextcontext,BatteryServicebattery,
  2. PowerManagerServicepower,AlarmManagerServicealarm,
  3. ActivityManagerServiceactivity){
  4. mResolver=context.getContentResolver();
  5. mBattery=battery;
  6. mPower=power;
  7. mAlarm=alarm;
  8. mActivity=activity;
  9. //注册重启广播接收器
  10. context.registerReceiver(newRebootReceiver(),newIntentFilter(REBOOT_ACTION));
  11. mRebootIntent=PendingIntent.getBroadcast(context,0,newIntent(REBOOT_ACTION),0);
  12. //注册重启请求广播接收器
  13. context.registerReceiver(newRebootRequestReceiver(),
  14. newIntentFilter(Intent.ACTION_REBOOT),
  15. android.Manifest.permission.REBOOT,null);
  16. mBootTime=System.currentTimeMillis();
  17. }
RebootReceiver负责接收由AlarManagerService发出的PendingIntent,并进行系统重启。
RebootRequestReceiver负责接收系统内部发出的重启Intent消息,并进行系统重启。

添加监控对象


在启动Watchdog前,需要向其添加监测对象。在Android4.1中有7个服务实现了Watchdog.Monitor接口,即这些服务都可以被Watchdog监控。 ActivityManagerService
InputManagerService
MountService
NativeDaemonConnector
NetworkManagementService
PowerManagerService
WindowManagerService
Watchdog提供了addMonitor方法来添加监控对象
[java] view plain copy
  1. publicvoidaddMonitor(Monitormonitor){
  2. synchronized(this){
  3. if(isAlive()){
  4. thrownewRuntimeException("Monitorscan'tbeaddedwhiletheWatchdogisrunning");
  5. }
  6. mMonitors.add(monitor);
  7. }
  8. }
添加过程只是将需要被Watchdog监控的对象添加到Watchdog的动态monitor数组mMonitors中。

Watchdog监控过程


当调用Watchdog.getInstance().start()将启动Watchdog线程,Watchdog执行过程如下: [java] view plain copy
  1. publicvoidrun(){
  2. booleanwaitedHalf=false;
  3. while(true){
  4. /**
  5. *反复设置mCompleted变量为false
  6. */
  7. mCompleted=false;
  8. /**
  9. *发送一个MONITOR消息给心跳HeartbeatHandler处理,处理过程就是调用各个监控对象的monitor函数,
  10. *如果各个被监控服务的monitor都顺利返回,心跳HeartbeatHandler会将mCompleted设置为true
  11. */
  12. if(mHandler.sendEmptyMessage(MONITOR)){
  13. if(WATCHDOG_DEBUG)Slog.v(TAG,"****-1-WatchdogMSGSENT!****");
  14. }
  15. /**
  16. *Watchdog线程和SystemServer主线程共用同一个消息队列,为了在两个线程中改变mCompleted的值,这里必须使用线程同步机制
  17. */
  18. synchronized(this){
  19. /**
  20. *TIME_TO_WAIT的默认时间为30s。此为第一次等待时间,WatchDog判断对象是否死锁的最长处理时间为1Min。
  21. */
  22. longtimeout=TIME_TO_WAIT;
  23. /**
  24. *获取当前时间
  25. */
  26. longstart=SystemClock.uptimeMillis();
  27. /**
  28. *等待30秒,等待HeartbeatHandler的处理结果。然后才会进行下一步动作。
  29. */
  30. while(timeout>0&&!mForceKillSystem){
  31. try{
  32. wait(timeout);//notifyAll()iscalledwhenmForceKillSystemisset
  33. }catch(InterruptedExceptione){
  34. Log.wtf(TAG,e);
  35. }
  36. timeout=TIME_TO_WAIT-(SystemClock.uptimeMillis()-start);
  37. }
  38. /**
  39. *如果所有监控对象在30s内能够顺利返回,则会得到mCompleted=true;
  40. */
  41. if(mCompleted&&!mForceKillSystem){
  42. /**
  43. *设置waitedHalf的值为false,表示SystemServer中被监测的服务对象运行正常
  44. */
  45. waitedHalf=false;
  46. continue;//则本次监控结束,返回继续下一轮监护。
  47. }
  48. /**
  49. *waitedHalf在监测对象运行正常时,一直被设置为false,只有当Watchdog监测到服务对象运行异常时才
  50. *会被设置为true,因此在上一个30s周期内监测到服务对象运行异常,同时在本次30s周期内,waitedHalf
  51. *没有重新设置为false,说明本周期内服务运行依然异常,就直接杀死SystemServer进程
  52. */
  53. if(!waitedHalf){
  54. ArrayList<Integer>pids=newArrayList<Integer>();
  55. pids.add(Process.myPid());
  56. /**
  57. *dump进程堆栈信息,将堆栈信息保存到/data/anr/traces.txt文件,同时dump出mediaserver,
  58. *sdcard,surfaceflinger这三个native进程的堆栈信息,并发送进程退出信号
  59. */
  60. ActivityManagerService.dumpStackTraces(true,pids,null,null,NATIVE_STACKS_OF_INTEREST);
  61. SystemClock.sleep(3000);
  62. /**
  63. *RECORD_KERNEL_THREADS初始值为true,则dump出内核堆栈信息
  64. */
  65. if(RECORD_KERNEL_THREADS){
  66. dumpKernelStackTraces();
  67. SystemClock.sleep(2000);
  68. }
  69. /**
  70. *设置waitedHalf的值为true,表示心跳HeartbeatHandler在monitor监测对象时,30s内没有顺利完成
  71. */
  72. waitedHalf=true;
  73. /**
  74. *则本次监控结束,返回继续下一轮监测.这就说明当第一个30s监测到服务对象运行异常时,只是打印进程堆栈信息,
  75. *并不会杀死SystemServer进程
  76. */
  77. continue;
  78. }
  79. }
  80. /**
  81. *若紧接着的下一轮监护,在30s内,monitor对象依旧未及时返回,直接运行到这里。这表示系统的监护对象有死锁现象发生,
  82. *SystemServer进程需要kill并重启。
  83. */
  84. finalStringname=(mCurrentMonitor!=null)?mCurrentMonitor.getClass().getName():"null";
  85. Slog.w(TAG,"***WATCHDOGISGOINGTOKILLSYSTEMPROCESS:"+name);
  86. EventLog.writeEvent(EventLogTags.WATCHDOG,name);
  87. ArrayList<Integer>pids=newArrayList<Integer>();
  88. pids.add(Process.myPid());
  89. if(mPhonePid>0)pids.add(mPhonePid);
  90. /**
  91. *当Watchdog监测到服务对象运行异常时waitedHalf会被设置为true,这里传递的第一个参数为waitedHalf的取反,表示以追加的方式
  92. *将进程堆栈信息保存到trace文件中
  93. */
  94. finalFilestack=ActivityManagerService.dumpStackTraces(
  95. !waitedHalf,pids,null,null,NATIVE_STACKS_OF_INTEREST);
  96. /**
  97. *睡眠是为了等待完成进程堆栈信息的文件写操作
  98. */
  99. SystemClock.sleep(3000);
  100. if(RECORD_KERNEL_THREADS){
  101. dumpKernelStackTraces();
  102. SystemClock.sleep(2000);
  103. }
  104. /**
  105. *启动watchdogWriteToDropbox线程写dropbox错误日志
  106. */
  107. ThreaddropboxThread=newThread("watchdogWriteToDropbox"){
  108. publicvoidrun(){
  109. mActivity.addErrorToDropBox("watchdog",null,"system_server",null,null,
  110. name,null,stack,null);
  111. }
  112. };
  113. dropboxThread.start();
  114. try{
  115. dropboxThread.join(2000);//waitupto2secondsforittoreturn.
  116. }catch(InterruptedExceptionignored){}
  117. /**
  118. *杀死SystemServer进程,从而引发Zygote进程自杀,并触发init进程重新启动Zygote进程,以达到手机重启目的
  119. */
  120. if(!Debug.isDebuggerConnected()){
  121. Slog.w(TAG,"***WATCHDOGKILLINGSYSTEMPROCESS:"+name);
  122. Process.killProcess(Process.myPid());
  123. System.exit(10);
  124. }else{
  125. Slog.w(TAG,"Debuggerconnected:Watchdogis*not*killingthesystemprocess");
  126. }
  127. waitedHalf=false;
  128. }
  129. }
run函数实现比较简单,周期性地设置mCompleted变量为假,通知心跳handler去调用各个monitor,而心跳handler会调用各个service的monitor,如果各个monitor都返回了,心跳handler会将mCompleted设置为真。否则,经过2次等待watchgod的run()发现mCompleted还为假,就证明hang了。在Watchdog线程中只是周期性地发送MONITOR消息以达到喂狗的效果,真正监测服务对象的任务在SystemServer的主线程中完成: [java] view plain copy
  1. publicvoidhandleMessage(Messagemsg){
  2. switch(msg.what){
  3. /**
  4. *接收到Watchdog线程发送过来的MONITOR消息
  5. */
  6. caseMONITOR:{
  7. if(WATCHDOG_DEBUG)Slog.v(TAG,"****0-CHECKIFFORCEAREBOOT!****");
  8. //Seeifweshouldforceareboot.
  9. intrebootInterval=mReqRebootInterval>=0
  10. ?mReqRebootInterval:Settings.Secure.getInt(
  11. mResolver,Settings.Secure.REBOOT_INTERVAL,
  12. REBOOT_DEFAULT_INTERVAL);
  13. if(mRebootInterval!=rebootInterval){
  14. mRebootInterval=rebootInterval;
  15. //Wehavebeenrunninglongenoughthatarebootcan
  16. //beconsidered...
  17. checkReboot(false);
  18. }
  19. if(WATCHDOG_DEBUG)Slog.v(TAG,"****1-CHECKALLMONITORSBEGIN!****");
  20. /**
  21. *依次调用每个被监控的服务对象的monitor函数,以达到监控服务对象是否正常运行的目的
  22. */
  23. finalintsize=mMonitors.size();
  24. for(inti=0;i<size;i++){
  25. mCurrentMonitor=mMonitors.get(i);
  26. mCurrentMonitor.monitor();
  27. }
  28. if(WATCHDOG_DEBUG)Slog.v(TAG,"****2-CHECKALLMONITORSFINISHED!****");//如果监护的对象都正常,则会很快运行到这里,并对mCompleted赋值为true,表示对象正常返回。mCompleted值初始为false。
  29. /**
  30. *如果在30s内所有的服务对象的monitor函数都能顺利返回,说明服务运行正常,这时就修改mCompleted的值为true
  31. *告知Watchdog线程服务的运行状态,由于Watchdog线程周期性地判断mCompleted的值以达到查询服务运行状态的目的,
  32. *因此这里必须使用线程同步机制
  33. */
  34. synchronized(Watchdog.this){
  35. mCompleted=true;
  36. mCurrentMonitor=null;
  37. }
  38. if(WATCHDOG_DEBUG)Slog.v(TAG,"****3-SYNCWatchdog.THISFINISHED!****");
  39. if(WATCHDOG_DEBUG)Slog.v(TAG,"");
  40. }break;
  41. }
  42. }
每个注册到WatchDog服务中的监测对象对必须实现WatchDog.Monitor接口,同时必须实现该接口中的monitor方法,这些被监控的服务在monitor函数中都做了什么工作呢?对于ActivityManagerService来说,其实现的monitor函数如下: [java] view plain copy
  1. publicvoidmonitor(){
  2. synchronized(this){}
  3. }
在ActivityManagerService服务实现的其他函数中,用于线程同步的锁都是ActivityManagerService对象自身,这里的monitor函数只是简单地去请求这个锁,如果ActivityManagerService服务运行正常,即没有发送线程死锁等,请求这个锁是很快完成的,即monitor函数可以顺利返回,但是如果ActivityManagerService在执行过程中发生线程死锁,即其他执行函数始终占用锁,monitor函数不能及时请求到该锁,也即无法正常返回,心跳HeartbeatHandler不能及时设置标志位mCompleted的值,从而告知Watchdog线程被监测的对象运行有异常,让Watchdog线程杀死SystemServer进程。SystemServer监控重要service,重要service hang则SystemServer死,SystemServer死则Zygote监控到,Zygote也死并且杀死整个Java世界,Zygote死则init监控到,init重新启动Zygote,之后SystemServer、service又进入重生过程。 Android软Watchdog源码分析_第2张图片

更多相关文章

  1. Android UI主线程和子线程
  2. Android文档——进程优先级与线程
  3. Android之 UI主线程ZT
  4. Android中的多线程
  5. 五.在Android中实现线程的方法
  6. android 多线程

随机推荐

  1. Android(安卓)- AutoCompleteTextView
  2. Android摇一摇
  3. android的文件操作
  4. [Android(安卓)Pro] android 杀死进程的
  5. Android(安卓)7.0 中 FileProvider空指针
  6. Importing Android(安卓)Source Code int
  7. android用sharepreference保存输入框中的
  8. Android(安卓)在程序中删除程序包
  9. Android版本和API Level对应关系 [更新到
  10. Android(安卓)Cache Partition