Program: 99193
Project: 99193
Buggy source:
@Override public void run(){
  running=true;
  Rect viewportRect=new Rect(0,0,0,0);
  while (running) {
    while (cache.getState() != CacheState.START_UPDATE)     try {
      Thread.sleep(Integer.MAX_VALUE);
    }
 catch (    InterruptedException e) {
    }
    if (!running)     return;
    long start=System.currentTimeMillis();
    boolean cont=false;
synchronized (cache) {
      if (cache.getState() == CacheState.START_UPDATE) {
        cache.setState(CacheState.IN_UPDATE);
        cache.bitmapRef=null;
        cont=true;
      }
    }
    if (cont) {
synchronized (viewport) {
        viewportRect.set(viewport.window);
      }
synchronized (cache) {
        if (cache.getState() == CacheState.IN_UPDATE)         cache.window.set(calculateCacheWindow(viewportRect));
 else         cont=false;
      }
      if (cont) {
        try {
          Bitmap bitmap=fillCache(cache.window);
synchronized (cache) {
            if (cache.getState() == CacheState.IN_UPDATE) {
              cache.bitmapRef=bitmap;
              cache.setState(CacheState.READY);
            }
 else {
              Log.w(TAG,"String_Node_Str");
            }
          }
          long done=System.currentTimeMillis();
          if (DEBUG)           Log.d(TAG,String.format("String_Node_Str",done - start));
        }
 catch (        OutOfMemoryError e) {
synchronized (cache) {
            fillCacheOutOfMemoryError(e);
            if (cache.getState() == CacheState.IN_UPDATE) {
              cache.setState(CacheState.START_UPDATE);
            }
          }
        }
      }
    }
  }
}

Fixed version (ground truth):
@Override public void run(){
  running=true;
  Rect viewportRect=new Rect(0,0,0,0);
  while (running) {
    while (running && cache.getState() != CacheState.START_UPDATE)     try {
      Thread.sleep(Integer.MAX_VALUE);
    }
 catch (    InterruptedException e) {
    }
    if (!running)     return;
    long start=System.currentTimeMillis();
    boolean cont=false;
synchronized (cache) {
      if (cache.getState() == CacheState.START_UPDATE) {
        cache.setState(CacheState.IN_UPDATE);
        cache.bitmapRef=null;
        cont=true;
      }
    }
    if (cont) {
synchronized (viewport) {
        viewportRect.set(viewport.window);
      }
synchronized (cache) {
        if (cache.getState() == CacheState.IN_UPDATE)         cache.window.set(calculateCacheWindow(viewportRect));
 else         cont=false;
      }
      if (cont) {
        try {
          Bitmap bitmap=fillCache(cache.window);
synchronized (cache) {
            if (cache.getState() == CacheState.IN_UPDATE) {
              cache.bitmapRef=bitmap;
              cache.setState(CacheState.READY);
            }
 else {
              Log.w(TAG,"String_Node_Str");
            }
          }
          long done=System.currentTimeMillis();
          if (DEBUG)           Log.d(TAG,String.format("String_Node_Str",done - start));
        }
 catch (        OutOfMemoryError e) {
synchronized (cache) {
            fillCacheOutOfMemoryError(e);
            if (cache.getState() == CacheState.IN_UPDATE) {
              cache.setState(CacheState.START_UPDATE);
            }
          }
        }
      }
    }
  }
}