LoadChainTip requires cs_main to be locked. Under some conditions, it may call ActivateBestChain. However, ActivateBestChain requires cs_main NOT to be taken when called.
bool ret = DisconnectTip(state, chainparams, &disconnectpool);
        
        
        
        
        
        UpdateMempoolForReorg(disconnectpool,  (++disconnected <= 10) && ret);
        if (!ret) return false;
        assert(invalid_walk_tip->pprev == m_chain.Tip());
        
        
        
        
        
        invalid_walk_tip->nStatus |= BLOCK_FAILED_VALID;
        setDirtyBlockIndex.insert(invalid_walk_tip);
        setBlockIndexCandidates.erase(invalid_walk_tip);
        setBlockIndexCandidates.insert(invalid_walk_tip->pprev);
        if (invalid_walk_tip->pprev == to_mark_failed && (to_mark_failed->nStatus & BLOCK_FAILED_VALID)) {
            
            
            to_mark_failed->nStatus = (to_mark_failed->nStatus ^ BLOCK_FAILED_VALID) | BLOCK_FAILED_CHILD;
            setDirtyBlockIndex.insert(to_mark_failed);
        }
        
        
        to_mark_failed = invalid_walk_tip;
    }
    {
        LOCK(cs_main);