Skip to content

Commit 7bb2581

Browse files
Magnus EdlundJean-Baptiste Queru
authored andcommitted
Fix problem with restarting an application process that recently has died.
There exists a race condition when starting a process that recently has died. If the ActivityManager receives the death notification for the died process after the new process has been started but before an application thread has been attached to the new process will the newly created process be removed during the cleanup of the died process. If this happens when sending a broadcast could it result in an ANR. This is solved by doing the clean up before starting a new process that uses the same process record.
1 parent 853226b commit 7bb2581

File tree

1 file changed

+19
-5
lines changed

1 file changed

+19
-5
lines changed

services/java/com/android/server/am/ActivityManagerService.java

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1905,11 +1905,16 @@ private final ProcessRecord startProcessLocked(String processName,
19051905
+ " app=" + app + " knownToBeDead=" + knownToBeDead
19061906
+ " thread=" + (app != null ? app.thread : null)
19071907
+ " pid=" + (app != null ? app.pid : -1));
1908-
if (app != null &&
1909-
(!knownToBeDead || app.thread == null) && app.pid > 0) {
1910-
return app;
1908+
if (app != null && app.pid > 0) {
1909+
if (!knownToBeDead || app.thread == null) {
1910+
return app;
1911+
} else {
1912+
// An application record is attached to a previous process,
1913+
// clean it up now.
1914+
handleAppDiedLocked(app, true);
1915+
}
19111916
}
1912-
1917+
19131918
String hostingNameStr = hostingName != null
19141919
? hostingName.flattenToShortString() : null;
19151920

@@ -4553,7 +4558,9 @@ private final void appDiedLocked(ProcessRecord app, int pid,
45534558

45544559
mProcDeaths[0]++;
45554560

4556-
if (app.thread != null && app.thread.asBinder() == thread.asBinder()) {
4561+
// Clean up already done if the process has been re-started.
4562+
if (app.pid == pid && app.thread != null &&
4563+
app.thread.asBinder() == thread.asBinder()) {
45574564
Log.i(TAG, "Process " + app.processName + " (pid " + pid
45584565
+ ") has died.");
45594566
EventLog.writeEvent(LOG_AM_PROCESS_DIED, app.pid, app.processName);
@@ -4603,6 +4610,11 @@ private final void appDiedLocked(ProcessRecord app, int pid,
46034610
scheduleAppGcsLocked();
46044611
}
46054612
}
4613+
} else if (app.pid != pid) {
4614+
// A new process has already been started.
4615+
Log.i(TAG, "Process " + app.processName + " (pid " + pid
4616+
+ ") has died and restarted (pid " + app.pid + ").");
4617+
EventLog.writeEvent(LOG_AM_PROCESS_DIED, pid, app.processName);
46064618
} else if (Config.LOGD) {
46074619
Log.d(TAG, "Received spurious death notification for thread "
46084620
+ thread.asBinder());
@@ -5424,6 +5436,8 @@ private final boolean attachApplicationLocked(IApplicationThread thread,
54245436
finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
54255437
br.resultExtras, br.resultAbort, true);
54265438
scheduleBroadcastsLocked();
5439+
// We need to reset the state if we fails to start the receiver.
5440+
br.state = BroadcastRecord.IDLE;
54275441
}
54285442
}
54295443

0 commit comments

Comments
 (0)