Repository: dotnet/runtime
File: src/coreclr/vm/excep.cpp (C++)

Code before:
    // Always save the current object in the handle so on rethrow we can reuse it. This is important as it
    // contains stack trace info.
    //
    // Note: we use SafeSetLastThrownObject, which will try to set the throwable and if there are any problems,
    // it will set the throwable to something appropriate (like OOM exception) and return the new
    // exception. Thus, the user's exception object can be replaced here.
    throwable = pThread->SafeSetLastThrownObject(throwable);

    ULONG_PTR hr = GetHRFromThrowable(throwable);

    argCount = MarkAsThrownByUs(exceptionArgs, hr);
    flags = EXCEPTION_NONCONTINUABLE;
    code = EXCEPTION_COMPLUS;

    if (pThread->IsAbortInitiated () && IsExceptionOfType(kThreadAbortException,&throwable))
    {
        pThread->ResetPreparingAbort();

        if (pThread->GetFrame() == FRAME_TOP)
        {
            // There is no more managed code on stack.
            pThread->ResetAbort();
        }
    }

    // Can't access the exception object when are in pre-emptive, so find out before
    // if its an SO.
    BOOL fIsStackOverflow = IsExceptionOfType(kStackOverflowException, &throwable);

    if (fIsStackOverflow)
    {
        // Don't probe if we're already handling an SO.  Just throw the exception.
        RaiseException(code, flags, argCount, exceptionArgs);
    }

    // This needs to be both here and inside the handler below
    // enable preemptive mode before call into OS
    GCX_PREEMP_NO_DTOR();

    // In non-debug, we can just raise the exception once we've probed.
    RaiseException(code, flags, argCount, exceptionArgs);

    _ASSERTE(!"Cannot continue after CLR exception");      // Debugger can bring you here.
    // For example,
    // Debugger breaks in due to second chance exception (unhandled)
    // User hits 'g'
    // Then debugger can bring us here.
    EEPOLICY_HANDLE_FATAL_ERROR(COR_E_EXECUTIONENGINE);
    UNREACHABLE();
}


Review comment (bug):
I think this whole special check for stack overflow can be deleted. It looks like a left-over from times where we tried to have stackoverflows that can be handled.

Code after:
    // Always save the current object in the handle so on rethrow we can reuse it. This is important as it
    // contains stack trace info.
    //
    // Note: we use SafeSetLastThrownObject, which will try to set the throwable and if there are any problems,
    // it will set the throwable to something appropriate (like OOM exception) and return the new
    // exception. Thus, the user's exception object can be replaced here.
    throwable = pThread->SafeSetLastThrownObject(throwable);

    ULONG_PTR hr = GetHRFromThrowable(throwable);

    argCount = MarkAsThrownByUs(exceptionArgs, hr);
    flags = EXCEPTION_NONCONTINUABLE;
    code = EXCEPTION_COMPLUS;

    if (pThread->IsAbortInitiated () && IsExceptionOfType(kThreadAbortException,&throwable))
    {
        pThread->ResetPreparingAbort();

        if (pThread->GetFrame() == FRAME_TOP)
        {
            // There is no more managed code on stack.
            pThread->ResetAbort();
        }
    }

    // Enable preemptive mode before call into OS
    GCX_PREEMP_NO_DTOR();

    RaiseException(code, flags, argCount, exceptionArgs);

    _ASSERTE(!"Cannot continue after CLR exception");      // Debugger can bring you here.
    // For example,
    // Debugger breaks in due to second chance exception (unhandled)
    // User hits 'g'
    // Then debugger can bring us here.
    EEPOLICY_HANDLE_FATAL_ERROR(COR_E_EXECUTIONENGINE);
    UNREACHABLE();
}

static VOID DECLSPEC_NORETURN RealCOMPlusThrowWorker(OBJECTREF throwable)
{
    STATIC_CONTRACT_THROWS;
    STATIC_CONTRACT_GC_TRIGGERS;
    STATIC_CONTRACT_MODE_ANY;

    // RaiseTheException will throw C++ OOM and SO, so that our escalation policy can kick in.
    // Unfortunately, COMPlusFrameHandler installed here, will try to create managed exception object.
    // We may hit a recursion.

    _ASSERTE(throwable != CLRException::GetPreallocatedStackOverflowException());