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.
{
    
    static std::atomic<bool> latchToFalse{false};
    
    if (latchToFalse.load(std::memory_order_relaxed))
        return false;
    LOCK(cs_main);
    if (latchToFalse.load(std::memory_order_relaxed))
        return false;
    if (fImporting || fReindex)
        return true;
    if (::ChainActive().Tip() == nullptr)
        return true;
    if (::ChainActive().Tip()->nChainWork < nMinimumChainWork)
        return true;
    if (::ChainActive().Tip()->GetBlockTime() < (GetTime() - nMaxTipAge))
        return true;
    LogPrintf("Leaving InitialBlockDownload (latching to false)\n");
    latchToFalse.store(true, std::memory_order_relaxed);
    return false;
}
CBlockIndex *pindexBestForkTip = nullptr, *pindexBestForkBase = nullptr;
static void AlertNotify(const std::string& strMessage)