frameworks
/base
/services
/java
/com
/android
/server
/SystemServer
.java
305
308 public static void main(String
[] args
) {
309 new SystemServer().run();
310 }
run方法中执行了
java
446 try {
447 traceBeginAndSlog("StartServices");
448 startBootstrapServices();
449 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
604
605
606 RescueParty
.noteBoot(mSystemContext
);
...
}
最终会到 这是第一个会造成触救援发机制的原因,
frameworks
/base
/services
/core
/java
/com
/android
/server
/RescueParty
.java
102
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
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
443
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
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;
262 setCount(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
);
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 sec
Line 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 sec
Line 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 sec
Line 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);
247 setStart(0);
248 }
3. incrementRescueLevel(t
.uid
);
140
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
);
148 SystemProperties
.set(PROP_RESCUE_LEVEL
, Integer
.toString(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 10016
Line 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 10016
Line 109332: S0325B9 08-31 11:33:53.379 3934 7285 W PackageManager: Incremented rescue level to RESET_SETTINGS_UNTRUSTED_CHANGES triggered by UID 10016
Line 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 10016
Line 116885: S03409A 08-31 11:34:05.735 3934 4106 W PackageManager: Incremented rescue level to RESET_SETTINGS_TRUSTED_DEFAULTS triggered by UID 10016
Line 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 10016
Line 123443: S03584E 08-31 11:34:16.217 3934 4106 W PackageManager: Incremented rescue level to FACTORY_RESET triggered by UID 10016
Line 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_DEFAULTS
Line 109334: S0325BB 08-31 11:33:53.380 3934 7285 W RescueParty: Attempting rescue level RESET_SETTINGS_UNTRUSTED_CHANGES
Line 116887: S03409C 08-31 11:34:05.736 3934 4106 W RescueParty: Attempting rescue level RESET_SETTINGS_TRUSTED_DEFAULTS
Line 123445: S035850 08-31 11:34:16.217 3934 4106 W RescueParty: Attempting rescue level FACTORY_RESET
Line 102049: S030AC0 08-31 11:33:43.775 3934 11186 D PackageManager: Finished rescue level RESET_SETTINGS_UNTRUSTED_DEFAULTS
Line 102050: E030AC1 08-31 11:33:43.775 3934 11186 I pm_critical_info: Finished rescue level RESET_SETTINGS_UNTRUSTED_DEFAULTS
Line 109337: S0325BE 08-31 11:33:53.381 3934 7285 D PackageManager: Finished rescue level RESET_SETTINGS_UNTRUSTED_CHANGES
Line 109338: E0325BF 08-31 11:33:53.381 3934 7285 I pm_critical_info: Finished rescue level RESET_SETTINGS_UNTRUSTED_CHANGES
Line 116894: S0340A3 08-31 11:34:05.747 3934 4106 D PackageManager: Finished rescue level RESET_SETTINGS_TRUSTED_DEFAULTS
Line 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
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模式。