Program: 160268
Project: 160268
Buggy source:
public void testUpdateDocsAndReadRevHistory() throws Exception {
  if (!multithreadsTestsEnabled())   return;
  if (!isSQLiteDB())   return;
  Thread insertThread=new Thread(new Runnable(){
    @Override public void run(){
      for (int i=0; i < 100; i++) {
        String docID=String.format(Locale.ENGLISH,"String_Node_Str",i);
        Document doc=database.getDocument(docID);
        Map<String,Object> props=new HashMap<String,Object>();
        props.put("String_Node_Str",i);
        try {
          doc.putProperties(props);
        }
 catch (        CouchbaseLiteException e) {
          Log.e(TAG,"String_Node_Str",e);
          fail(e.getMessage());
        }
      }
    }
  }
);
  insertThread.start();
  try {
    insertThread.join();
  }
 catch (  InterruptedException e) {
    Log.e(TAG,"String_Node_Str",e);
  }
  Thread readThread=new Thread(new Runnable(){
    @Override public void run(){
      for (int j=0; j < 20; j++) {
        for (int i=0; i < 100; i++) {
          String docID=String.format(Locale.ENGLISH,"String_Node_Str",i);
          Document doc=database.getDocument(docID);
          String revID=doc.getCurrentRevisionId();
          RevisionInternal rev=new RevisionInternal(doc.getId(),doc.getCurrentRevisionId(),false);
          List<RevisionInternal> revs=database.getRevisionHistory(rev);
          assertNotNull(revs);
        }
      }
    }
  }
);
  Thread updateThread=new Thread(new Runnable(){
    @Override public void run(){
      for (int i=0; i < 100; i++) {
        String docID=String.format(Locale.ENGLISH,"String_Node_Str",i);
        Log.e(TAG,"String_Node_Str",docID);
        for (int j=0; j < 20; j++) {
          Document doc=database.getDocument(docID);
          Map<String,Object> props=new HashMap<String,Object>();
          props.putAll(doc.getProperties());
          props.put("String_Node_Str",j);
          try {
            doc.putProperties(props);
          }
 catch (          CouchbaseLiteException e) {
            Log.e(TAG,"String_Node_Str",e,Thread.currentThread().getName());
            fail(e.getMessage());
          }
        }
      }
    }
  }
);
  readThread.start();
  updateThread.start();
  try {
    readThread.join();
  }
 catch (  InterruptedException e) {
    Log.e(TAG,"String_Node_Str",e);
  }
  try {
    updateThread.join();
  }
 catch (  InterruptedException e) {
    Log.e(TAG,"String_Node_Str",e);
  }
}

Fixed version (ground truth):
/** 
 * IMPORTANT: DON'T run this test with Genymotion emulator with Android 4.x or older. It caseus unknown crash. https://github.com/couchbase/couchbase-lite-java-core/issues/1437
 */
public void testUpdateDocsAndReadRevHistory() throws Exception {
  if (!multithreadsTestsEnabled())   return;
  Thread insertThread=new Thread(new Runnable(){
    @Override public void run(){
      for (int i=0; i < 100; i++) {
        String docID=String.format(Locale.ENGLISH,"String_Node_Str",i);
        Document doc=database.getDocument(docID);
        Map<String,Object> props=new HashMap<String,Object>();
        props.put("String_Node_Str",i);
        try {
          doc.putProperties(props);
        }
 catch (        CouchbaseLiteException e) {
          Log.e(TAG,"String_Node_Str",e);
          fail(e.getMessage());
        }
      }
    }
  }
);
  insertThread.start();
  try {
    insertThread.join();
  }
 catch (  InterruptedException e) {
    Log.e(TAG,"String_Node_Str",e);
  }
  Thread readThread=new Thread(new Runnable(){
    @Override public void run(){
      for (int j=0; j < 20; j++) {
        for (int i=0; i < 100; i++) {
          String docID=String.format(Locale.ENGLISH,"String_Node_Str",i);
          Document doc=database.getDocument(docID);
          String revID=doc.getCurrentRevisionId();
          RevisionInternal rev=new RevisionInternal(doc.getId(),doc.getCurrentRevisionId(),false);
          List<RevisionInternal> revs=database.getRevisionHistory(rev);
          assertNotNull(revs);
        }
      }
    }
  }
);
  Thread updateThread=new Thread(new Runnable(){
    @Override public void run(){
      for (int i=0; i < 100; i++) {
        String docID=String.format(Locale.ENGLISH,"String_Node_Str",i);
        Log.e(TAG,"String_Node_Str",docID);
        for (int j=0; j < 20; j++) {
          Document doc=database.getDocument(docID);
          Map<String,Object> props=new HashMap<String,Object>();
          props.putAll(doc.getProperties());
          props.put("String_Node_Str",j);
          try {
            doc.putProperties(props);
          }
 catch (          CouchbaseLiteException e) {
            Log.e(TAG,"String_Node_Str",e,Thread.currentThread().getName());
            fail(e.getMessage());
          }
        }
      }
    }
  }
);
  readThread.start();
  updateThread.start();
  try {
    readThread.join();
  }
 catch (  InterruptedException e) {
    Log.e(TAG,"String_Node_Str",e);
  }
  try {
    updateThread.join();
  }
 catch (  InterruptedException e) {
    Log.e(TAG,"String_Node_Str",e);
  }
}