OSDN Git Service

When fork() fails, clean up data structures.
authorJeff Sharkey <jsharkey@android.com>
Mon, 2 May 2016 18:33:22 +0000 (12:33 -0600)
committerJeff Sharkey <jsharkey@android.com>
Mon, 2 May 2016 18:33:24 +0000 (12:33 -0600)
There are a number of different conditions that could cause
ActivityManager to fail to fork() a process.  One of the most common
ones is a package being "frozen" during a PackageManager operation.

When this happens, use the common forceStopPackageLocked() method
to cleanup any internal bookkeeping structures.  (It's slightly
misnamed, since it doesn't actually "force stop" the app.)  It's
also the same method that we called moments earlier when the package
was first frozen through KILL_APPLICATION_MSG.

Bug: 28395549
Change-Id: I7b1623c5f66fc1de24cad5360c977ea764d09244

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

index ddb9b8a..30dd33f 100644 (file)
@@ -3724,13 +3724,16 @@ public final class ActivityManagerService extends ActivityManagerNative
             }
             checkTime(startTime, "startProcess: done updating pids map");
         } catch (RuntimeException e) {
-            // XXX do better error recovery.
-            app.setPid(0);
-            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
-            if (app.isolated) {
-                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
-            }
             Slog.e(TAG, "Failure starting process " + app.processName, e);
+
+            // Something went very wrong while trying to start this process; one
+            // common case is when the package is frozen due to an active
+            // upgrade. To recover, clean up any active bookkeeping related to
+            // starting this process. (We already invoked this method once when
+            // the package was initially frozen through KILL_APPLICATION_MSG, so
+            // it doesn't hurt to use it again.)
+            forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
+                    false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
         }
     }