From 0120825e34b72c623ece09cb7fc09ca9e399f8e7 Mon Sep 17 00:00:00 2001 From: Jing Ji Date: Tue, 16 Nov 2021 00:04:48 -0800 Subject: [PATCH] Fix race conditions in removing dying process record While waiting for the death of a process, if its subsequent process record is created and killed immediately, we may end up removing the former process record from the dying process list. Bug: 201305599 Bug: 206336727 Test: Presubmit Change-Id: I00521a5561d98f2df6f52443b9e23025faeaeb3c --- .../com/android/server/am/ActivityManagerService.java | 9 +++++++++ .../core/java/com/android/server/am/ProcessList.java | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index b1a1e0d230198..a2299ca0f3718 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -11910,6 +11910,15 @@ public class ActivityManagerService extends IActivityManager.Stub // If this is a preceding instance of another process instance allowRestart = mProcessList.handlePrecedingAppDiedLocked(app); + // If somehow this process was still waiting for the death of its predecessor, + // (probably it's "killed" before starting for real), reset the bookkeeping. + final ProcessRecord predecessor = app.mPredecessor; + if (predecessor != null) { + predecessor.mSuccessor = null; + predecessor.mSuccessorStartRunnable = null; + app.mPredecessor = null; + } + // If the caller is restarting this app, then leave it in its // current lists and let the caller take care of it. if (restarting) { diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index ca32e08dcddee..0df19ba43e4e4 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -5143,7 +5143,8 @@ public final class ProcessList { } Watchdog.getInstance().processDied(app.processName, app.getPid()); - if (app.getDeathRecipient() == null) { + if (app.getDeathRecipient() == null + && mDyingProcesses.get(app.processName, app.uid) == app) { // If we've done unlinkDeathRecipient before calling into this, remove from dying list. mDyingProcesses.remove(app.processName, app.uid); app.setDyingPid(0);