init.cpp:1635 prints mapBlockIndex.size() without cs_main. This is technically a race (though it is rather inconsequential). At some point someone should fix this so tsan stops complaining.
if (!tx.vout[o].scriptPubKey.IsUnspendable()) {
                COutPoint out(hash, o);
                Coin coin;
                bool is_spent = view.SpendCoin(out, &coin);
                if (!is_spent || tx.vout[o] != coin.out || pindex->nHeight != coin.nHeight || is_coinbase != coin.fCoinBase) {
                    fClean = false; 
                }
            }
        }
        
        if (i > 0) { 
            CTxUndo &txundo = blockUndo.vtxundo[i-1];
            if (txundo.vprevout.size() != tx.vin.size()) {
                error("DisconnectBlock(): transaction and undo data inconsistent");
                return DISCONNECT_FAILED;
            }
            for (unsigned int j = tx.vin.size(); j-- > 0;) {
                const COutPoint &out = tx.vin[j].prevout;
                int res = ApplyTxInUndo(std::move(txundo.vprevout[j]), view, out);
                if (res == DISCONNECT_FAILED) return DISCONNECT_FAILED;
                fClean = fClean && res != DISCONNECT_UNCLEAN;
            }
            
        }
    }
    
    view.SetBestBlock(pindex->pprev->GetBlockHash());
    return fClean ? DISCONNECT_OK : DISCONNECT_UNCLEAN;
}
void static FlushBlockFile(bool fFinalize = false)