frameworks/base/services/java/com/android/server/SystemServer.java305     /**306      * The main entry point from zygote.307      */308     public static void main(String[] args) { 309         new SystemServer().run();  //SystemServer启动开始310     }run方法中执行了java446         try {447             traceBeginAndSlog("StartServices");448             startBootstrapServices();  //启动startBootstrapServices449             startCoreServices();450             startOtherServices();451             SystemServerInitThreadPool.shutdown();452         } catch (Throwable ex) {453             Slog.e("System", "******************************************");454             Slog.e("System", "************ Failure starting system services", ex);455             throw ex;456         } finally {457             traceEnd();458         }
     private void startBootstrapServices() {...603         // Now that we have the bare essentials of the OS up and running, take604         // note that we just booted, which might send out a rescue party if605         // we're stuck in a runtime restart loop.606         RescueParty.noteBoot(mSystemContext);//注释解释:操作系统刚刚启动,现在救援机制已经随时待命,如果遇到接下来发生的特殊情况的话。...}
 最终会到  这是第一个会造成触救援发机制的原因,
     frameworks/base/services/core/java/com/android/server/RescueParty.java
102     /**
103      * Take note of a boot event. If we notice too many of these events
104      * happening in rapid succession, we'll send out a rescue party.
105      */
106     public static void noteBoot(Context context) {107         if (isDisabled()) return;
108         if (sBoot.incrementAndTest()) {109             sBoot.reset();
110             incrementRescueLevel(sBoot.uid);
111             executeRescueLevel(context);
112         }
113     }
 另外一个是本次触发救援机制的原因即APPCrash导致。
115     /**
116      * Take note of a persistent app crash. If we notice too many of these
117      * events happening in rapid succession, we'll send out a rescue party.
118      */
119     public static void notePersistentAppCrash(Context context, int uid) {120         if (isDisabled()) return;
121         Threshold t = sApps.get(uid);
122         if (t == null) {123             t = new AppThreshold(uid);
124             sApps.put(uid, t);
125         }
126         if (t.incrementAndTest()) {127             t.reset();
128             incrementRescueLevel(t.uid);
129             executeRescueLevel(context);
130         }
131     }
 这两个即https://blog.csdn.net/weixin_33841722/article/details/94650416这篇博客提到的1.system_server 在 5 分钟内重启 5 次以上。2.永久性系统应用在 30 秒内崩溃 5 次以上。下面重点分析第2种 永久性系统应用在 30 秒内崩溃 5 次以上。首先 找到进入该方法的入口
 frameworks/base/services/core/java/com/android/server/am/AppErrors.java +:445:442         // If a persistent app is stuck in a crash loop, the device isn't very443         // usable, so we want to consider sending out a rescue party.444         if (r != null && r.persistent) {445             RescueParty.notePersistentAppCrash(mContext, r.uid);//解释为如果一个持久性的应用程序陷入了崩溃循环,那么这个设备就不能很好地使用了,所以我们想考虑派出一个救援队。446         }447
 那么何为persistent?源码解释为200     boolean persistent;         // always keep this application running?在这里我们可以解释为系统常驻应用,比如systemui,当然还有一些人为增加的保持常驻的应用。到现在可以进入到RescueParty.java本身开始看问题。if (isDisabled()) return;  isDisabled()的几种条件。(1)  persist.sys.enable_rescue 本身系统没有设值,默认false ,所以得看下面的判断。(2) eng版本默认return true,不会触发救援机制。(3) userdebug 版本并且插入usb状态 return true,不会触发救援机制。(4) persist.sys.disable_rescue 这个值默认也为false ,所以最后return false ,更改这个值为true ,即可关闭触发救援机制。
121     Threshold t = sApps.get(uid);
122     if (t == null) {123         t = new AppThreshold(uid);
124         sApps.put(uid, t);
125     }```java
126     if (t.incrementAndTest()) {127        t.reset();
128        incrementRescueLevel(t.uid);
129        executeRescueLevel(context);
130     }
 接下来分别介绍4个方法
     1.   t.incrementAndTest()
250         /**
251          * @return if this threshold has been triggered
252          */
253         public boolean incrementAndTest() {254             final long now = SystemClock.elapsedRealtime();
255             final long window = now - getStart();
256             if (window > triggerWindow) {257                 setCount(1);
258                 setStart(now);
259                 return false;//持续的时间大于触发窗口的时间即被认定为正常情况
260             } else {261                 int count = getCount() + 1;  //出现异常情况在上一次事件+1
262                 setCount(count);              //将事件数量保存在sys.rescue_boot_count ,读也读这个值
263                 EventLogTags.writeRescueNote(uid, count, window);
264                 Slog.w(TAG, "Noticed " + count + " events for UID " + uid + " in last "
265                         + (window / 1000) + " sec");
266                 return (count >= triggerCount);//上面我们有提到triggerCount这个值为5 ,在构造函数中固定了这个值,所以当事件累积到5次时会return true
267             }
268         }
269     }
Log:
Line 97942: S02FC4B  08-31 11:33:37.445  3934 11449 W RescueParty: Noticed 2 events for UID 10016 in last 1 sec
Line 99210: S0300DB  08-31 11:33:39.086  3934  4382 W RescueParty: Noticed 3 events for UID 10016 in last 3 sec
Line 100288: S0304D2  08-31 11:33:40.942  3934  6769 W RescueParty: Noticed 4 events for UID 10016 in last 5 sec
Line 102030: S030AAD  08-31 11:33:43.772  3934 11186 W RescueParty: Noticed 5 events for UID 10016 in last 8 secLine 104296: S0312F7  08-31 11:33:47.373  3934  4382 W RescueParty: Noticed 2 events for UID 10016 in last 1 sec
Line 106359: S031AE5  08-31 11:33:49.264  3934 12091 W RescueParty: Noticed 3 events for UID 10016 in last 3 sec
Line 107860: S032093  08-31 11:33:51.229  3934  9042 W RescueParty: Noticed 4 events for UID 10016 in last 5 sec
Line 109329: S0325B6  08-31 11:33:53.377  3934  7285 W RescueParty: Noticed 5 events for UID 10016 in last 7 secLine 111998: S032F58  08-31 11:33:57.584  3934 11501 W RescueParty: Noticed 2 events for UID 10016 in last 2 sec
Line 113602: S0334E6  08-31 11:33:59.478  3934  7285 W RescueParty: Noticed 3 events for UID 10016 in last 4 sec
Line 115201: S033A87  08-31 11:34:02.461  3934 11501 W RescueParty: Noticed 4 events for UID 10016 in last 7 sec
Line 116883: S034098  08-31 11:34:05.734  3934  4106 W RescueParty: Noticed 5 events for UID 10016 in last 10 secLine 119206: S03491B  08-31 11:34:09.965  3934  4906 W RescueParty: Noticed 2 events for UID 10016 in last 1 sec
Line 120468: S034DA1  08-31 11:34:11.946  3934  3945 W RescueParty: Noticed 3 events for UID 10016 in last 3 sec
Line 121787: S03527D  08-31 11:34:13.810  3934  6769 W RescueParty: Noticed 4 events for UID 10016 in last 5 sec
Line 123441: S03584C  08-31 11:34:16.216  3934  4106 W RescueParty: Noticed 5 events for UID 10016 in last 8 sec
     2.  t.reset();
245         public void reset() {246             setCount(0);//之前累积的释放掉,重置为0
247             setStart(0);
248         }
3.   incrementRescueLevel(t.uid);140     /**
141      * Escalate to the next rescue level. After incrementing the level you'll
142      * probably want to call {@link #executeRescueLevel(Context)}.
143      */
144     private static void incrementRescueLevel(int triggerUid) {145         final int level = MathUtils.constrain(
146                 SystemProperties.getInt(PROP_RESCUE_LEVEL, LEVEL_NONE) + 1,
147                 LEVEL_NONE, LEVEL_FACTORY_RESET);//第一次走进来的时候为1,level 也为1 最多为4 为LEVEL_FACTORY_RESET这个值
148         SystemProperties.set(PROP_RESCUE_LEVEL, Integer.toString(level));//保存level
149
150         EventLogTags.writeRescueLevel(level, triggerUid);
151         logCriticalInfo(Log.WARN, "Incremented rescue level to "
152                 + levelToString(level) + " triggered by UID " + triggerUid);
153     }
154 35     public static int constrain(int amount, int low, int high) {36         return amount < low ? low : (amount > high ? high : amount);37     }38
Log:Line 102032: S030AAF  08-31 11:33:43.772  3934 11186 W PackageManager: Incremented rescue level to RESET_SETTINGS_UNTRUSTED_DEFAULTS triggered by UID 10016Line 102033: E030AB0  08-31 11:33:43.772  3934 11186 I pm_critical_info: Incremented rescue level to RESET_SETTINGS_UNTRUSTED_DEFAULTS triggered by UID 10016Line 109332: S0325B9  08-31 11:33:53.379  3934  7285 W PackageManager: Incremented rescue level to RESET_SETTINGS_UNTRUSTED_CHANGES triggered by UID 10016Line 109333: E0325BA  08-31 11:33:53.379  3934  7285 I pm_critical_info: Incremented rescue level to RESET_SETTINGS_UNTRUSTED_CHANGES triggered by UID 10016Line 116885: S03409A  08-31 11:34:05.735  3934  4106 W PackageManager: Incremented rescue level to RESET_SETTINGS_TRUSTED_DEFAULTS triggered by UID 10016Line 116886: E03409B  08-31 11:34:05.735  3934  4106 I pm_critical_info: Incremented rescue level to RESET_SETTINGS_TRUSTED_DEFAULTS triggered by UID 10016Line 123443: S03584E  08-31 11:34:16.217  3934  4106 W PackageManager: Incremented rescue level to FACTORY_RESET triggered by UID 10016Line 123444: E03584F  08-31 11:34:16.217  3934  4106 I pm_critical_info: Incremented rescue level to FACTORY_RESET triggered by UID 10016
4.   executeRescueLevel(context);163     private static void executeRescueLevel(Context context) {164         final int level = SystemProperties.getInt(PROP_RESCUE_LEVEL, LEVEL_NONE);
165         if (level == LEVEL_NONE) return;
166
167         Slog.w(TAG, "Attempting rescue level " + levelToString(level));
168         try {169             executeRescueLevelInternal(context, level);//接下来走这个方法
170             EventLogTags.writeRescueSuccess(level);
171             logCriticalInfo(Log.DEBUG,
172                     "Finished rescue level " + levelToString(level));
173         } catch (Throwable t) {174             final String msg = ExceptionUtils.getCompleteMessage(t);
175             EventLogTags.writeRescueFailure(level, msg);
176             logCriticalInfo(Log.ERROR,
177                     "Failed rescue level " + levelToString(level) + ": " + msg);
178         }
179     }
Log:  Line 102038: S030AB5  08-31 11:33:43.774  3934 11186 W RescueParty: Attempting rescue level RESET_SETTINGS_UNTRUSTED_DEFAULTSLine 109334: S0325BB  08-31 11:33:53.380  3934  7285 W RescueParty: Attempting rescue level RESET_SETTINGS_UNTRUSTED_CHANGESLine 116887: S03409C  08-31 11:34:05.736  3934  4106 W RescueParty: Attempting rescue level RESET_SETTINGS_TRUSTED_DEFAULTSLine 123445: S035850  08-31 11:34:16.217  3934  4106 W RescueParty: Attempting rescue level FACTORY_RESETLine 102049: S030AC0  08-31 11:33:43.775  3934 11186 D PackageManager: Finished rescue level RESET_SETTINGS_UNTRUSTED_DEFAULTSLine 102050: E030AC1  08-31 11:33:43.775  3934 11186 I pm_critical_info: Finished rescue level RESET_SETTINGS_UNTRUSTED_DEFAULTSLine 109337: S0325BE  08-31 11:33:53.381  3934  7285 D PackageManager: Finished rescue level RESET_SETTINGS_UNTRUSTED_CHANGESLine 109338: E0325BF  08-31 11:33:53.381  3934  7285 I pm_critical_info: Finished rescue level RESET_SETTINGS_UNTRUSTED_CHANGESLine 116894: S0340A3  08-31 11:34:05.747  3934  4106 D PackageManager: Finished rescue level RESET_SETTINGS_TRUSTED_DEFAULTSLine 116895: E0340A4  08-31 11:34:05.747  3934  4106 I pm_critical_info: Finished rescue level RESET_SETTINGS_TRUSTED_DEFAULTS
180
181     private static void executeRescueLevelInternal(Context context, int level) throws Exception {182         switch (level) {183             case LEVEL_RESET_SETTINGS_UNTRUSTED_DEFAULTS:
184                 resetAllSettings(context, Settings.RESET_MODE_UNTRUSTED_DEFAULTS);//重置数据
185                 break;
186             case LEVEL_RESET_SETTINGS_UNTRUSTED_CHANGES:
187                 resetAllSettings(context, Settings.RESET_MODE_UNTRUSTED_CHANGES);
188                 break;
189             case LEVEL_RESET_SETTINGS_TRUSTED_DEFAULTS:
190                 resetAllSettings(context, Settings.RESET_MODE_TRUSTED_DEFAULTS);
191                 break;
192             case LEVEL_FACTORY_RESET:
193                 //bug917816 debug system_server/zygote manay times restart question.
194                 if (Build.IS_USERDEBUG){195                     Slog.w(TAG, "[SPRD_DBG]RescueParty ERROR system again and again reboot!!!");
196                 }else{197                     RecoverySystem.rebootPromptAndWipeUserData(context, TAG);
198                 }
199                 break;
200         }
201     }
202 
 总结:第一次常驻应用发生crash,累积5次会从原来的LEVEL_NONE到LEVEL_RESET_SETTINGS_UNTRUSTED_DEFAULTS  (0->1)并且系统做了resetAllSettings,重置了部分数据。第二次常驻应用发生crash,累积5次会从原来的LEVEL_RESET_SETTINGS_UNTRUSTED_DEFAULTS到LEVEL_RESET_SETTINGS_UNTRUSTED_CHANGES(1->2)并且系统仍然尝试重置部分数据。第三次常驻应用发生crash,累积5次会从原来的LEVEL_RESET_SETTINGS_UNTRUSTED_CHANGES到LEVEL_RESET_SETTINGS_TRUSTED_DEFAULTS(2->3)并且系统仍然尝试重置部分数据。第四次常驻应用发生crash,累积5次会从原来的LEVEL_RESET_SETTINGS_TRUSTED_DEFAULTS到LEVEL_FACTORY_RESET(3->4)会再次判断是否为userdebug软件,然后进入recovery模式。

进入recovery模式分析相关推荐

  1. android 系统(154)----OTA制作及升级过程

    OTA制作及升级过程 1.概述 1.1   文档概要 前段时间学习了AndroidRecovery模式及OTA升级过程,为加深理解和防止以后遗忘,所以写这篇文档进行一个总结和梳理,以便日后查阅回顾.文 ...

  2. OTA制作及升级过程笔记

    1.概述 1.1   文档概要 前段时间学习了AndroidRecovery模式及OTA升级过程,为加深理解和防止以后遗忘,所以写这篇文档进行一个总结和梳理,以便日后查阅回顾.文档主要包括两部分,第一 ...

  3. OTA制作及升级过程

    OTA制作及升级过程 1.概述 1.1 文档概要 前段时间学习了AndroidRecovery模式及OTA升级过程,为加深理解和防止以后遗忘,所以写这篇文档进行一个总结和梳理,以便日后查阅回顾.文档主 ...

  4. OTA制作及升级过程笔记【转】

    本文转载自:http://www.it610.com/article/5752570.htm 1.概述 1.1   文档概要 前段时间学习了AndroidRecovery模式及OTA升级过程,为加深理 ...

  5. Android系统Recovery工作原理之使用update.zip升级过程分析(一)

    这篇及以后的篇幅将通过分析update.zip包在具体Android系统升级的过程,来理解Android系统中Recovery模式服务的工作原理.我们先从update.zip包的制作开始,然后是And ...

  6. Android系统Recovery工作原理之使用update.zip升级过程分析(一)---update.zip包的制作【转】...

    本文转载自:http://blog.csdn.net/mu0206mu/article/details/7399822 这篇及以后的篇幅将通过分析update.zip包在具体Android系统升级的过 ...

  7. android 4.0 安全模式分析

    前言 Android系统中具备6个模式,分别为一般启动模式(normal mode).安全模式(safe mode).恢复模式(recovery mode).引导模式(bootloader mode) ...

  8. innodb force recovery

    innodb force recovery的6种设置: 1.innodb force recovery=1,即使发现了损坏页面也继续让服务器继续运行,这个选项对于备份或者转存当前数据尤为有用 2.in ...

  9. oracle block media recovery,Oracle非归档模式Media Recovery错误之--ORA-26040

    11.转储对应的logfile 14:35:48 SYS@ prod>alter system dump logfile '/dsk1/oradata/prod/redo01a.log': Sy ...

最新文章

  1. TableView/CollectionView 滑动顶部效果优化
  2. python读取文件多行内容-Python读取文件、大文件和指定行内容的几种方法
  3. 继承机制中的构造器和析构器 - C++快速入门17
  4. 程序员在未来会变成廉价劳动力(农民工)吗?
  5. CentOS Tomcat6 修改默认端口8080为80
  6. 百度分享--分享按钮的实现
  7. 断今天日期和指定日期相等和两者的时间差为两年的sql
  8. ubuntu mysql 内存满了_Ubuntu mysql可以把data防止到内存盘中
  9. JavaScript是如何工作的:引擎,运行时和调用堆栈的概述!
  10. 我发现了一个价值8500美元的 HackerOne 平台漏洞
  11. MyBaties入门
  12. android Holo UI框架,Holo风格的开源中国Android客户端——持续更新(2)
  13. 计算机怎样用PS抠婚纱图,用PS应该怎样抠出透明婚纱照片
  14. JAVA_调用方法_用户输入姓名打印出欢迎词
  15. 解决方案:rabbitmq使用场景-超时未支付订单处理
  16. 樊登读书分享ppt_樊登读书《干法》学习分享
  17. Centos yum和pip下载离线安装包
  18. 骁龙855+4800万像素+五大配件,魅族16s开售
  19. 内存 profile (zz)
  20. 银行春招:六大行薪资待遇知多少?(下)

热门文章

  1. 体内有湿气是什么原因?常吃这3种食物,或能帮你祛湿
  2. (Tekla Structures二次开发)同一图纸中,不同视图中的局部坐标系也不一样
  3. 蓝湖导出android代码,蓝湖一键生成整页代码,帮开发留住头发
  4. [4G5G专题-24]:架构-5G接入网协议栈规范
  5. 2022 IoTDB Summit:阿里白渐《迈向物联网时代大数据计算平台——MaxCompute 基于IoTDB构建解决方案》...
  6. 不成问题的问题:一个英伟达与另一个英伟达
  7. 用PyQt实现简单的图片浏览器
  8. 【国庆篇】用html5简单制作一个国旗
  9. C4D这10个惊人超实用的功能分享,来学习一下吧
  10. Python 爬取诗词分析古人最喜欢用的诗词