While checking #16661 I stumbled upon what seems to be a lifetime issue in `ReleaseWallet(CWallet* wallet)` (`wallet.cpp`).

https://github.com/bitcoin/bitcoin/blob/fa6431055abfacea4f72ef11d061c7c755de327a/src/wallet/wallet.cpp#L107-L111

After `delete wallet;` the pointer is invalid and shouldn't be used like in the call `g_unloading_wallet_set.erase(wallet)`.

The code was introduced in #14941 which was merged into `master` on January 15, 2019.

In addition to fixing this specific instance it might be worth thinking about how we can use static analysis to automatically catch this class of issues going forward :-)
{
    WalletBatch batch(*database);
    return AddCScriptWithDB(batch, redeemScript);
}
bool CWallet::AddCScriptWithDB(WalletBatch& batch, const CScript& redeemScript)
{
    if (!FillableSigningProvider::AddCScript(redeemScript))
        return false;
    if (batch.WriteCScript(Hash160(redeemScript), redeemScript)) {
        UnsetWalletFlagWithDB(batch, WALLET_FLAG_BLANK_WALLET);
        return true;
    }
    return false;
}
bool CWallet::LoadCScript(const CScript& redeemScript)
{
    /* A sanity check was added in pull #3843 to avoid adding redeemScripts
     * that never can be redeemed. However, old wallets may still contain
     * these. Do not add them to the wallet and warn. */
    if (redeemScript.size() > MAX_SCRIPT_ELEMENT_SIZE)
    {
        std::string strAddr = EncodeDestination(ScriptHash(redeemScript));
        WalletLogPrintf("%s: Warning: This wallet contains a redeemScript of size %i which exceeds maximum size %i thus can never be redeemed. Do not use address %s.\n", __func__, redeemScript.size(), MAX_SCRIPT_ELEMENT_SIZE, strAddr);
        return true;
    }
    return FillableSigningProvider::AddCScript(redeemScript);
}
static bool ExtractPubKey(const CScript &dest, CPubKey& pubKeyOut)