Program: 196839
Project: 196839
Buggy source:
/** 
 * Main code for cleaning up a process when it has gone away.  This is called both as a result of the process dying, or directly when stopping a process when running in single process mode.
 */
private final void cleanUpApplicationRecordLocked(ProcessRecord app,boolean restarting,boolean allowRestart,int index){
  if (index >= 0) {
    removeLruProcessLocked(app);
    ProcessList.remove(app.pid);
  }
  mProcessesToGc.remove(app);
  mPendingPssProcesses.remove(app);
  if (app.crashDialog != null && !app.forceCrashReport) {
    app.crashDialog.dismiss();
    app.crashDialog=null;
  }
  if (app.anrDialog != null) {
    app.anrDialog.dismiss();
    app.anrDialog=null;
  }
  if (app.waitDialog != null) {
    app.waitDialog.dismiss();
    app.waitDialog=null;
  }
  app.crashing=false;
  app.notResponding=false;
  app.resetPackageList(mProcessStats);
  app.unlinkDeathRecipient();
  app.makeInactive(mProcessStats);
  app.waitingToKill=null;
  app.forcingToForeground=null;
  updateProcessForegroundLocked(app,false,false);
  app.foregroundActivities=false;
  app.hasShownUi=false;
  app.treatLikeActivity=false;
  app.hasAboveClient=false;
  app.hasClientActivities=false;
  mServices.killServicesLocked(app,allowRestart);
  boolean restart=false;
  for (int i=app.pubProviders.size() - 1; i >= 0; i--) {
    ContentProviderRecord cpr=app.pubProviders.valueAt(i);
    final boolean always=app.bad || !allowRestart;
    if (removeDyingProviderLocked(app,cpr,always) || always) {
      restart=true;
    }
    cpr.provider=null;
    cpr.proc=null;
  }
  app.pubProviders.clear();
  if (checkAppInLaunchingProvidersLocked(app,false)) {
    restart=true;
  }
  if (!app.conProviders.isEmpty()) {
    for (int i=0; i < app.conProviders.size(); i++) {
      ContentProviderConnection conn=app.conProviders.get(i);
      conn.provider.connections.remove(conn);
    }
    app.conProviders.clear();
  }
  if (false) {
    for (int i=0; i < mLaunchingProviders.size(); i++) {
      ContentProviderRecord cpr=(ContentProviderRecord)mLaunchingProviders.get(i);
      if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
synchronized (cpr) {
          cpr.launchingApp=null;
          cpr.notifyAll();
        }
      }
    }
  }
  skipCurrentReceiverLocked(app);
  for (int i=app.receivers.size() - 1; i >= 0; i--) {
    removeReceiverLocked(app.receivers.valueAt(i));
  }
  app.receivers.clear();
  if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
    if (DEBUG_BACKUP || DEBUG_CLEANUP)     Slog.d(TAG,"String_Node_Str" + mBackupTarget.appInfo + "String_Node_Str");
    try {
      IBackupManager bm=IBackupManager.Stub.asInterface(ServiceManager.getService(Context.BACKUP_SERVICE));
      bm.agentDisconnected(app.info.packageName);
    }
 catch (    RemoteException e) {
    }
  }
  for (int i=mPendingProcessChanges.size() - 1; i >= 0; i--) {
    ProcessChangeItem item=mPendingProcessChanges.get(i);
    if (item.pid == app.pid) {
      mPendingProcessChanges.remove(i);
      mAvailProcessChanges.add(item);
    }
  }
  mHandler.obtainMessage(DISPATCH_PROCESS_DIED,app.pid,app.info.uid,null).sendToTarget();
  if (restarting) {
    return;
  }
  if (!app.persistent || app.isolated) {
    if (DEBUG_PROCESSES || DEBUG_CLEANUP)     Slog.v(TAG,"String_Node_Str" + app);
    mProcessNames.remove(app.processName,app.uid);
    mIsolatedProcesses.remove(app.uid);
    if (mHeavyWeightProcess == app) {
      mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,mHeavyWeightProcess.userId,0));
      mHeavyWeightProcess=null;
    }
  }
 else   if (!app.removed) {
    if (mPersistentStartingProcesses.indexOf(app) < 0) {
      mPersistentStartingProcesses.add(app);
      restart=true;
    }
  }
  if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app))   Slog.v(TAG,"String_Node_Str" + app);
  mProcessesOnHold.remove(app);
  if (app == mHomeProcess) {
    mHomeProcess=null;
  }
  if (app == mPreviousProcess) {
    mPreviousProcess=null;
  }
  if (restart && !app.isolated) {
    mProcessNames.put(app.processName,app.uid,app);
    startProcessLocked(app,"String_Node_Str",app.processName);
  }
 else   if (app.pid > 0 && app.pid != MY_PID) {
    boolean removed;
synchronized (mPidsSelfLocked) {
      mPidsSelfLocked.remove(app.pid);
      mHandler.removeMessages(PROC_START_TIMEOUT_MSG,app);
    }
    mBatteryStatsService.noteProcessFinish(app.processName,app.info.uid);
    if (app.isolated) {
      mBatteryStatsService.removeIsolatedUid(app.uid,app.info.uid);
    }
    app.setPid(0);
  }
}

Fixed version (ground truth):
/** 
 * Main code for cleaning up a process when it has gone away.  This is called both as a result of the process dying, or directly when stopping a process when running in single process mode.
 * @return Returns true if the given process has been restarted, so theapp that was passed in must remain on the process lists.
 */
private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,boolean restarting,boolean allowRestart,int index){
  if (index >= 0) {
    removeLruProcessLocked(app);
    ProcessList.remove(app.pid);
  }
  mProcessesToGc.remove(app);
  mPendingPssProcesses.remove(app);
  if (app.crashDialog != null && !app.forceCrashReport) {
    app.crashDialog.dismiss();
    app.crashDialog=null;
  }
  if (app.anrDialog != null) {
    app.anrDialog.dismiss();
    app.anrDialog=null;
  }
  if (app.waitDialog != null) {
    app.waitDialog.dismiss();
    app.waitDialog=null;
  }
  app.crashing=false;
  app.notResponding=false;
  app.resetPackageList(mProcessStats);
  app.unlinkDeathRecipient();
  app.makeInactive(mProcessStats);
  app.waitingToKill=null;
  app.forcingToForeground=null;
  updateProcessForegroundLocked(app,false,false);
  app.foregroundActivities=false;
  app.hasShownUi=false;
  app.treatLikeActivity=false;
  app.hasAboveClient=false;
  app.hasClientActivities=false;
  mServices.killServicesLocked(app,allowRestart);
  boolean restart=false;
  for (int i=app.pubProviders.size() - 1; i >= 0; i--) {
    ContentProviderRecord cpr=app.pubProviders.valueAt(i);
    final boolean always=app.bad || !allowRestart;
    if (removeDyingProviderLocked(app,cpr,always) || always) {
      restart=true;
    }
    cpr.provider=null;
    cpr.proc=null;
  }
  app.pubProviders.clear();
  if (checkAppInLaunchingProvidersLocked(app,false)) {
    restart=true;
  }
  if (!app.conProviders.isEmpty()) {
    for (int i=0; i < app.conProviders.size(); i++) {
      ContentProviderConnection conn=app.conProviders.get(i);
      conn.provider.connections.remove(conn);
    }
    app.conProviders.clear();
  }
  if (false) {
    for (int i=0; i < mLaunchingProviders.size(); i++) {
      ContentProviderRecord cpr=(ContentProviderRecord)mLaunchingProviders.get(i);
      if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
synchronized (cpr) {
          cpr.launchingApp=null;
          cpr.notifyAll();
        }
      }
    }
  }
  skipCurrentReceiverLocked(app);
  for (int i=app.receivers.size() - 1; i >= 0; i--) {
    removeReceiverLocked(app.receivers.valueAt(i));
  }
  app.receivers.clear();
  if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
    if (DEBUG_BACKUP || DEBUG_CLEANUP)     Slog.d(TAG,"String_Node_Str" + mBackupTarget.appInfo + "String_Node_Str");
    try {
      IBackupManager bm=IBackupManager.Stub.asInterface(ServiceManager.getService(Context.BACKUP_SERVICE));
      bm.agentDisconnected(app.info.packageName);
    }
 catch (    RemoteException e) {
    }
  }
  for (int i=mPendingProcessChanges.size() - 1; i >= 0; i--) {
    ProcessChangeItem item=mPendingProcessChanges.get(i);
    if (item.pid == app.pid) {
      mPendingProcessChanges.remove(i);
      mAvailProcessChanges.add(item);
    }
  }
  mHandler.obtainMessage(DISPATCH_PROCESS_DIED,app.pid,app.info.uid,null).sendToTarget();
  if (restarting) {
    return false;
  }
  if (!app.persistent || app.isolated) {
    if (DEBUG_PROCESSES || DEBUG_CLEANUP)     Slog.v(TAG,"String_Node_Str" + app);
    mProcessNames.remove(app.processName,app.uid);
    mIsolatedProcesses.remove(app.uid);
    if (mHeavyWeightProcess == app) {
      mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,mHeavyWeightProcess.userId,0));
      mHeavyWeightProcess=null;
    }
  }
 else   if (!app.removed) {
    if (mPersistentStartingProcesses.indexOf(app) < 0) {
      mPersistentStartingProcesses.add(app);
      restart=true;
    }
  }
  if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app))   Slog.v(TAG,"String_Node_Str" + app);
  mProcessesOnHold.remove(app);
  if (app == mHomeProcess) {
    mHomeProcess=null;
  }
  if (app == mPreviousProcess) {
    mPreviousProcess=null;
  }
  if (restart && !app.isolated) {
    if (index < 0) {
      ProcessList.remove(app.pid);
    }
    mProcessNames.put(app.processName,app.uid,app);
    startProcessLocked(app,"String_Node_Str",app.processName);
    return true;
  }
 else   if (app.pid > 0 && app.pid != MY_PID) {
    boolean removed;
synchronized (mPidsSelfLocked) {
      mPidsSelfLocked.remove(app.pid);
      mHandler.removeMessages(PROC_START_TIMEOUT_MSG,app);
    }
    mBatteryStatsService.noteProcessFinish(app.processName,app.info.uid);
    if (app.isolated) {
      mBatteryStatsService.removeIsolatedUid(app.uid,app.info.uid);
    }
    app.setPid(0);
  }
  return false;
}