Program: 196821
Project: 196821
Buggy source:
final void killServicesLocked(ProcessRecord app,boolean allowRestart){
  if (false) {
    if (app.services.size() > 0) {
      Iterator<ServiceRecord> it=app.services.iterator();
      while (it.hasNext()) {
        ServiceRecord r=it.next();
        for (int conni=r.connections.size() - 1; conni >= 0; conni--) {
          ArrayList<ConnectionRecord> cl=r.connections.valueAt(conni);
          for (int i=0; i < cl.size(); i++) {
            ConnectionRecord c=cl.get(i);
            if (c.binding.client != app) {
              try {
              }
 catch (              Exception e) {
                Slog.w(TAG,"String_Node_Str" + r.shortName + "String_Node_Str"+ app.processName,e);
              }
            }
          }
        }
      }
    }
  }
  for (int i=app.services.size() - 1; i >= 0; i--) {
    ServiceRecord sr=app.services.valueAt(i);
synchronized (sr.stats.getBatteryStats()) {
      sr.stats.stopLaunchedLocked();
    }
    if (sr.app != app && sr.app != null && !sr.app.persistent) {
      sr.app.services.remove(sr);
    }
    sr.app=null;
    sr.isolatedProc=null;
    sr.executeNesting=0;
    sr.forceClearTracker();
    if (mDestroyingServices.remove(sr)) {
      if (DEBUG_SERVICE)       Slog.v(TAG,"String_Node_Str" + sr);
    }
    final int numClients=sr.bindings.size();
    for (int bindingi=numClients - 1; bindingi >= 0; bindingi--) {
      IntentBindRecord b=sr.bindings.valueAt(bindingi);
      if (DEBUG_SERVICE)       Slog.v(TAG,"String_Node_Str" + b + "String_Node_Str"+ b.hasBound);
      b.binder=null;
      b.requested=b.received=b.hasBound=false;
      for (int appi=b.apps.size() - 1; appi >= 0; appi--) {
        final ProcessRecord proc=b.apps.keyAt(appi);
        if (proc.killedByAm || proc.thread == null) {
          continue;
        }
        final AppBindRecord abind=b.apps.valueAt(appi);
        boolean hasCreate=false;
        for (int conni=abind.connections.size() - 1; conni >= 0; conni--) {
          ConnectionRecord conn=abind.connections.valueAt(conni);
          if ((conn.flags & (Context.BIND_AUTO_CREATE | Context.BIND_ALLOW_OOM_MANAGEMENT | Context.BIND_WAIVE_PRIORITY)) == Context.BIND_AUTO_CREATE) {
            hasCreate=true;
            break;
          }
        }
        if (!hasCreate) {
          continue;
        }
        if (proc != null && !proc.persistent && proc.thread != null && proc.pid != 0 && proc.pid != ActivityManagerService.MY_PID && proc.setProcState >= ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
          proc.kill("String_Node_Str" + sr.name.flattenToShortString() + "String_Node_Str"+ (app != null ? app.processName : "String_Node_Str"),true);
        }
      }
    }
  }
  for (int i=app.connections.size() - 1; i >= 0; i--) {
    ConnectionRecord r=app.connections.valueAt(i);
    removeConnectionLocked(r,app,null);
  }
  updateServiceConnectionActivitiesLocked(app);
  app.connections.clear();
  ServiceMap smap=getServiceMap(app.userId);
  for (int i=app.services.size() - 1; i >= 0; i--) {
    ServiceRecord sr=app.services.valueAt(i);
    if (!app.persistent) {
      app.services.removeAt(i);
    }
    final ServiceRecord curRec=smap.mServicesByName.get(sr.name);
    if (curRec != sr) {
      if (curRec != null) {
        Slog.wtf(TAG,"String_Node_Str" + sr + "String_Node_Str"+ app+ "String_Node_Str"+ curRec);
      }
      continue;
    }
    if (allowRestart && sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) == 0) {
      Slog.w(TAG,"String_Node_Str" + sr.crashCount + "String_Node_Str"+ sr);
      EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,sr.userId,sr.crashCount,sr.shortName,app.pid);
      bringDownServiceLocked(sr);
    }
 else     if (!allowRestart) {
      bringDownServiceLocked(sr);
    }
 else {
      boolean canceled=scheduleServiceRestartLocked(sr,true);
      if (sr.startRequested && (sr.stopIfKilled || canceled)) {
        if (sr.pendingStarts.size() == 0) {
          sr.startRequested=false;
          if (sr.tracker != null) {
            sr.tracker.setStarted(false,mAm.mProcessStats.getMemFactorLocked(),SystemClock.uptimeMillis());
          }
          if (!sr.hasAutoCreateConnections()) {
            bringDownServiceLocked(sr);
          }
        }
      }
    }
  }
  if (!allowRestart) {
    app.services.clear();
    for (int i=mRestartingServices.size() - 1; i >= 0; i--) {
      ServiceRecord r=mRestartingServices.get(i);
      if (r.processName.equals(app.processName) && r.serviceInfo.applicationInfo.uid == app.info.uid) {
        mRestartingServices.remove(i);
        clearRestartingIfNeededLocked(r);
      }
    }
    for (int i=mPendingServices.size() - 1; i >= 0; i--) {
      ServiceRecord r=mPendingServices.get(i);
      if (r.processName.equals(app.processName) && r.serviceInfo.applicationInfo.uid == app.info.uid) {
        mPendingServices.remove(i);
      }
    }
  }
  int i=mDestroyingServices.size();
  while (i > 0) {
    i--;
    ServiceRecord sr=mDestroyingServices.get(i);
    if (sr.app == app) {
      sr.forceClearTracker();
      mDestroyingServices.remove(i);
      if (DEBUG_SERVICE)       Slog.v(TAG,"String_Node_Str" + sr);
    }
  }
  app.executingServices.clear();
}

Fixed version (ground truth):
final void killServicesLocked(ProcessRecord app,boolean allowRestart){
  if (false) {
    if (app.services.size() > 0) {
      Iterator<ServiceRecord> it=app.services.iterator();
      while (it.hasNext()) {
        ServiceRecord r=it.next();
        for (int conni=r.connections.size() - 1; conni >= 0; conni--) {
          ArrayList<ConnectionRecord> cl=r.connections.valueAt(conni);
          for (int i=0; i < cl.size(); i++) {
            ConnectionRecord c=cl.get(i);
            if (c.binding.client != app) {
              try {
              }
 catch (              Exception e) {
                Slog.w(TAG,"String_Node_Str" + r.shortName + "String_Node_Str"+ app.processName,e);
              }
            }
          }
        }
      }
    }
  }
  for (int i=app.services.size() - 1; i >= 0; i--) {
    ServiceRecord sr=app.services.valueAt(i);
synchronized (sr.stats.getBatteryStats()) {
      sr.stats.stopLaunchedLocked();
    }
    if (sr.app != app && sr.app != null && !sr.app.persistent) {
      sr.app.services.remove(sr);
    }
    sr.app=null;
    sr.isolatedProc=null;
    sr.executeNesting=0;
    sr.forceClearTracker();
    if (mDestroyingServices.remove(sr)) {
      if (DEBUG_SERVICE)       Slog.v(TAG,"String_Node_Str" + sr);
    }
    final int numClients=sr.bindings.size();
    for (int bindingi=numClients - 1; bindingi >= 0; bindingi--) {
      IntentBindRecord b=sr.bindings.valueAt(bindingi);
      if (DEBUG_SERVICE)       Slog.v(TAG,"String_Node_Str" + b + "String_Node_Str"+ b.hasBound);
      b.binder=null;
      b.requested=b.received=b.hasBound=false;
      for (int appi=b.apps.size() - 1; appi >= 0; appi--) {
        final ProcessRecord proc=b.apps.keyAt(appi);
        if (proc.killedByAm || proc.thread == null) {
          continue;
        }
        final AppBindRecord abind=b.apps.valueAt(appi);
        boolean hasCreate=false;
        for (int conni=abind.connections.size() - 1; conni >= 0; conni--) {
          ConnectionRecord conn=abind.connections.valueAt(conni);
          if ((conn.flags & (Context.BIND_AUTO_CREATE | Context.BIND_ALLOW_OOM_MANAGEMENT | Context.BIND_WAIVE_PRIORITY)) == Context.BIND_AUTO_CREATE) {
            hasCreate=true;
            break;
          }
        }
        if (!hasCreate) {
          continue;
        }
        if (false && proc != null && !proc.persistent && proc.thread != null && proc.pid != 0 && proc.pid != ActivityManagerService.MY_PID && proc.setProcState >= ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
          proc.kill("String_Node_Str" + sr.name.flattenToShortString() + "String_Node_Str"+ (app != null ? app.processName : "String_Node_Str"),true);
        }
      }
    }
  }
  for (int i=app.connections.size() - 1; i >= 0; i--) {
    ConnectionRecord r=app.connections.valueAt(i);
    removeConnectionLocked(r,app,null);
  }
  updateServiceConnectionActivitiesLocked(app);
  app.connections.clear();
  ServiceMap smap=getServiceMap(app.userId);
  for (int i=app.services.size() - 1; i >= 0; i--) {
    ServiceRecord sr=app.services.valueAt(i);
    if (!app.persistent) {
      app.services.removeAt(i);
    }
    final ServiceRecord curRec=smap.mServicesByName.get(sr.name);
    if (curRec != sr) {
      if (curRec != null) {
        Slog.wtf(TAG,"String_Node_Str" + sr + "String_Node_Str"+ app+ "String_Node_Str"+ curRec);
      }
      continue;
    }
    if (allowRestart && sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) == 0) {
      Slog.w(TAG,"String_Node_Str" + sr.crashCount + "String_Node_Str"+ sr);
      EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,sr.userId,sr.crashCount,sr.shortName,app.pid);
      bringDownServiceLocked(sr);
    }
 else     if (!allowRestart) {
      bringDownServiceLocked(sr);
    }
 else {
      boolean canceled=scheduleServiceRestartLocked(sr,true);
      if (sr.startRequested && (sr.stopIfKilled || canceled)) {
        if (sr.pendingStarts.size() == 0) {
          sr.startRequested=false;
          if (sr.tracker != null) {
            sr.tracker.setStarted(false,mAm.mProcessStats.getMemFactorLocked(),SystemClock.uptimeMillis());
          }
          if (!sr.hasAutoCreateConnections()) {
            bringDownServiceLocked(sr);
          }
        }
      }
    }
  }
  if (!allowRestart) {
    app.services.clear();
    for (int i=mRestartingServices.size() - 1; i >= 0; i--) {
      ServiceRecord r=mRestartingServices.get(i);
      if (r.processName.equals(app.processName) && r.serviceInfo.applicationInfo.uid == app.info.uid) {
        mRestartingServices.remove(i);
        clearRestartingIfNeededLocked(r);
      }
    }
    for (int i=mPendingServices.size() - 1; i >= 0; i--) {
      ServiceRecord r=mPendingServices.get(i);
      if (r.processName.equals(app.processName) && r.serviceInfo.applicationInfo.uid == app.info.uid) {
        mPendingServices.remove(i);
      }
    }
  }
  int i=mDestroyingServices.size();
  while (i > 0) {
    i--;
    ServiceRecord sr=mDestroyingServices.get(i);
    if (sr.app == app) {
      sr.forceClearTracker();
      mDestroyingServices.remove(i);
      if (DEBUG_SERVICE)       Slog.v(TAG,"String_Node_Str" + sr);
    }
  }
  app.executingServices.clear();
}