diff --git a/src/coreclr/clrdefinitions.cmake b/src/coreclr/clrdefinitions.cmake index ce2bc382a99377..aa071ea69fe3db 100644 --- a/src/coreclr/clrdefinitions.cmake +++ b/src/coreclr/clrdefinitions.cmake @@ -105,7 +105,6 @@ endif(CLR_CMAKE_TARGET_WIN32) add_definitions(-DFEATURE_BASICFREEZE) add_definitions(-DFEATURE_CORECLR) add_definitions(-DFEATURE_CORESYSTEM) -add_definitions(-DFEATURE_CORRUPTING_EXCEPTIONS) if(FEATURE_DBGIPC) add_definitions(-DFEATURE_DBGIPC_TRANSPORT_DI) add_definitions(-DFEATURE_DBGIPC_TRANSPORT_VM) diff --git a/src/coreclr/src/inc/clrconfigvalues.h b/src/coreclr/src/inc/clrconfigvalues.h index 51b47e4f7ec19b..f4cf1d192905c0 100644 --- a/src/coreclr/src/inc/clrconfigvalues.h +++ b/src/coreclr/src/inc/clrconfigvalues.h @@ -253,7 +253,6 @@ CONFIG_DWORD_INFO(INTERNAL_SuppressLockViolationsOnReentryFromOS, W("SuppressLoc CONFIG_DWORD_INFO_DIRECT_ACCESS(INTERNAL_AssertOnFailFast, W("AssertOnFailFast"), "") RETAIL_CONFIG_DWORD_INFO_EX(UNSUPPORTED_legacyCorruptedStateExceptionsPolicy, W("legacyCorruptedStateExceptionsPolicy"), 0, "Enabled Pre-V4 CSE behavior", CLRConfig::EEConfig_default) CONFIG_DWORD_INFO_EX(INTERNAL_SuppressLostExceptionTypeAssert, W("SuppressLostExceptionTypeAssert"), 0, "", CLRConfig::EEConfig_default) -RETAIL_CONFIG_DWORD_INFO_EX(UNSUPPORTED_FailFastOnCorruptedStateException, W("FailFastOnCorruptedStateException"), 0, "Failfast if a CSE is encountered", CLRConfig::EEConfig_default) RETAIL_CONFIG_DWORD_INFO_EX(INTERNAL_UseEntryPointFilter, W("UseEntryPointFilter"), 0, "", CLRConfig::EEConfig_default) RETAIL_CONFIG_DWORD_INFO_EX(INTERNAL_Corhost_Swallow_Uncaught_Exceptions, W("Corhost_Swallow_Uncaught_Exceptions"), 0, "", CLRConfig::EEConfig_default) diff --git a/src/coreclr/src/inc/corpriv.h b/src/coreclr/src/inc/corpriv.h index f0261b3381cc4b..6b92458ec40f18 100644 --- a/src/coreclr/src/inc/corpriv.h +++ b/src/coreclr/src/inc/corpriv.h @@ -25,9 +25,6 @@ interface IAssemblyName; -// PE images loaded through the runtime. -typedef struct _dummyCOR { BYTE b; } *HCORMODULE; - class UTSemReadWrite; // Helper function to get a pointer to the Dispenser interface. @@ -70,11 +67,6 @@ STDAPI GetAssemblyMDInternalImport( // Return code. REFIID riid, // [IN] The interface desired. IUnknown **ppIUnk); // [OUT] Return interface on success. -HRESULT GetAssemblyMDInternalImportFromImage( - HCORMODULE hImage, //[IN] pointer to module handle to get the metadata from. - REFIID riid, //[IN] The interface desired. - IUnknown **ppIUnk); //[OUT] Return Interface on success. - STDAPI GetAssemblyMDInternalImportByStream( // Return code. IStream *pIStream, // [IN] The IStream for the file UINT64 AssemblyId, // [IN] Unique Id for the assembly @@ -303,60 +295,6 @@ typedef enum CorOpenFlagsInternal #define COR_MODULE_CLASS "" #define COR_WMODULE_CLASS W("") -STDAPI RuntimeOpenImage(LPCWSTR pszFileName, HCORMODULE* hHandle); -STDAPI RuntimeOpenImageInternal(LPCWSTR pszFileName, HCORMODULE* hHandle, - DWORD *pdwLength, MDInternalImportFlags flags, HANDLE hFile = INVALID_HANDLE_VALUE); -STDAPI RuntimeOpenImageByStream(IStream* pIStream, UINT64 AssemblyId, DWORD dwModuleId, - HCORMODULE* hHandle, DWORD *pdwLength, MDInternalImportFlags flags); - -void RuntimeAddRefHandle(HCORMODULE hHandle); -STDAPI RuntimeReleaseHandle(HCORMODULE hHandle); -STDAPI RuntimeGetImageBase(HCORMODULE hHandle, LPVOID* base, BOOL bMapped, COUNT_T* dwSize); -STDAPI RuntimeGetImageKind(HCORMODULE hHandle, DWORD* pdwKind, DWORD* pdwMachine); -STDAPI RuntimeOSHandle(HCORMODULE hHandle, HMODULE* hModule); -STDAPI RuntimeGetAssemblyStrongNameHashForModule(HCORMODULE hModule, - IMetaDataImport *pMDimport, - BYTE *pbSNHash, - DWORD *pcbSNHash); -STDAPI RuntimeGetMDInternalImport(HCORMODULE hHandle, - MDInternalImportFlags flags, - IMDInternalImport** ppMDImport); - -FORCEINLINE -void ReleaseHCorModule(HCORMODULE hModule) -{ - HRESULT hr = RuntimeReleaseHandle(hModule); - _ASSERTE(SUCCEEDED(hr)); -} - -typedef Wrapper, ReleaseHCorModule, (UINT_PTR) NULL> HCORMODULEHolder; - - -// =========================================================================== -// ISNAssemblySignature (similar to IAssemblySignature in V1) -// -// This is a private interface that allows querying of the strong name -// signature. -// This can be used for (strong-named) assemblies added to the GAC as -// a unique identifier. -// - -// {848845BC-0C4A-42e3-8915-DC850112443D} -EXTERN_GUID(IID_ISNAssemblySignature, 0x848845BC, 0x0C4A, 0x42e3, 0x89, 0x15, 0xDC, 0x85, 0x01, 0x12, 0x44, 0x3D); - -#undef INTERFACE -#define INTERFACE ISNAssemblySignature -DECLARE_INTERFACE_(ISNAssemblySignature, IUnknown) -{ - // Returns the strong-name signature if the assembly is strong-name-signed - // Returns the MVID if the assembly is delay-signed. - // Fails if the assembly is not signed at all. - STDMETHOD(GetSNAssemblySignature) ( - BYTE *pbSig, // [IN, OUT] Buffer to write signature - DWORD *pcbSig // [IN, OUT] Size of buffer, bytes written - ) PURE; -}; - //------------------------------------- //--- ICeeGenInternal //------------------------------------- diff --git a/src/coreclr/src/inc/ex.h b/src/coreclr/src/inc/ex.h index 21ce9d3d4b0ec7..32f5b312d4792b 100644 --- a/src/coreclr/src/inc/ex.h +++ b/src/coreclr/src/inc/ex.h @@ -710,93 +710,17 @@ class CAutoTryCleanup EX_RETHROW; \ } \ -// Don't use this - use RethrowCorruptingExceptions (see below) instead. #define SwallowAllExceptions ; -////////////////////////////////////////////////////////////////////// -// -// Corrupted State Exception Support -// -///////////////////////////////////////////////////////////////////// - -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - -#define CORRUPTING_EXCEPTIONS_ONLY(expr) expr -#define COMMA_CORRUPTING_EXCEPTIONS_ONLY(expr) ,expr - -// EX_END_CATCH has been modified to not swallow Corrupting Exceptions (CE) when one of the -// following arguments are passed to it: -// -// 1) RethrowTerminalExceptions - rethrows both terminal and corrupting exceptions -// 2) RethrowCorruptingExceptions - swallows all exceptions exception corrupting exceptions. This SHOULD BE USED instead of SwallowAllExceptions. -// 3) RethrowTerminalExceptionsEx - same as (1) but rethrow of CE can be controlled via a condition. -// 4) RethrowCorruptingExceptionsEx - same as (2) but rethrow of CE can be controlled via a condition. -// -// By default, if a CE is encountered when one of the above policies are applied, the runtime will -// ensure that the CE propagates up the stack and not get swallowed unless the developer chooses to override the behaviour. -// This can be done by using the "Ex" versions above that take a conditional which evaluates to a BOOL. In such a case, -// the CE will *only* be rethrown if the conditional evalutes to TRUE. For examples, refer to COMToCLRWorker or -// DispatchInfo::InvokeMember implementations. -// -// SET_CE_RETHROW_FLAG_FOR_EX_CATCH macros helps evaluate if the CE is to be rethrown or not. This has been redefined in -// Clrex.h to add the condition of evaluating the throwable as well (which is not available outside the VM folder). -// -// Passing FALSE as the second argument to IsProcessCorruptedStateException implies that SET_CE_RETHROW_FLAG_FOR_EX_CATCH -// will ensure that we dont rethrow SO and allow EX_ENDTRY to SO specific processing. If none is done, then EX_ENDTRY will -// rethrow SO. By that time stack has been reclaimed and thus, throwing SO will be safe. -// -// We also check the global override flag incase it has been set to force pre-V4 beahviour. "0" implies it has not -// been overriden. -#define SET_CE_RETHROW_FLAG_FOR_EX_CATCH(expr) ((((expr) == TRUE) && \ - (CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_legacyCorruptedStateExceptionsPolicy) == 0) && \ - IsProcessCorruptedStateException(GetCurrentExceptionCode(), FALSE))) - -// This rethrow policy can be used in EX_END_CATCH to swallow all exceptions except the corrupting ones. -// This macro can be used to rethrow the CE based upon a BOOL condition. -#define RethrowCorruptingExceptionsEx(expr) \ - if (SET_CE_RETHROW_FLAG_FOR_EX_CATCH(expr)) \ - { \ - STATIC_CONTRACT_THROWS_TERMINAL; \ - EX_RETHROW; \ - } - -#define RethrowCorruptingExceptionsExAndHookRethrow(shouldRethrowExpr, aboutToRethrowExpr) \ - if (SET_CE_RETHROW_FLAG_FOR_EX_CATCH(shouldRethrowExpr)) \ - { \ - STATIC_CONTRACT_THROWS_TERMINAL; \ - aboutToRethrowExpr; \ - EX_RETHROW; \ - } - -#else // !FEATURE_CORRUPTING_EXCEPTIONS - -#define CORRUPTING_EXCEPTIONS_ONLY(expr) -#define COMMA_CORRUPTING_EXCEPTIONS_ONLY(expr) - -// When we dont have support for CE, just map it to SwallowAllExceptions -#define RethrowCorruptingExceptionsEx(expr) SwallowAllExceptions -#define RethrowCorruptingExceptionsExAndHookRethrow(shouldRethrowExpr, aboutToRethrowExpr) SwallowAllExceptions -#define SET_CE_RETHROW_FLAG_FOR_EX_CATCH(expr) !TRUE -#endif // FEATURE_CORRUPTING_EXCEPTIONS - -// Map to RethrowCorruptingExceptionsEx so that it does the "right" thing -#define RethrowCorruptingExceptions RethrowCorruptingExceptionsEx(TRUE) - -// This macro can be used to rethrow the CE based upon a BOOL condition. It will continue to rethrow terminal -// exceptions unconditionally. -#define RethrowTerminalExceptionsEx(expr) \ - if (GET_EXCEPTION()->IsTerminal() || \ - SET_CE_RETHROW_FLAG_FOR_EX_CATCH(expr)) \ +// When applied to EX_END_CATCH, this policy will always rethrow Terminal exceptions if they are +// encountered. +#define RethrowTerminalExceptions \ + if (GET_EXCEPTION()->IsTerminal()) \ { \ STATIC_CONTRACT_THROWS_TERMINAL; \ EX_RETHROW; \ } \ - -// When applied to EX_END_CATCH, this policy will always rethrow Terminal and Corrupting exceptions if they are -// encountered. -#define RethrowTerminalExceptions RethrowTerminalExceptionsEx(TRUE) - // Special define to be used in EEStartup that will also check for VM initialization before // commencing on a path that may use the managed thread object. #define RethrowTerminalExceptionsWithInitCheck \ diff --git a/src/coreclr/src/inc/utilcode.h b/src/coreclr/src/inc/utilcode.h index 1721db03dc01f4..14b261b08ad07d 100644 --- a/src/coreclr/src/inc/utilcode.h +++ b/src/coreclr/src/inc/utilcode.h @@ -4715,13 +4715,6 @@ BOOL IsIPInModule(HMODULE_TGT hModule, PCODE ip); extern HINSTANCE g_hmodCoreCLR; -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - -// Corrupting Exception limited support for outside the VM folder -BOOL IsProcessCorruptedStateException(DWORD dwExceptionCode, BOOL fCheckForSO = TRUE); - -#endif // FEATURE_CORRUPTING_EXCEPTIONS - namespace UtilCode { // These are type-safe versions of Interlocked[Compare]Exchange diff --git a/src/coreclr/src/md/runtime/mdinternaldisp.h b/src/coreclr/src/md/runtime/mdinternaldisp.h index 510e87351f3544..530a1419895654 100644 --- a/src/coreclr/src/md/runtime/mdinternaldisp.h +++ b/src/coreclr/src/md/runtime/mdinternaldisp.h @@ -16,7 +16,6 @@ #include "mdinternalro.h" - enum MDFileFormat { MDFormat_ReadOnly = 0, @@ -25,8 +24,6 @@ enum MDFileFormat MDFormat_Invalid = 3 }; - -HRESULT CheckFileFormat(LPVOID pData, ULONG cbData, MDFileFormat *pFormat); STDAPI GetMDInternalInterface( LPVOID pData, // [IN] Buffer with the metadata. ULONG cbData, // [IN] Size of the data in the buffer. @@ -34,11 +31,6 @@ STDAPI GetMDInternalInterface( REFIID riid, // [in] The interface desired. void **ppIUnk); // [out] Return interface on success. -HRESULT GetAssemblyMDInternalImportHelper(HCORMODULE hModule, - REFIID riid, - MDInternalImportFlags flags, - IUnknown **ppIUnk); - #endif //FEATURE_METADATA_INTERNAL_APIS #endif // __MDInternalDispenser__h__ diff --git a/src/coreclr/src/utilcode/util.cpp b/src/coreclr/src/utilcode/util.cpp index f1f004d3897d54..8c980df45dea16 100644 --- a/src/coreclr/src/utilcode/util.cpp +++ b/src/coreclr/src/utilcode/util.cpp @@ -3031,58 +3031,6 @@ lDone: ; return param.fRet; } -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - -// To include definition of EXCEPTION_SOFTSO -#include "corexcep.h" - -// These functions provide limited support for corrupting exceptions -// outside the VM folder. Its limited since we don't have access to the -// throwable. -// -// These functions are also wrapped by the corresponding CEHelper -// methods in excep.cpp. - -// Given an exception code, this method returns a BOOL to indicate if the -// code belongs to a corrupting exception or not. -BOOL IsProcessCorruptedStateException(DWORD dwExceptionCode, BOOL fCheckForSO /*=TRUE*/) -{ - LIMITED_METHOD_CONTRACT; - - // By default, assume its not corrupting - BOOL fIsCorruptedStateException = FALSE; - - if (CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_legacyCorruptedStateExceptionsPolicy) == 1) - { - return fIsCorruptedStateException; - } - - // If we have been asked not to include SO in the CSE check - // and the code represent SO, then exit now. - if ((fCheckForSO == FALSE) && (dwExceptionCode == STATUS_STACK_OVERFLOW)) - { - return fIsCorruptedStateException; - } - - switch(dwExceptionCode) - { - case STATUS_ACCESS_VIOLATION: - case STATUS_STACK_OVERFLOW: - case EXCEPTION_ILLEGAL_INSTRUCTION: - case EXCEPTION_IN_PAGE_ERROR: - case EXCEPTION_INVALID_DISPOSITION: - case EXCEPTION_NONCONTINUABLE_EXCEPTION: - case EXCEPTION_PRIV_INSTRUCTION: - case STATUS_UNWIND_CONSOLIDATE: - fIsCorruptedStateException = TRUE; - break; - } - - return fIsCorruptedStateException; -} - -#endif // FEATURE_CORRUPTING_EXCEPTIONS - namespace Clr { namespace Util diff --git a/src/coreclr/src/vm/.vscode/c_cpp_properties.json b/src/coreclr/src/vm/.vscode/c_cpp_properties.json index a4c0ec931c99ac..2a68e99359295e 100644 --- a/src/coreclr/src/vm/.vscode/c_cpp_properties.json +++ b/src/coreclr/src/vm/.vscode/c_cpp_properties.json @@ -53,7 +53,6 @@ "FEATURE_COMINTEROP_WINRT_MANAGED_ACTIVATION", "FEATURE_CORECLR", "FEATURE_CORESYSTEM", - "FEATURE_CORRUPTING_EXCEPTIONS", "FEATURE_DATABREAKPOINT", "FEATURE_DEFAULT_INTERFACES", "FEATURE_EVENT_TRACE=1", diff --git a/src/coreclr/src/vm/castcache.cpp b/src/coreclr/src/vm/castcache.cpp index 9fb5f7a61c7e76..829d8b331e0127 100644 --- a/src/coreclr/src/vm/castcache.cpp +++ b/src/coreclr/src/vm/castcache.cpp @@ -40,7 +40,7 @@ BASEARRAYREF CastCache::CreateCastCache(DWORD size) EX_CATCH { } - EX_END_CATCH(RethrowCorruptingExceptions) + EX_END_CATCH(RethrowTerminalExceptions) if (!table) { @@ -54,7 +54,7 @@ BASEARRAYREF CastCache::CreateCastCache(DWORD size) EX_CATCH { } - EX_END_CATCH(RethrowCorruptingExceptions) + EX_END_CATCH(RethrowTerminalExceptions) if (!table) { diff --git a/src/coreclr/src/vm/clrex.h b/src/coreclr/src/vm/clrex.h index 16b32574f5a39f..3a570a5480f26c 100644 --- a/src/coreclr/src/vm/clrex.h +++ b/src/coreclr/src/vm/clrex.h @@ -735,7 +735,7 @@ class EEFileLoadException : public EEException // { // EX_RETHROW() // } -// EX_END_CATCH(RethrowTerminalExceptions or RethrowCorruptingExceptions) +// EX_END_CATCH(RethrowTerminalExceptions) // -------------------------------------------------------------------------------------------------------- // In DAC builds, we don't want to override the normal utilcode exception handling. @@ -746,62 +746,6 @@ class EEFileLoadException : public EEException #define GET_THROWABLE() CLRException::GetThrowableFromException(GET_EXCEPTION()) -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - -// For the VM folder, we redefine SET_CE_RETHROW_FLAG_FOR_EX_CATCH to also check the -// corruption severity when deciding whether to rethrow them or not. -// -// We also check the global override flag incase it has been set to force pre-V4 behaviour. -// -// Doing the checks for "__fCaughtSO" and "__fCaughtNonCxx" will ensure that we check for -// corruption severity only if the last exception was a managed exception that could have been rethrown in the VM. -// When "(__fCaughtSO == FALSE) && (__fCaughtNonCxx == true)" is true, it implies we are dealing with a managed exception -// inside the VM that is represented by the CLRLastThrownObjectException instance (see EX_TRY/EX_CATCH implementation in VM -// folder to see how CLRLastThrownObjectException is used). -// -// This macro also supports the following scenarios: -// -// Scenario 1 -// ---------- -// -// [VM1] -> [VM2] -> -// -// If a managed exception is swallowed by an EX_CATCH in native function VM2, which then returns back -// to native function VM1 that throws, for example, a VM C++ exception, an EX_CATCH(RethrowCorruptingExceptions) -// in VM1 that catches the C++ exception will not rethrow since the last exception was not a managed CSE but -// a C++ exception. -// -// A variation of this is for VM2 to return back in VM1, which calls VM3 that throws a VM C++ exception that -// reaches VM1's EX_CATCH(RethrowCorruptingExceptions). VM1 shouldn't be rethrowing the exception in such a case. -// -// Scenario 2 -// ---------- -// -// [VM1 - RethrowCSE] -> [VM2 - RethrowCSE] -> [VM3 - RethrowCSE] -> -// -// When managed code throws a CSE (e.g. TargetInvocationException flagged as CSE), [VM3] will rethrow it and we will -// enter EX_CATCH in VM2 which is supposed to rethrow it as well. But if the implementation of EX_CATCH in VM2 throws -// another VM C++ exception (e.g. EEFileLoadException) *before* rethrow policy is applied, control will reach EX_CATCH -// in VM1 that *shouldn't* rethrow (even though it has RethrowCSE as the policy) since the last exception was a VM C++ -// exception. -// -// Scenario 3 -// ---------- -// -// This is about VM throwing a managed exception that gets handled either within the VM, with or without CLR's managed code -// exception handler coming into the picture. -// -// This is explained in detail (alongwith relevant changes) in the implementation of RaiseTheException (in excep.cpp). - -#undef SET_CE_RETHROW_FLAG_FOR_EX_CATCH -#define SET_CE_RETHROW_FLAG_FOR_EX_CATCH(expr) (((expr) == TRUE) && \ - (g_pConfig->LegacyCorruptedStateExceptionsPolicy() == false) && \ - (CEHelper::IsProcessCorruptedStateException(GetCurrentExceptionCode(), FALSE) || \ - (!__state.DidCatchCxx() && \ - CEHelper::IsLastActiveExceptionCorrupting(TRUE)))) - -#endif // FEATURE_CORRUPTING_EXCEPTIONS - #undef EX_TRY #define EX_TRY \ EX_TRY_CUSTOM(CLRException::HandlerState, (::GetThreadNULLOk()), CLRLastThrownObjectException) @@ -1002,25 +946,6 @@ LONG CLRNoCatchHandler(EXCEPTION_POINTERS* pExceptionInfo, PVOID pv); } \ } \ -// This macro should be used at the entry points (e.g. COM interop boundaries) -// where CE's are not expected to get swallowed. -#define END_EXTERNAL_ENTRYPOINT_RETHROW_CORRUPTING_EXCEPTIONS_EX(fCond) \ - } \ - EX_CATCH \ - { \ - *__phr = GET_EXCEPTION()->GetHR(); \ - } \ - EX_END_CATCH(RethrowCorruptingExceptionsEx(fCond)); \ - } \ - } \ - -// This macro should be used at the entry points (e.g. COM interop boundaries) -// where CE's are not expected to get swallowed. -#define END_EXTERNAL_ENTRYPOINT_RETHROW_CORRUPTING_EXCEPTIONS \ - END_EXTERNAL_ENTRYPOINT_RETHROW_CORRUPTING_EXCEPTIONS_EX(TRUE) - - - //============================================================================== // --------------------------------------------------------------------------- diff --git a/src/coreclr/src/vm/comcallablewrapper.cpp b/src/coreclr/src/vm/comcallablewrapper.cpp index c621eeb74304dd..583d52d1cf38d4 100644 --- a/src/coreclr/src/vm/comcallablewrapper.cpp +++ b/src/coreclr/src/vm/comcallablewrapper.cpp @@ -3678,8 +3678,7 @@ IDispatch* ComCallWrapper::GetIDispatchIP() CorIfaceAttr ifaceType = hndDefItfClass.GetMethodTable()->GetComInterfaceType(); if (IsDispatchBasedItf(ifaceType)) { - RETURN (IDispatch*)GetComIPFromCCW(this, GUID_NULL, hndDefItfClass.GetMethodTable(), - GetComIPFromCCW::SuppressSecurityCheck); + RETURN (IDispatch*)GetComIPFromCCW(this, GUID_NULL, hndDefItfClass.GetMethodTable()); } else { diff --git a/src/coreclr/src/vm/comcallablewrapper.h b/src/coreclr/src/vm/comcallablewrapper.h index 51b6f88d87b868..9ef02ec63e3848 100644 --- a/src/coreclr/src/vm/comcallablewrapper.h +++ b/src/coreclr/src/vm/comcallablewrapper.h @@ -957,8 +957,7 @@ struct GetComIPFromCCW { None = 0, CheckVisibility = 1, - SuppressSecurityCheck = 2, - SuppressCustomizedQueryInterface = 4 + SuppressCustomizedQueryInterface = 2 }; }; diff --git a/src/coreclr/src/vm/comdelegate.cpp b/src/coreclr/src/vm/comdelegate.cpp index 20a724bf0a9085..e2b45fb108d1dd 100644 --- a/src/coreclr/src/vm/comdelegate.cpp +++ b/src/coreclr/src/vm/comdelegate.cpp @@ -3282,44 +3282,7 @@ static void InvokeUnhandledSwallowing(OBJECTREF *pDelegate, EX_TRY { -#if defined(FEATURE_CORRUPTING_EXCEPTIONS) - BOOL fCanMethodHandleException = g_pConfig->LegacyCorruptedStateExceptionsPolicy(); - if (!fCanMethodHandleException) - { - // CSE policy has not been overridden - proceed with our checks. - // - // Notifications for CSE are only delivered if the delegate target follows CSE rules. - // So, get the corruption severity of the active exception that has gone unhandled. - // - // By Default, assume that the active exception is not corrupting. - CorruptionSeverity severity = NotCorrupting; - Thread *pCurThread = GetThread(); - _ASSERTE(pCurThread != NULL); - ThreadExceptionState *pExState = pCurThread->GetExceptionState(); - if (pExState->IsExceptionInProgress()) - { - // If an exception is active, it implies we have a tracker for it. - // Hence, get the corruption severity from the active exception tracker. - severity = pExState->GetCurrentExceptionTracker()->GetCorruptionSeverity(); - _ASSERTE(severity > NotSet); - } - - // Notifications are delivered based upon corruption severity of the exception - fCanMethodHandleException = ExceptionNotifications::CanDelegateBeInvokedForException(pDelegate, severity); - if (!fCanMethodHandleException) - { - LOG((LF_EH, LL_INFO100, "InvokeUnhandledSwallowing: ADUEN Delegate cannot be invoked for corruption severity %d\n", - severity)); - } - } - - if (fCanMethodHandleException) -#endif // defined(FEATURE_CORRUPTING_EXCEPTIONS) - { - // We've already exercised the prestub on this delegate's COMDelegate::GetMethodDesc, - // as part of wiring up a reliable event sink. Deliver the notification. - ExceptionNotifications::DeliverExceptionNotification(UnhandledExceptionHandler, pDelegate, pDomain, pEventArgs); - } + ExceptionNotifications::DeliverExceptionNotification(UnhandledExceptionHandler, pDelegate, pDomain, pEventArgs); } EX_CATCH { diff --git a/src/coreclr/src/vm/commodule.cpp b/src/coreclr/src/vm/commodule.cpp index 3a546963066756..51160cf2b896ca 100644 --- a/src/coreclr/src/vm/commodule.cpp +++ b/src/coreclr/src/vm/commodule.cpp @@ -888,7 +888,7 @@ HINSTANCE QCALLTYPE COMModule::GetHINSTANCE(QCall::ModuleHandle pModule) BEGIN_QCALL; - // This returns the base address - this will work for either HMODULE or HCORMODULES + // This returns the base address // Other modules should have zero base PEFile *pPEFile = pModule->GetFile(); if (!pPEFile->IsDynamic() && !pPEFile->IsResource()) @@ -1093,4 +1093,3 @@ FCIMPL0(void*, COMPunkSafeHandle::nGetDReleaseTarget) } FCIMPLEND - diff --git a/src/coreclr/src/vm/dispatchinfo.cpp b/src/coreclr/src/vm/dispatchinfo.cpp index 8da1151b93c05c..dca9108f1d8532 100644 --- a/src/coreclr/src/vm/dispatchinfo.cpp +++ b/src/coreclr/src/vm/dispatchinfo.cpp @@ -2193,10 +2193,8 @@ HRESULT DispatchInfo::InvokeMember(SimpleComCallWrapper *pSimpleWrap, DISPID id, EX_CATCH { pThrowable = GET_THROWABLE(); - - // RethrowCorruptingExceptionsEx, in EX_END_CATCH below, will ensure that CEs are rethrown. } - EX_END_CATCH(RethrowCorruptingExceptionsEx(!CEHelper::CanIDispatchTargetHandleException())) + EX_END_CATCH(RethrowTerminalExceptions) catchFrame.Pop(); if (pThrowable != NULL) diff --git a/src/coreclr/src/vm/eeconfig.cpp b/src/coreclr/src/vm/eeconfig.cpp index bf0c602aa19c60..bb4266f86fb7f2 100644 --- a/src/coreclr/src/vm/eeconfig.cpp +++ b/src/coreclr/src/vm/eeconfig.cpp @@ -126,11 +126,6 @@ HRESULT EEConfig::Init() fJitMinOpts = false; fPInvokeRestoreEsp = (DWORD)-1; -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // By default, there is not pre-V4 CSE policy - fLegacyCorruptedStateExceptionsPolicy = false; -#endif // FEATURE_CORRUPTING_EXCEPTIONS - fNgenBindOptimizeNonGac = false; fStressLog = false; fProbeForStackOverflow = true; diff --git a/src/coreclr/src/vm/eeconfig.h b/src/coreclr/src/vm/eeconfig.h index c6579786aa821b..7ed91a49fc9d4e 100644 --- a/src/coreclr/src/vm/eeconfig.h +++ b/src/coreclr/src/vm/eeconfig.h @@ -133,11 +133,6 @@ class EEConfig } } -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // Returns a bool to indicate if the legacy CSE (pre-v4) behaviour is enabled or not - bool LegacyCorruptedStateExceptionsPolicy(void) const {LIMITED_METHOD_CONTRACT; return fLegacyCorruptedStateExceptionsPolicy; } -#endif // FEATURE_CORRUPTING_EXCEPTIONS - bool InteropValidatePinnedObjects() const { LIMITED_METHOD_CONTRACT; return m_fInteropValidatePinnedObjects; } bool InteropLogArguments() const { LIMITED_METHOD_CONTRACT; return m_fInteropLogArguments; } @@ -559,10 +554,6 @@ class EEConfig unsigned fPInvokeRestoreEsp; // -1=Default, 0=Never, Else=Always -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - bool fLegacyCorruptedStateExceptionsPolicy; -#endif // FEATURE_CORRUPTING_EXCEPTIONS - LPUTF8 pszBreakOnClassLoad; // Halt just before loading this class #ifdef TEST_DATA_CONSISTENCY diff --git a/src/coreclr/src/vm/eventtrace.cpp b/src/coreclr/src/vm/eventtrace.cpp index aee5caebdf7f54..d5099e498c2a67 100644 --- a/src/coreclr/src/vm/eventtrace.cpp +++ b/src/coreclr/src/vm/eventtrace.cpp @@ -974,7 +974,7 @@ HRESULT ETW::GCLog::ForceGCForDiagnostics() #ifndef FEATURE_REDHAWK } EX_CATCH { } - EX_END_CATCH(RethrowCorruptingExceptions); + EX_END_CATCH(RethrowTerminalExceptions); #endif // FEATURE_REDHAWK return hr; @@ -1752,7 +1752,7 @@ int BulkTypeEventLogger::LogSingleType(TypeHandle th) { fSucceeded = FALSE; } - EX_END_CATCH(RethrowCorruptingExceptions); + EX_END_CATCH(RethrowTerminalExceptions); if (!fSucceeded) return -1; @@ -1791,7 +1791,7 @@ int BulkTypeEventLogger::LogSingleType(TypeHandle th) { fSucceeded = FALSE; } - EX_END_CATCH(RethrowCorruptingExceptions); + EX_END_CATCH(RethrowTerminalExceptions); if (!fSucceeded) return -1; } @@ -1811,7 +1811,7 @@ int BulkTypeEventLogger::LogSingleType(TypeHandle th) { fSucceeded = FALSE; } - EX_END_CATCH(RethrowCorruptingExceptions); + EX_END_CATCH(RethrowTerminalExceptions); if (!fSucceeded) return -1; } @@ -1850,7 +1850,7 @@ int BulkTypeEventLogger::LogSingleType(TypeHandle th) { fSucceeded = FALSE; } - EX_END_CATCH(RethrowCorruptingExceptions); + EX_END_CATCH(RethrowTerminalExceptions); if (!fSucceeded) return -1; } @@ -1888,7 +1888,7 @@ int BulkTypeEventLogger::LogSingleType(TypeHandle th) // won't have a name in it. pVal->sName.Clear(); } - EX_END_CATCH(RethrowCorruptingExceptions); + EX_END_CATCH(RethrowTerminalExceptions); // Now that we know the full size of this type's data, see if it fits in our // batch or whether we need to flush @@ -1986,7 +1986,7 @@ void BulkTypeEventLogger::LogTypeAndParameters(ULONGLONG thAsAddr, ETW::TypeSyst { fSucceeded = FALSE; } - EX_END_CATCH(RethrowCorruptingExceptions); + EX_END_CATCH(RethrowTerminalExceptions); if (!fSucceeded) return; @@ -2551,7 +2551,7 @@ VOID ETW::GCLog::SendFinalizeObjectEvent(MethodTable * pMT, Object * pObj) EX_CATCH { } - EX_END_CATCH(RethrowCorruptingExceptions); + EX_END_CATCH(RethrowTerminalExceptions); } } @@ -2977,7 +2977,7 @@ BOOL ETW::TypeSystemLog::AddOrReplaceTypeLoggingInfo(ETW::LoggedTypesFromModule { fSucceeded = FALSE; } - EX_END_CATCH(RethrowCorruptingExceptions); + EX_END_CATCH(RethrowTerminalExceptions); return fSucceeded; } @@ -3384,7 +3384,7 @@ ETW::TypeLoggingInfo ETW::TypeSystemLog::LookupOrCreateTypeLoggingInfo(TypeHandl { fSucceeded = FALSE; } - EX_END_CATCH(RethrowCorruptingExceptions); + EX_END_CATCH(RethrowTerminalExceptions); if (!fSucceeded) { *pfCreatedNew = FALSE; @@ -3422,7 +3422,7 @@ ETW::TypeLoggingInfo ETW::TypeSystemLog::LookupOrCreateTypeLoggingInfo(TypeHandl { fSucceeded = FALSE; } - EX_END_CATCH(RethrowCorruptingExceptions); + EX_END_CATCH(RethrowTerminalExceptions); if (!fSucceeded) { *pfCreatedNew = FALSE; @@ -3518,7 +3518,7 @@ BOOL ETW::TypeSystemLog::AddTypeToGlobalCacheIfNotExists(TypeHandle th, BOOL * p { fSucceeded = FALSE; } - EX_END_CATCH(RethrowCorruptingExceptions); + EX_END_CATCH(RethrowTerminalExceptions); if (!fSucceeded) { *pfCreatedNew = FALSE; @@ -3550,7 +3550,7 @@ BOOL ETW::TypeSystemLog::AddTypeToGlobalCacheIfNotExists(TypeHandle th, BOOL * p { fSucceeded = FALSE; } - EX_END_CATCH(RethrowCorruptingExceptions); + EX_END_CATCH(RethrowTerminalExceptions); if (!fSucceeded) { *pfCreatedNew = FALSE; @@ -4641,7 +4641,6 @@ VOID ETW::ExceptionLog::ExceptionThrown(CrawlFrame *pCf, BOOL bIsReThrownExcept pExInfo = pExState->GetCurrentExceptionTracker(); _ASSERTE(pExInfo != NULL); bIsNestedException = (pExInfo->GetPreviousExceptionTracker() != NULL); - bIsCSE = (pExInfo->GetCorruptionSeverity() == ProcessCorrupting); bIsCLSCompliant = IsException((gc.exceptionObj)->GetMethodTable()) && ((gc.exceptionObj)->GetMethodTable() != MscorlibBinder::GetException(kRuntimeWrappedException)); @@ -4656,7 +4655,6 @@ VOID ETW::ExceptionLog::ExceptionThrown(CrawlFrame *pCf, BOOL bIsReThrownExcept exceptionFlags = ((bHasInnerException ? ETW::ExceptionLog::ExceptionStructs::HasInnerException : 0) | (bIsNestedException ? ETW::ExceptionLog::ExceptionStructs::IsNestedException : 0) | (bIsReThrownException ? ETW::ExceptionLog::ExceptionStructs::IsReThrownException : 0) | - (bIsCSE ? ETW::ExceptionLog::ExceptionStructs::IsCSE : 0) | (bIsCLSCompliant ? ETW::ExceptionLog::ExceptionStructs::IsCLSCompliant : 0)); if (pCf->IsFrameless()) @@ -6279,7 +6277,7 @@ VOID ETW::MethodLog::SendMethodDetailsEvent(MethodDesc *pMethodDesc) { fSucceeded = FALSE; } - EX_END_CATCH(RethrowCorruptingExceptions); + EX_END_CATCH(RethrowTerminalExceptions); if (!fSucceeded) goto done; diff --git a/src/coreclr/src/vm/excep.cpp b/src/coreclr/src/vm/excep.cpp index 2dd54dbb42ac03..657717d6b3adaa 100644 --- a/src/coreclr/src/vm/excep.cpp +++ b/src/coreclr/src/vm/excep.cpp @@ -121,11 +121,7 @@ typedef struct { PEXCEPTION_REGISTRATION_RECORD GetCurrentSEHRecord(); BOOL IsUnmanagedToManagedSEHHandler(EXCEPTION_REGISTRATION_RECORD*); -VOID DECLSPEC_NORETURN RealCOMPlusThrow(OBJECTREF throwable, BOOL rethrow -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , CorruptionSeverity severity = NotCorrupting -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ); +VOID DECLSPEC_NORETURN RealCOMPlusThrow(OBJECTREF throwable, BOOL rethrow); //------------------------------------------------------------------------------- // Basically, this asks whether the exception is a managed exception thrown by @@ -2711,85 +2707,6 @@ LONG RaiseExceptionFilter(EXCEPTION_POINTERS* ep, LPVOID pv) return EXCEPTION_CONTINUE_SEARCH; } -//========================================================================== -// Throw an object. -//========================================================================== -VOID DECLSPEC_NORETURN RaiseTheException(OBJECTREF throwable, BOOL rethrow -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , CorruptionSeverity severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ) -{ - STATIC_CONTRACT_THROWS; - STATIC_CONTRACT_GC_TRIGGERS; - STATIC_CONTRACT_MODE_COOPERATIVE; - - LOG((LF_EH, LL_INFO100, "RealCOMPlusThrow throwing %s\n", - throwable->GetMethodTable()->GetDebugClassName())); - - if (throwable == NULL) - { - _ASSERTE(!"RealCOMPlusThrow(OBJECTREF) called with NULL argument. Somebody forgot to post an exception!"); - EEPOLICY_HANDLE_FATAL_ERROR(COR_E_EXECUTIONENGINE); - } - - _ASSERTE(throwable != CLRException::GetPreallocatedStackOverflowException()); - -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - if (!g_pConfig->LegacyCorruptedStateExceptionsPolicy()) - { - // This is Scenario 3 described in clrex.h around the definition of SET_CE_RETHROW_FLAG_FOR_EX_CATCH macro. - // - // We are here because the VM is attempting to throw a managed exception. It is posssible this exception - // may not be seen by CLR's exception handler for managed code (e.g. there maybe an EX_CATCH up the stack - // that will swallow or rethrow this exception). In the following scenario: - // - // [VM1 - RethrowCSE] -> [VM2 - RethrowCSE] -> [VM3 - RethrowCSE] -> - // - // When managed code throws a CSE (e.g. TargetInvocationException flagged as CSE), [VM3] will rethrow it and we will - // enter EX_CATCH in VM2 which is supposed to rethrow it as well. Two things can happen: - // - // 1) The implementation of EX_CATCH in VM2 throws a new managed exception *before* rethrow policy is applied and control - // will reach EX_CATCH in VM1, OR - // - // 2) EX_CATCH in VM2 swallows the exception, comes out of the catch block and later throws a new managed exception that - // will be caught by EX_CATCH in VM1. - // - // In either of the cases, rethrow in VM1 should be on the basis of the new managed exception's corruption severity. - // - // To support this scenario, we set corruption severity of the managed exception VM is throwing. If its a rethrow, - // it implies we are rethrowing the last exception that was seen by CLR's managed code exception handler. In such a case, - // we will copy over the corruption severity of that exception. - - // If throwable indicates corrupted state, forcibly set the severity. - if (CEHelper::IsProcessCorruptedStateException(throwable)) - { - severity = ProcessCorrupting; - } - - // No one should have passed us an invalid severity. - _ASSERTE(severity > NotSet); - - if (severity == NotSet) - { - severity = NotCorrupting; - } - - // Update the corruption severity of the exception being thrown by the VM. - GetThread()->GetExceptionState()->SetLastActiveExceptionCorruptionSeverity(severity); - - // Exception's corruption severity should be reused in reraise if this exception leaks out from the VM - // into managed code - CEHelper::MarkLastActiveExceptionCorruptionSeverityForReraiseReuse(); - - LOG((LF_EH, LL_INFO100, "RaiseTheException - Set VM thrown managed exception severity to %d.\n", severity)); - } - -#endif // FEATURE_CORRUPTING_EXCEPTIONS - - RaiseTheExceptionInternalOnly(throwable,rethrow); -} - HRESULT GetHRFromThrowable(OBJECTREF throwable) { STATIC_CONTRACT_THROWS; @@ -2965,11 +2882,8 @@ VOID DECLSPEC_NORETURN RaiseTheExceptionInternalOnly(OBJECTREF throwable, BOOL r // INSTALL_COMPLUS_EXCEPTION_HANDLER has a filter, so must put the call in a separate fcn -static VOID DECLSPEC_NORETURN RealCOMPlusThrowWorker(OBJECTREF throwable, BOOL rethrow -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , CorruptionSeverity severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS -) { +static VOID DECLSPEC_NORETURN RealCOMPlusThrowWorker(OBJECTREF throwable, BOOL rethrow) +{ STATIC_CONTRACT_THROWS; STATIC_CONTRACT_GC_TRIGGERS; STATIC_CONTRACT_MODE_ANY; @@ -2982,23 +2896,24 @@ static VOID DECLSPEC_NORETURN RealCOMPlusThrowWorker(OBJECTREF throwable, BOOL r // TODO: Do we need to install COMPlusFrameHandler here? INSTALL_COMPLUS_EXCEPTION_HANDLER(); - RaiseTheException(throwable, rethrow -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ); + if (throwable == NULL) + { + _ASSERTE(!"RealCOMPlusThrow(OBJECTREF) called with NULL argument. Somebody forgot to post an exception!"); + EEPOLICY_HANDLE_FATAL_ERROR(COR_E_EXECUTIONENGINE); + } + RaiseTheExceptionInternalOnly(throwable, rethrow); UNINSTALL_COMPLUS_EXCEPTION_HANDLER(); } - -VOID DECLSPEC_NORETURN RealCOMPlusThrow(OBJECTREF throwable, BOOL rethrow -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , CorruptionSeverity severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS -) { +VOID DECLSPEC_NORETURN RealCOMPlusThrow(OBJECTREF throwable, BOOL rethrow) +{ STATIC_CONTRACT_THROWS; STATIC_CONTRACT_GC_TRIGGERS; STATIC_CONTRACT_MODE_ANY; + + LOG((LF_EH, LL_INFO100, "RealCOMPlusThrow throwing %s\n", + throwable->GetMethodTable()->GetDebugClassName())); + GCPROTECT_BEGIN(throwable); _ASSERTE(IsException(throwable->GetMethodTable())); @@ -3019,20 +2934,12 @@ VOID DECLSPEC_NORETURN RealCOMPlusThrow(OBJECTREF throwable, BOOL rethrow ExceptionPreserveStackTrace(throwable); } - RealCOMPlusThrowWorker(throwable, rethrow -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ); + RealCOMPlusThrowWorker(throwable, rethrow); GCPROTECT_END(); } -VOID DECLSPEC_NORETURN RealCOMPlusThrow(OBJECTREF throwable -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , CorruptionSeverity severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ) +VOID DECLSPEC_NORETURN RealCOMPlusThrow(OBJECTREF throwable) { CONTRACTL { @@ -3042,11 +2949,7 @@ VOID DECLSPEC_NORETURN RealCOMPlusThrow(OBJECTREF throwable } CONTRACTL_END; - RealCOMPlusThrow(throwable, FALSE -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ); + RealCOMPlusThrow(throwable, FALSE); } // this function finds the managed callback to get a resource @@ -3709,14 +3612,6 @@ BOOL IsUncatchable(OBJECTREF *pThrowable) if (OBJECTREFToObject(*pThrowable)->GetMethodTable() == g_pExecutionEngineExceptionClass) return TRUE; - -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // Corrupting exceptions are also uncatchable - if (CEHelper::IsProcessCorruptedStateException(*pThrowable)) - { - return TRUE; - } -#endif //FEATURE_CORRUPTING_EXCEPTIONS } return FALSE; @@ -8552,35 +8447,6 @@ LONG ReflectionInvocationExceptionFilter( } #endif // !TARGET_UNIX - // If the application has opted into triggering a failfast when a CorruptedStateException enters the Reflection system, - // then do the needful. - if (CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_FailFastOnCorruptedStateException) == 1) - { - // Get the thread and the managed exception object - they must exist at this point - Thread *pCurThread = GetThread(); - _ASSERTE(pCurThread != NULL); - - // Get the thread exception state - ThreadExceptionState * pCurTES = pCurThread->GetExceptionState(); - _ASSERTE(pCurTES != NULL); - - // Get the exception tracker for the current exception -#ifdef FEATURE_EH_FUNCLETS - PTR_ExceptionTracker pEHTracker = pCurTES->GetCurrentExceptionTracker(); -#elif TARGET_X86 - PTR_ExInfo pEHTracker = pCurTES->GetCurrentExceptionTracker(); -#else // !(HOST_64BIT || TARGET_X86) -#error Unsupported platform -#endif // HOST_64BIT - -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - if (pEHTracker->GetCorruptionSeverity() == ProcessCorrupting) - { - EEPolicy::HandleFatalError(COR_E_FAILFAST, reinterpret_cast(pExceptionInfo->ExceptionRecord->ExceptionAddress), NULL, pExceptionInfo); - } -#endif // FEATURE_CORRUPTING_EXCEPTIONS - } - return ret; } // LONG ReflectionInvocationExceptionFilter() @@ -11095,781 +10961,43 @@ PTR_ExInfo GetEHTrackerForException(OBJECTREF oThrowable, PTR_ExInfo pStartingEH return fFoundTracker ? pEHTracker : NULL; } -#ifdef FEATURE_CORRUPTING_EXCEPTIONS -// ----------------------------------------------------------------------- -// Support for CorruptedState Exceptions -// ----------------------------------------------------------------------- - // Given an exception code, this method returns a BOOL to indicate if the // code belongs to a corrupting exception or not. /* static */ -BOOL CEHelper::IsProcessCorruptedStateException(DWORD dwExceptionCode, BOOL fCheckForSO /*= TRUE*/) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - } - CONTRACTL_END; - - if (g_pConfig->LegacyCorruptedStateExceptionsPolicy()) - { - return FALSE; - } - - // Call into the utilcode helper function to check if this - // is a CE or not. - return (::IsProcessCorruptedStateException(dwExceptionCode, fCheckForSO)); -} - -// This is used in the VM folder version of "SET_CE_RETHROW_FLAG_FOR_EX_CATCH" (in clrex.h) -// to check if the managed exception caught by EX_END_CATCH is CSE or not. -// -// If you are using it from rethrow boundaries (e.g. SET_CE_RETHROW_FLAG_FOR_EX_CATCH -// macro that is used to automatically rethrow corrupting exceptions), then you may -// want to set the "fMarkForReuseIfCorrupting" to TRUE to enable propagation of the -// corruption severity when the reraised exception is seen by managed code again. -/* static */ -BOOL CEHelper::IsLastActiveExceptionCorrupting(BOOL fMarkForReuseIfCorrupting /* = FALSE */) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - PRECONDITION(GetThread() != NULL); - } - CONTRACTL_END; - - if (g_pConfig->LegacyCorruptedStateExceptionsPolicy()) - { - return FALSE; - } - - BOOL fIsCorrupting = FALSE; - ThreadExceptionState *pCurTES = GetThread()->GetExceptionState(); - - // Check the corruption severity - CorruptionSeverity severity = pCurTES->GetLastActiveExceptionCorruptionSeverity(); - fIsCorrupting = (severity == ProcessCorrupting); - if (fIsCorrupting && fMarkForReuseIfCorrupting) - { - // Mark the corruption severity for reuse - CEHelper::MarkLastActiveExceptionCorruptionSeverityForReraiseReuse(); - } - - LOG((LF_EH, LL_INFO100, "CEHelper::IsLastActiveExceptionCorrupting - Using corruption severity from TES.\n")); - - return fIsCorrupting; -} - -// Given a MethodDesc, this method will return a BOOL to indicate if -// the containing assembly was built for PreV4 runtime or not. -/* static */ -BOOL CEHelper::IsMethodInPreV4Assembly(PTR_MethodDesc pMethodDesc) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - PRECONDITION(pMethodDesc != NULL); - } - CONTRACTL_END; - - // By default, assume that the containing assembly was not - // built for PreV4 runtimes. - BOOL fBuiltForPreV4Runtime = FALSE; - - if (g_pConfig->LegacyCorruptedStateExceptionsPolicy()) - { - return TRUE; - } - - LPCSTR pszVersion = NULL; - - // Retrieve the manifest metadata reference since that contains - // the "built-for" runtime details - IMDInternalImport *pImport = pMethodDesc->GetAssembly()->GetManifestImport(); - if (pImport && SUCCEEDED(pImport->GetVersionString(&pszVersion))) - { - if (pszVersion != NULL) - { - // If version begins with "v1.*" or "v2.*", it was built for preV4 runtime - if ((pszVersion[0] == 'v' || pszVersion[0] == 'V') && - IS_DIGIT(pszVersion[1]) && - (pszVersion[2] == '.') ) - { - // Looks like a version. Is it lesser than v4.0 major version where we start using new behavior? - fBuiltForPreV4Runtime = ((DIGIT_TO_INT(pszVersion[1]) != 0) && - (DIGIT_TO_INT(pszVersion[1]) <= HIGHEST_MAJOR_VERSION_OF_PREV4_RUNTIME)); - } - } - } - - return fBuiltForPreV4Runtime; -} - -// Given a MethodDesc and CorruptionSeverity, this method will return a -// BOOL indicating if the method can handle those kinds of CEs or not. -/* static */ -BOOL CEHelper::CanMethodHandleCE(PTR_MethodDesc pMethodDesc, CorruptionSeverity severity) -{ - BOOL fCanMethodHandleSeverity = FALSE; - -#ifndef DACCESS_COMPILE - CONTRACTL - { - GC_NOTRIGGER; - THROWS; - MODE_ANY; - PRECONDITION(pMethodDesc != NULL); - } - CONTRACTL_END; - - - if (g_pConfig->LegacyCorruptedStateExceptionsPolicy()) - { - return TRUE; - } - - // Since the method is Security Critical, now check if it is - // attributed to handle the CE or not. - IMDInternalImport *pImport = pMethodDesc->GetMDImport(); - if (pImport != NULL) - { - mdMethodDef methodDef = pMethodDesc->GetMemberDef(); - switch(severity) - { - case ProcessCorrupting: - fCanMethodHandleSeverity = (S_OK == pImport->GetCustomAttributeByName( - methodDef, - HANDLE_PROCESS_CORRUPTED_STATE_EXCEPTION_ATTRIBUTE, - NULL, - NULL)); - break; - default: - _ASSERTE(!"Unknown Exception Corruption Severity!"); - break; - } - } -#endif // !DACCESS_COMPILE - - return fCanMethodHandleSeverity; -} - -// Given a MethodDesc, this method will return a BOOL to indicate if the method should be examined for exception -// handlers for the specified exception. -// -// This method accounts for both corrupting and non-corrupting exceptions. -/* static */ -BOOL CEHelper::CanMethodHandleException(CorruptionSeverity severity, PTR_MethodDesc pMethodDesc) -{ - CONTRACTL - { - GC_NOTRIGGER; - THROWS; - MODE_ANY; - PRECONDITION(pMethodDesc != NULL); - } - CONTRACTL_END; - - // By default, assume that the runtime shouldn't look for exception handlers - // in the method pointed by the MethodDesc - BOOL fLookForExceptionHandlersInMethod = FALSE; - - if (g_pConfig->LegacyCorruptedStateExceptionsPolicy()) - { - return TRUE; - } - - // If we have been asked to use the last active corruption severity (e.g. in cases of Reflection - // or COM interop), then retrieve it. - if (severity == UseLast) - { - LOG((LF_EH, LL_INFO100, "CEHelper::CanMethodHandleException - Using LastActiveExceptionCorruptionSeverity.\n")); - severity = GetThread()->GetExceptionState()->GetLastActiveExceptionCorruptionSeverity(); - } - - LOG((LF_EH, LL_INFO100, "CEHelper::CanMethodHandleException - Processing CorruptionSeverity: %d.\n", severity)); - - if (severity > NotCorrupting) - { - // If the method lies in an assembly built for pre-V4 runtime, allow the runtime - // to look for exception handler for the CE. - BOOL fIsMethodInPreV4Assembly = FALSE; - fIsMethodInPreV4Assembly = CEHelper::IsMethodInPreV4Assembly(pMethodDesc); - - if (!fIsMethodInPreV4Assembly) - { - // Method lies in an assembly built for V4 or later runtime. - LOG((LF_EH, LL_INFO100, "CEHelper::CanMethodHandleException - Method is in an assembly built for V4 or later runtime.\n")); - - // Depending upon the corruption severity of the exception, see if the - // method supports handling that. - LOG((LF_EH, LL_INFO100, "CEHelper::CanMethodHandleException - Exception is corrupting.\n")); - - // Check if the method can handle the severity specified in the exception object. - fLookForExceptionHandlersInMethod = CEHelper::CanMethodHandleCE(pMethodDesc, severity); - } - else - { - // Method is in a Pre-V4 assembly - allow it to be examined for processing the CE - fLookForExceptionHandlersInMethod = TRUE; - } - } - else - { - // Non-corrupting exceptions can continue to be delivered - fLookForExceptionHandlersInMethod = TRUE; - } - - return fLookForExceptionHandlersInMethod; -} - -// Given a managed exception object, this method will return a BOOL -// indicating if it corresponds to a ProcessCorruptedState exception -// or not. -/* static */ -BOOL CEHelper::IsProcessCorruptedStateException(OBJECTREF oThrowable) +BOOL IsProcessCorruptedStateException(DWORD dwExceptionCode, OBJECTREF throwable) { CONTRACTL { NOTHROW; GC_NOTRIGGER; MODE_COOPERATIVE; - PRECONDITION(oThrowable != NULL); } CONTRACTL_END; - if (g_pConfig->LegacyCorruptedStateExceptionsPolicy()) + switch (dwExceptionCode) { + case STATUS_ACCESS_VIOLATION: + if (throwable != NULL && MscorlibBinder::IsException(throwable->GetMethodTable(), kNullReferenceException)) + return FALSE; + break; + case STATUS_STACK_OVERFLOW: + case EXCEPTION_ILLEGAL_INSTRUCTION: + case EXCEPTION_IN_PAGE_ERROR: + case EXCEPTION_INVALID_DISPOSITION: + case EXCEPTION_NONCONTINUABLE_EXCEPTION: + case EXCEPTION_PRIV_INSTRUCTION: + case STATUS_UNWIND_CONSOLIDATE: + break; + default: return FALSE; } -#ifndef DACCESS_COMPILE - // If the throwable represents preallocated SO, then indicate it as a CSE - if (CLRException::GetPreallocatedStackOverflowException() == oThrowable) - { - return TRUE; - } -#endif // !DACCESS_COMPILE - - // Check if we have an exception tracker for this exception - // and if so, if it represents corrupting exception or not. - // Get the exception tracker for the current exception -#ifdef FEATURE_EH_FUNCLETS - PTR_ExceptionTracker pEHTracker = GetEHTrackerForException(oThrowable, NULL); -#elif TARGET_X86 - PTR_ExInfo pEHTracker = GetEHTrackerForException(oThrowable, NULL); -#else -#error Unsupported platform -#endif - - if (pEHTracker != NULL) - { - // Found the tracker for exception object - check if its CSE or not. - return (pEHTracker->GetCorruptionSeverity() == ProcessCorrupting); - } - - return FALSE; -} - -#ifdef FEATURE_EH_FUNCLETS -void CEHelper::SetupCorruptionSeverityForActiveExceptionInUnwindPass(Thread *pCurThread, PTR_ExceptionTracker pEHTracker, BOOL fIsFirstPass, - DWORD dwExceptionCode) -{ -#ifndef DACCESS_COMPILE - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - PRECONDITION(!fIsFirstPass); // This method should only be called during an unwind - PRECONDITION(pCurThread != NULL); - } - CONTRACTL_END; - - // - // - // Typically, exception tracker is created for an exception when the OS is in the first pass. - // However, it may be created during the 2nd pass under specific cases. Managed C++ provides - // such a scenario. In the following, stack grows left to right: - // - // CallDescrWorker -> ILStub1 -> -> UMThunkStub -> IL_Stub2 -> - // - // If a CSE exception goes unhandled from managed main, it will reach the OS. The [CRT in?] OS triggers - // unwind that results in invoking the personality routine of UMThunkStub, called UMThunkStubUnwindFrameChainHandler, - // that releases all exception trackers below it. Thus, the tracker for the CSE, which went unhandled, is also - // released. This detail is 64bit specific and the crux of this issue. - // - // Now, it is expected that by the time we are in the unwind pass, the corruption severity would have already been setup in the - // exception tracker and thread exception state (TES) as part of the first pass, and thus, are identical. - // - // However, for the scenario above, when the unwind continues and reaches ILStub1, its personality routine (which is ProcessCLRException) - // is invoked. It attempts to get the exception tracker corresponding to the exception. Since none exists, it creates a brand new one, - // which has the exception corruption severity as NotSet. - // - // During the stack walk, we know (from TES) that the active exception was a CSE, and thus, ILStub1 cannot handle the exception. Prior - // to bailing out, we assert that our data structures are intact by comparing the exception severity in TES with the one in the current - // exception tracker. Since the tracker was recreated, it had the severity as NotSet and this does not match the severity in TES. - // Thus, the assert fires. [This check is performed in ProcessManagedCallFrame.] - // - // To address such a case, if we have created a new exception tracker in the unwind (2nd) pass, then set its - // exception corruption severity to what the TES holds currently. This will maintain the same semantic as the case - // where new tracker is not created (for e.g. the exception was caught in Managed main). - // - // The exception is the scenario of code that uses longjmp to jump to a different context. Longjmp results in a raise - // of a new exception with the longjmp exception code (0x80000026) but with ExceptionFlags set indicating unwind. When this is - // seen by ProcessCLRException (64bit personality routine), it will create a new tracker in the 2nd pass. - // - // Longjmp outside an exceptional path does not interest us, but the one in the exceptional - // path would only happen when a method attributed to handle CSE invokes it. Thus, if the longjmp happened during the 2nd pass of a CSE, - // we want it to proceed (and thus, jump) as expected and not apply the CSE severity to the tracker - this is equivalent to - // a catch block that handles a CSE and then does a "throw new Exception();". The new exception raised is - // non-CSE in nature as well. - // - // http://www.nynaeve.net/?p=105 has a brief description of how exception-safe setjmp/longjmp works. - // - // - if (pEHTracker->GetCorruptionSeverity() == NotSet) - { - // Get the thread exception state - ThreadExceptionState *pCurTES = pCurThread->GetExceptionState(); - - // Set the tracker to have the same corruption severity as the last active severity unless we are dealing - // with LONGJMP - if (dwExceptionCode == STATUS_LONGJUMP) - { - pCurTES->SetLastActiveExceptionCorruptionSeverity(NotCorrupting); - } - - pEHTracker->SetCorruptionSeverity(pCurTES->GetLastActiveExceptionCorruptionSeverity()); - LOG((LF_EH, LL_INFO100, "CEHelper::SetupCorruptionSeverityForActiveExceptionInUnwindPass - Setup the corruption severity in the second pass.\n")); - } -#endif // !DACCESS_COMPILE -} -#endif // FEATURE_EH_FUNCLETS - -// This method is invoked from the personality routine for managed code and is used to setup the -// corruption severity for the active exception on the thread exception state and the -// exception tracker corresponding to the exception. -/* static */ -void CEHelper::SetupCorruptionSeverityForActiveException(BOOL fIsRethrownException, BOOL fIsNestedException, BOOL fShouldTreatExceptionAsNonCorrupting /* = FALSE */) -{ -#ifndef DACCESS_COMPILE - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_COOPERATIVE; - } - CONTRACTL_END; - - // Get the thread and the managed exception object - they must exist at this point - Thread *pCurThread = GetThread(); - _ASSERTE(pCurThread != NULL); - - OBJECTREF oThrowable = pCurThread->GetThrowable(); - _ASSERTE(oThrowable != NULL); - - // Get the thread exception state - ThreadExceptionState * pCurTES = pCurThread->GetExceptionState(); - _ASSERTE(pCurTES != NULL); - - // Get the exception tracker for the current exception -#ifdef FEATURE_EH_FUNCLETS - PTR_ExceptionTracker pEHTracker = pCurTES->GetCurrentExceptionTracker(); -#elif TARGET_X86 - PTR_ExInfo pEHTracker = pCurTES->GetCurrentExceptionTracker(); -#else // !(HOST_64BIT || TARGET_X86) -#error Unsupported platform -#endif // HOST_64BIT - - _ASSERTE(pEHTracker != NULL); - - // Get the current exception code from the tracker. - PEXCEPTION_RECORD pEHRecord = pCurTES->GetExceptionRecord(); - _ASSERTE(pEHRecord != NULL); - DWORD dwActiveExceptionCode = pEHRecord->ExceptionCode; - - if (pEHTracker->GetCorruptionSeverity() != NotSet) - { - // Since the exception tracker already has the corruption severity set, - // we dont have much to do. Just confirm that our assumptions are correct. - _ASSERTE(pEHTracker->GetCorruptionSeverity() == pCurTES->GetLastActiveExceptionCorruptionSeverity()); - - LOG((LF_EH, LL_INFO100, "CEHelper::SetupCorruptionSeverityForActiveException - Current tracker already has the corruption severity set.\n")); - return; - } - - // If the exception in question is to be treated as non-corrupting, - // then flag it and exit. - if (fShouldTreatExceptionAsNonCorrupting || g_pConfig->LegacyCorruptedStateExceptionsPolicy()) - { - pEHTracker->SetCorruptionSeverity(NotCorrupting); - LOG((LF_EH, LL_INFO100, "CEHelper::SetupCorruptionSeverityForActiveException - Exception treated as non-corrupting.\n")); - goto done; - } - - if (!fIsRethrownException && !fIsNestedException) - { - // There should be no previously active exception for this case - _ASSERTE(pEHTracker->GetPreviousExceptionTracker() == NULL); - - CorruptionSeverity severityTES = NotSet; - - if (pCurTES->ShouldLastActiveExceptionCorruptionSeverityBeReused()) - { - // Get the corruption severity from the ThreadExceptionState (TES) for the last active exception - severityTES = pCurTES->GetLastActiveExceptionCorruptionSeverity(); - - // Incase of scenarios like AD transition or Reflection invocation, - // TES would hold corruption severity of the last active exception. To propagate it - // to the current exception, we will apply it to current tracker and only if the applied - // severity is "NotSet", will we proceed to check the current exception for corruption - // severity. - pEHTracker->SetCorruptionSeverity(severityTES); - } - - // Reset TES Corruption Severity - pCurTES->SetLastActiveExceptionCorruptionSeverity(NotSet); - - if (severityTES == NotSet) - { - // Since the last active exception's severity was "NotSet", we will look up the - // exception code and the exception object to see if the exception should be marked - // corrupting. - // - // Since this exception was neither rethrown nor is nested, it implies that we are - // outside an active exception. Thus, even if it contains inner exceptions, we wont have - // corruption severity for them since that information is tracked in EH tracker and - // we wont have an EH tracker for the inner most exception. - - if (CEHelper::IsProcessCorruptedStateException(dwActiveExceptionCode) || - CEHelper::IsProcessCorruptedStateException(oThrowable)) - { - pEHTracker->SetCorruptionSeverity(ProcessCorrupting); - LOG((LF_EH, LL_INFO100, "CEHelper::SetupCorruptionSeverityForActiveException - Marked non-rethrow/non-nested exception as ProcessCorrupting.\n")); - } - else - { - pEHTracker->SetCorruptionSeverity(NotCorrupting); - LOG((LF_EH, LL_INFO100, "CEHelper::SetupCorruptionSeverityForActiveException - Marked non-rethrow/non-nested exception as NotCorrupting.\n")); - } - } - else - { - LOG((LF_EH, LL_INFO100, "CEHelper::SetupCorruptionSeverityForActiveException - Copied the corruption severity to tracker from ThreadExceptionState for non-rethrow/non-nested exception.\n")); - } - } - else - { - // Its either a rethrow or nested exception - -#ifdef FEATURE_EH_FUNCLETS - PTR_ExceptionTracker pOrigEHTracker = NULL; -#elif TARGET_X86 - PTR_ExInfo pOrigEHTracker = NULL; -#else -#error Unsupported platform -#endif - - BOOL fDoWeHaveCorruptionSeverity = FALSE; - - if (fIsRethrownException) - { - // Rethrown exceptions are nested by nature (of our implementation). The - // original EHTracker will exist for the exception - infact, it will be - // the tracker previous to the current one. We will simply copy - // its severity to the current EH tracker representing the rethrow. - pOrigEHTracker = pEHTracker->GetPreviousExceptionTracker(); - _ASSERTE(pOrigEHTracker != NULL); - - // Ideally, we would like have the assert below enabled. But, as may happen under OOM - // stress, this can be false. Here's how it will happen: - // - // An exception is thrown, which is later caught and rethrown in the catch block. Rethrow - // results in calling IL_Rethrow that will call RaiseTheExceptionInternalOnly to actually - // raise the exception. Prior to the raise, we update the last thrown object on the thread - // by calling Thread::SafeSetLastThrownObject which, internally, could have an OOM, resulting - // in "changing" the throwable used to raise the exception to be preallocated OOM object. - // - // When the rethrow happens and CLR's exception handler for managed code sees the exception, - // the exception tracker created for the rethrown exception will contain the reference to - // the last thrown object, which will be the preallocated OOM object. - // - // Thus, though, we came here because of a rethrow, and logically, the throwable should remain - // the same, it neednt be. Simply put, rethrow can result in working with a completely different - // exception object than what was originally thrown. - // - // Hence, the assert cannot be enabled. - // - // Thus, we will use the EH tracker corresponding to the original exception, to get the - // rethrown exception's corruption severity, only when the rethrown throwable is the same - // as the original throwable. Otherwise, we will pretend that we didnt get the original tracker - // and will automatically enter the path below to set the corruption severity based upon the - // rethrown throwable. - - // _ASSERTE(pOrigEHTracker->GetThrowable() == oThrowable); - if (pOrigEHTracker->GetThrowable() != oThrowable) - { - pOrigEHTracker = NULL; - LOG((LF_EH, LL_INFO100, "CEHelper::SetupCorruptionSeverityForActiveException - Rethrown throwable does not match the original throwable. Corruption severity will be set based upon rethrown throwable.\n")); - } - } - else - { - // Get the corruption severity from the ThreadExceptionState (TES) for the last active exception - CorruptionSeverity severityTES = NotSet; - - if (pCurTES->ShouldLastActiveExceptionCorruptionSeverityBeReused()) - { - severityTES = pCurTES->GetLastActiveExceptionCorruptionSeverity(); - - // Incase of scenarios like AD transition or Reflection invocation, - // TES would hold corruption severity of the last active exception. To propagate it - // to the current exception, we will apply it to current tracker and only if the applied - // severity is "NotSet", will we proceed to check the current exception for corruption - // severity. - pEHTracker->SetCorruptionSeverity(severityTES); - } - - // Reset TES Corruption Severity - pCurTES->SetLastActiveExceptionCorruptionSeverity(NotSet); - - // If the last exception didnt have any corruption severity, proceed to look for it. - if (severityTES == NotSet) - { - // This is a nested exception - check if it has an inner exception(s). If it does, - // find the EH tracker corresponding to the innermost exception and we will copy the - // corruption severity from the original tracker to the current one. - OBJECTREF oInnermostThrowable = ((EXCEPTIONREF)oThrowable)->GetBaseException(); - if (oInnermostThrowable != NULL) - { - // Find the tracker corresponding to the inner most exception, starting from - // the tracker previous to the current one. An EH tracker may not be found if - // the code did the following inside a catch clause: - // - // Exception ex = new Exception("inner exception"); - // throw new Exception("message", ex); - // - // Or, an exception like AV happened in the catch clause. - pOrigEHTracker = GetEHTrackerForException(oInnermostThrowable, pEHTracker->GetPreviousExceptionTracker()); - } - } - else - { - // We have the corruption severity from the TES. Set the flag indicating so. - fDoWeHaveCorruptionSeverity = TRUE; - LOG((LF_EH, LL_INFO100, "CEHelper::SetupCorruptionSeverityForActiveException - Copied the corruption severity to tracker from ThreadExceptionState for nested exception.\n")); - } - } - - if (!fDoWeHaveCorruptionSeverity) - { - if (pOrigEHTracker != NULL) - { - // Copy the severity from the original EH tracker to the current one - CorruptionSeverity origCorruptionSeverity = pOrigEHTracker->GetCorruptionSeverity(); - _ASSERTE(origCorruptionSeverity != NotSet); - pEHTracker->SetCorruptionSeverity(origCorruptionSeverity); - - LOG((LF_EH, LL_INFO100, "CEHelper::SetupCorruptionSeverityForActiveException - Copied the corruption severity (%d) from the original EH tracker for rethrown exception.\n", origCorruptionSeverity)); - } - else - { - if (CEHelper::IsProcessCorruptedStateException(dwActiveExceptionCode) || - CEHelper::IsProcessCorruptedStateException(oThrowable)) - { - pEHTracker->SetCorruptionSeverity(ProcessCorrupting); - LOG((LF_EH, LL_INFO100, "CEHelper::SetupCorruptionSeverityForActiveException - Marked nested exception as ProcessCorrupting.\n")); - } - else - { - pEHTracker->SetCorruptionSeverity(NotCorrupting); - LOG((LF_EH, LL_INFO100, "CEHelper::SetupCorruptionSeverityForActiveException - Marked nested exception as NotCorrupting.\n")); - } - } - } - } - -done: - // Save the current exception's corruption severity in the ThreadExceptionState (TES) - // for cases when we catch the managed exception in the runtime using EX_CATCH. - // At such a time, all exception trackers get released (due to unwind triggered - // by EX_END_CATCH) and yet we need the corruption severity information for - // scenarios like AD Transition, Reflection invocation, etc. - CorruptionSeverity currentSeverity = pEHTracker->GetCorruptionSeverity(); - - // We should be having a valid corruption severity at this point - _ASSERTE(currentSeverity != NotSet); - - // Save it in the TES - pCurTES->SetLastActiveExceptionCorruptionSeverity(currentSeverity); - LOG((LF_EH, LL_INFO100, "CEHelper::SetupCorruptionSeverityForActiveException - Copied the corruption severity (%d) to ThreadExceptionState.\n", currentSeverity)); - -#endif // !DACCESS_COMPILE -} - -// CE can be caught in the VM and later reraised again. Examples of such scenarios -// include AD transition, COM interop, Reflection invocation, to name a few. -// In such cases, we want to mark the corruption severity for reuse upon reraise, -// implying that when the VM does a reraise of such an exception, we should use -// the original corruption severity for the new raised exception, instead of creating -// a new one for it. -/* static */ -void CEHelper::MarkLastActiveExceptionCorruptionSeverityForReraiseReuse() -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - PRECONDITION(GetThread() != NULL); - } - CONTRACTL_END; - - // If the last active exception's corruption severity is anything but - // "NotSet", mark it for ReraiseReuse - ThreadExceptionState *pCurTES = GetThread()->GetExceptionState(); - _ASSERTE(pCurTES != NULL); - - CorruptionSeverity severityTES = pCurTES->GetLastActiveExceptionCorruptionSeverity(); - if (severityTES != NotSet) - { - pCurTES->SetLastActiveExceptionCorruptionSeverity((CorruptionSeverity)(severityTES | ReuseForReraise)); - } -} - -// This method will return a BOOL to indicate if the current exception is to be treated as -// non-corrupting. Currently, this returns true for NullReferenceException only. -/* static */ -BOOL CEHelper::ShouldTreatActiveExceptionAsNonCorrupting() -{ - BOOL fShouldTreatAsNonCorrupting = FALSE; - -#ifndef DACCESS_COMPILE - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - PRECONDITION(GetThread() != NULL); - } - CONTRACTL_END; - - if (g_pConfig->LegacyCorruptedStateExceptionsPolicy()) - { - return TRUE; - } - - DWORD dwActiveExceptionCode = GetThread()->GetExceptionState()->GetExceptionRecord()->ExceptionCode; - if (dwActiveExceptionCode == STATUS_ACCESS_VIOLATION) - { - // NullReference has the same exception code as AV - OBJECTREF oThrowable = NULL; - GCPROTECT_BEGIN(oThrowable); - - // Get the throwable and check if it represents null reference exception - oThrowable = GetThread()->GetThrowable(); - _ASSERTE(oThrowable != NULL); - if (MscorlibBinder::GetException(kNullReferenceException) == oThrowable->GetMethodTable()) - { - fShouldTreatAsNonCorrupting = TRUE; - } - GCPROTECT_END(); - } -#endif // !DACCESS_COMPILE - - return fShouldTreatAsNonCorrupting; -} - -// If we were working in a nested exception scenario, reset the corruption severity to the last -// exception we were processing, based upon its EH tracker. -// -// If none was present, reset it to NotSet. -// -// Note: This method must be called once the exception trackers have been adjusted post catch-block execution. -/* static */ -void CEHelper::ResetLastActiveCorruptionSeverityPostCatchHandler(Thread *pThread) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - PRECONDITION(pThread != NULL); - } - CONTRACTL_END; - - ThreadExceptionState *pCurTES = pThread->GetExceptionState(); - - // By this time, we would have set the correct exception tracker for the active exception domain, - // if applicable. An example is throwing and catching an exception within a catch block. We will update - // the LastActiveCorruptionSeverity based upon the active exception domain. If we are not in one, we will - // set it to "NotSet". -#ifdef FEATURE_EH_FUNCLETS - PTR_ExceptionTracker pEHTracker = pCurTES->GetCurrentExceptionTracker(); -#elif TARGET_X86 - PTR_ExInfo pEHTracker = pCurTES->GetCurrentExceptionTracker(); -#else -#error Unsupported platform -#endif - - if (pEHTracker) - { - pCurTES->SetLastActiveExceptionCorruptionSeverity(pEHTracker->GetCorruptionSeverity()); - } - else - { - pCurTES->SetLastActiveExceptionCorruptionSeverity(NotSet); - } - - LOG((LF_EH, LL_INFO100, "CEHelper::ResetLastActiveCorruptionSeverityPostCatchHandler - Reset LastActiveException corruption severity to %d.\n", - pCurTES->GetLastActiveExceptionCorruptionSeverity())); -} - -// This method will return a BOOL indicating if the target of IDispatch can handle the specified exception or not. -/* static */ -BOOL CEHelper::CanIDispatchTargetHandleException() -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - PRECONDITION(GetThread() != NULL); - } - CONTRACTL_END; - - // By default, assume that the target of IDispatch cannot handle the exception. - BOOL fCanMethodHandleException = FALSE; - - if (g_pConfig->LegacyCorruptedStateExceptionsPolicy()) - { - return TRUE; - } - - // IDispatch implementation in COM interop works by invoking the actual target via reflection. - // Thus, a COM client could use the V4 runtime to invoke a V2 method. In such a case, a CSE - // could come unhandled at the actual target invoked via reflection. - // - // Reflection invocation would have set a flag for us, indicating if the actual target was - // enabled to handle the CE or not. If it is, then we should allow the COM client to get the - // hresult from the call and not let the exception continue up the stack. - ThreadExceptionState *pCurTES = GetThread()->GetExceptionState(); - fCanMethodHandleException = pCurTES->CanReflectionTargetHandleException(); - - // Reset the flag so that subsequent invocations work as expected. - pCurTES->SetCanReflectionTargetHandleException(FALSE); + if (CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_legacyCorruptedStateExceptionsPolicy)) + return FALSE; - return fCanMethodHandleException; + return TRUE; } -#endif // FEATURE_CORRUPTING_EXCEPTIONS - #ifndef DACCESS_COMPILE // This method will deliver the actual exception notification. Its assumed that the caller has done the necessary checks, including // checking whether the delegate can be invoked for the exception's corruption severity. @@ -11964,7 +11092,7 @@ void ExceptionNotifications::GetEventArgsForNotification(ExceptionNotificationHa *pOutEventArgs = NULL; LOG((LF_EH, LL_INFO100, "ExceptionNotifications::GetEventArgsForNotification: Setting event args to NULL due to an exception.\n")); } - EX_END_CATCH(RethrowCorruptingExceptions); // Dont swallow any CSE that may come in from the .ctor. + EX_END_CATCH(RethrowTerminalExceptions); } // This SEH filter will be invoked when an exception escapes out of the exception notification @@ -11975,89 +11103,6 @@ static LONG ExceptionNotificationFilter(PEXCEPTION_POINTERS pExceptionInfo, LPVO return -1; } -#ifdef FEATURE_CORRUPTING_EXCEPTIONS -// This method will return a BOOL indicating if the delegate should be invoked for the exception -// of the specified corruption severity. -BOOL ExceptionNotifications::CanDelegateBeInvokedForException(OBJECTREF *pDelegate, CorruptionSeverity severity) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - PRECONDITION(pDelegate != NULL && IsProtectedByGCFrame(pDelegate) && (*pDelegate != NULL)); - PRECONDITION(severity > NotSet); - } - CONTRACTL_END; - - // Notifications for CSE are only delivered if the delegate target follows CSE rules. - BOOL fCanMethodHandleException = g_pConfig->LegacyCorruptedStateExceptionsPolicy() ? TRUE:(severity == NotCorrupting); - if (!fCanMethodHandleException) - { - EX_TRY - { - // Get the MethodDesc of the delegate to be invoked - MethodDesc *pMDDelegate = COMDelegate::GetMethodDesc(*pDelegate); - _ASSERTE(pMDDelegate != NULL); - - // Check the callback target and see if it is following CSE rules or not. - fCanMethodHandleException = CEHelper::CanMethodHandleException(severity, pMDDelegate); - } - EX_CATCH - { - // Incase of any exceptions, pretend we cannot handle the exception - fCanMethodHandleException = FALSE; - LOG((LF_EH, LL_INFO100, "ExceptionNotifications::CanDelegateBeInvokedForException: Exception while trying to determine if exception notification can be invoked or not.\n")); - } - EX_END_CATCH(RethrowCorruptingExceptions); // Dont swallow any CSEs. - } - - return fCanMethodHandleException; -} -#endif // FEATURE_CORRUPTING_EXCEPTIONS - -// This method will make the actual delegate invocation for the exception notification to be delivered. If an -// exception escapes out of the notification, our filter in ExceptionNotifications::DeliverNotification will -// address it. -void ExceptionNotifications::InvokeNotificationDelegate(ExceptionNotificationHandlerType notificationType, OBJECTREF *pDelegate, OBJECTREF *pEventArgs, - OBJECTREF *pAppDomain -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , CorruptionSeverity severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ) -{ - CONTRACTL - { - THROWS; - GC_TRIGGERS; - MODE_COOPERATIVE; - PRECONDITION(pDelegate != NULL && IsProtectedByGCFrame(pDelegate) && (*pDelegate != NULL)); - PRECONDITION(pEventArgs != NULL && IsProtectedByGCFrame(pEventArgs)); - PRECONDITION(pAppDomain != NULL && IsProtectedByGCFrame(pAppDomain)); -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - PRECONDITION(severity > NotSet); -#endif // FEATURE_CORRUPTING_EXCEPTIONS - // Unhandled Exception Notification is delivered via Unhandled Exception Processing - // mechanism. - PRECONDITION(notificationType != UnhandledExceptionHandler); - } - CONTRACTL_END; - -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // Notifications are delivered based upon corruption severity of the exception - if (!ExceptionNotifications::CanDelegateBeInvokedForException(pDelegate, severity)) - { - LOG((LF_EH, LL_INFO100, "ExceptionNotifications::InvokeNotificationDelegate: Delegate cannot be invoked for corruption severity %d\n", - severity)); - return; - } -#endif // FEATURE_CORRUPTING_EXCEPTIONS - - // We've already exercised the prestub on this delegate's COMDelegate::GetMethodDesc, - // as part of wiring up a reliable event sink in the BCL. Deliver the notification. - ExceptionNotifications::DeliverExceptionNotification(notificationType, pDelegate, pAppDomain, pEventArgs); -} - // This method returns a BOOL to indicate if the AppDomain is ready to receive exception notifications or not. BOOL ExceptionNotifications::CanDeliverNotificationToCurrentAppDomain(ExceptionNotificationHandlerType notificationType) { @@ -12087,11 +11132,7 @@ BOOL ExceptionNotifications::CanDeliverNotificationToCurrentAppDomain(ExceptionN // so that if an exception escapes out of the notification callback, we will trigger failfast from // our filter. void ExceptionNotifications::DeliverNotification(ExceptionNotificationHandlerType notificationType, - OBJECTREF *pThrowable -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , CorruptionSeverity severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ) + OBJECTREF *pThrowable) { STATIC_CONTRACT_GC_TRIGGERS; STATIC_CONTRACT_NOTHROW; // NOTHROW because incase of an exception, we will FailFast. @@ -12101,26 +11142,16 @@ void ExceptionNotifications::DeliverNotification(ExceptionNotificationHandlerTyp { ExceptionNotificationHandlerType notificationType; OBJECTREF *pThrowable; -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - CorruptionSeverity severity; -#endif // FEATURE_CORRUPTING_EXCEPTIONS } args; args.notificationType = notificationType; args.pThrowable = pThrowable; -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - args.severity = severity; -#endif // FEATURE_CORRUPTING_EXCEPTIONS PAL_TRY(TryArgs *, pArgs, &args) { // Make the call to the actual method that will invoke the callbacks ExceptionNotifications::DeliverNotificationInternal(pArgs->notificationType, - pArgs->pThrowable -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , pArgs->severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ); + pArgs->pThrowable); } PAL_EXCEPT_FILTER(ExceptionNotificationFilter) { @@ -12134,11 +11165,7 @@ void ExceptionNotifications::DeliverNotification(ExceptionNotificationHandlerTyp // This method will deliver the exception notification to the current AppDomain. void ExceptionNotifications::DeliverNotificationInternal(ExceptionNotificationHandlerType notificationType, - OBJECTREF *pThrowable -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , CorruptionSeverity severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ) + OBJECTREF *pThrowable) { CONTRACTL { @@ -12151,9 +11178,6 @@ void ExceptionNotifications::DeliverNotificationInternal(ExceptionNotificationHa PRECONDITION(notificationType != UnhandledExceptionHandler); PRECONDITION((pThrowable != NULL) && (*pThrowable != NULL)); PRECONDITION(ExceptionNotifications::CanDeliverNotificationToCurrentAppDomain(notificationType)); -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - PRECONDITION(severity > NotSet); // Exception corruption severity must be valid at this point. -#endif // FEATURE_CORRUPTING_EXCEPTIONS } CONTRACTL_END; @@ -12220,12 +11244,7 @@ void ExceptionNotifications::DeliverNotificationInternal(ExceptionNotificationHa gc.arrDelegates = (PTRARRAYREF) ((DELEGATEREF)(gc.oNotificationDelegate))->GetInvocationList(); if (gc.arrDelegates == NULL || !gc.arrDelegates->GetMethodTable()->IsArray()) { - ExceptionNotifications::InvokeNotificationDelegate(notificationType, &gc.oNotificationDelegate, &gc.oEventArgs, - &gc.oCurAppDomain -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ); + ExceptionNotifications::DeliverExceptionNotification(notificationType, &gc.oNotificationDelegate, &gc.oCurAppDomain, &gc.oEventArgs); } else { @@ -12237,12 +11256,7 @@ void ExceptionNotifications::DeliverNotificationInternal(ExceptionNotificationHa for (UINT_PTR i=0; im_Array[i]; - ExceptionNotifications::InvokeNotificationDelegate(notificationType, &gc.oInnerDelegate, &gc.oEventArgs, - &gc.oCurAppDomain -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ); + ExceptionNotifications::DeliverExceptionNotification(notificationType, &gc.oInnerDelegate, &gc.oCurAppDomain, &gc.oEventArgs); } } } @@ -12282,11 +11296,7 @@ void ExceptionNotifications::DeliverFirstChanceNotification() oThrowable = pCurTES->GetThrowable(); _ASSERTE(oThrowable != NULL); - ExceptionNotifications::DeliverNotification(FirstChanceExceptionHandler, &oThrowable -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , pCurTES->GetCurrentExceptionTracker()->GetCorruptionSeverity() -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ); + ExceptionNotifications::DeliverNotification(FirstChanceExceptionHandler, &oThrowable); GCPROTECT_END(); } diff --git a/src/coreclr/src/vm/excep.h b/src/coreclr/src/vm/excep.h index c31ead4d385290..661eefe813bb77 100644 --- a/src/coreclr/src/vm/excep.h +++ b/src/coreclr/src/vm/excep.h @@ -26,6 +26,8 @@ BOOL IsExceptionFromManagedCode(const EXCEPTION_RECORD * pExceptionRecord); BOOL IsIPinVirtualStub(PCODE f_IP); bool IsIPInMarkedJitHelper(UINT_PTR uControlPc); +BOOL IsProcessCorruptedStateException(DWORD dwExceptionCode, OBJECTREF throwable); + BOOL AdjustContextForJITHelpers(EXCEPTION_RECORD *pExceptionRecord, CONTEXT *pContext); #if defined(FEATURE_HIJACK) && (!defined(TARGET_X86) || defined(TARGET_UNIX)) @@ -70,8 +72,6 @@ struct ThrowCallbackType void * pPrevExceptionRecord; #endif - // Is the current exception a longjmp? - CORRUPTING_EXCEPTIONS_ONLY(BOOL m_fIsLongJump;) void Init() { LIMITED_METHOD_CONTRACT; @@ -92,8 +92,6 @@ struct ThrowCallbackType pCurrentExceptionRecord = 0; pPrevExceptionRecord = 0; #endif - // By default, the current exception is not a longjmp - CORRUPTING_EXCEPTIONS_ONLY(m_fIsLongJump = FALSE;) } }; @@ -251,11 +249,7 @@ VOID DECLSPEC_NORETURN RealCOMPlusThrowNonLocalized(RuntimeExceptionKind reKind, // Throw an object. //========================================================================== -VOID DECLSPEC_NORETURN RealCOMPlusThrow(OBJECTREF throwable -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , CorruptionSeverity severity = NotCorrupting -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ); +VOID DECLSPEC_NORETURN RealCOMPlusThrow(OBJECTREF throwable); //========================================================================== // Throw an undecorated runtime exception. @@ -800,44 +794,6 @@ LONG ReflectionInvocationExceptionFilter( EXCEPTION_POINTERS *pExceptionInfo, // the pExceptionInfo passed to a filter function. PVOID pParam); -#ifdef FEATURE_CORRUPTING_EXCEPTIONS -// ----------------------------------------------------------------------- -// Support for Corrupted State Exceptions -// ----------------------------------------------------------------------- -#ifndef HANDLE_PROCESS_CORRUPTED_STATE_EXCEPTION_ATTRIBUTE -#define HANDLE_PROCESS_CORRUPTED_STATE_EXCEPTION_ATTRIBUTE "System.Runtime.ExceptionServices.HandleProcessCorruptedStateExceptionsAttribute" -#endif // HANDLE_PROCESS_CORRUPTED_STATE_EXCEPTION_ATTRIBUTE - -#ifndef HIGHEST_MAJOR_VERSION_OF_PREV4_RUNTIME -#define HIGHEST_MAJOR_VERSION_OF_PREV4_RUNTIME 2 -#endif // HIGHEST_MAJOR_VERSION_OF_PREV4_RUNTIME - -// This helper class contains static method to support working with Corrupted State Exceptions, -// including checking if a method can handle it or not, copy state across throwables, etc. -class CEHelper -{ - BOOL static IsMethodInPreV4Assembly(PTR_MethodDesc pMethodDesc); - BOOL static CanMethodHandleCE(PTR_MethodDesc pMethodDesc, CorruptionSeverity severity); - -public: - BOOL static CanMethodHandleException(CorruptionSeverity severity, PTR_MethodDesc pMethodDesc); - BOOL static CanIDispatchTargetHandleException(); - BOOL static IsProcessCorruptedStateException(DWORD dwExceptionCode, BOOL fCheckForSO = TRUE); - BOOL static IsProcessCorruptedStateException(OBJECTREF oThrowable); - BOOL static IsLastActiveExceptionCorrupting(BOOL fMarkForReuseIfCorrupting = FALSE); - BOOL static ShouldTreatActiveExceptionAsNonCorrupting(); - void static MarkLastActiveExceptionCorruptionSeverityForReraiseReuse(); - void static SetupCorruptionSeverityForActiveException(BOOL fIsRethrownException, BOOL fIsNestedException, BOOL fShouldTreatExceptionAsNonCorrupting = FALSE); -#ifdef FEATURE_EH_FUNCLETS - typedef DPTR(class ExceptionTracker) PTR_ExceptionTracker; - void static SetupCorruptionSeverityForActiveExceptionInUnwindPass(Thread *pCurThread, PTR_ExceptionTracker pEHTracker, BOOL fIsFirstPass, - DWORD dwExceptionCode); -#endif // FEATURE_EH_FUNCLETS - void static ResetLastActiveCorruptionSeverityPostCatchHandler(Thread *pThread); -}; - -#endif // FEATURE_CORRUPTING_EXCEPTIONS - #ifndef DACCESS_COMPILE // exception filter invoked for unhandled exceptions on the entry point thread (thread 0) LONG EntryPointFilter(PEXCEPTION_POINTERS pExceptionInfo, PVOID _pData); @@ -860,36 +816,17 @@ class ExceptionNotifications OBJECTREF *pOutEventArgs, OBJECTREF *pThrowable); void static DeliverNotificationInternal(ExceptionNotificationHandlerType notificationType, - OBJECTREF *pThrowable -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , CorruptionSeverity severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ); - - void static InvokeNotificationDelegate(ExceptionNotificationHandlerType notificationType, OBJECTREF *pDelegate, OBJECTREF *pEventArgs, - OBJECTREF *pAppDomain -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , CorruptionSeverity severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ); + OBJECTREF *pThrowable); public: - BOOL static CanDeliverNotificationToCurrentAppDomain(ExceptionNotificationHandlerType notificationType); + void static DeliverExceptionNotification(ExceptionNotificationHandlerType notificationType, OBJECTREF *pDelegate, OBJECTREF *pEventArgs, + OBJECTREF *pAppDomain); - void static DeliverNotification(ExceptionNotificationHandlerType notificationType, - OBJECTREF *pThrowable -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , CorruptionSeverity severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ); + BOOL static CanDeliverNotificationToCurrentAppDomain(ExceptionNotificationHandlerType notificationType); -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - BOOL static CanDelegateBeInvokedForException(OBJECTREF *pDelegate, CorruptionSeverity severity); -#endif // FEATURE_CORRUPTING_EXCEPTIONS + void static DeliverNotification(ExceptionNotificationHandlerType notificationType, OBJECTREF *pThrowable); public: - void static DeliverExceptionNotification(ExceptionNotificationHandlerType notificationType, OBJECTREF *pDelegate, - OBJECTREF *pAppDomain, OBJECTREF *pEventArgs); void static DeliverFirstChanceNotification(); }; diff --git a/src/coreclr/src/vm/exceptionhandling.cpp b/src/coreclr/src/vm/exceptionhandling.cpp index 740678e978e171..c655fe8ded92c2 100644 --- a/src/coreclr/src/vm/exceptionhandling.cpp +++ b/src/coreclr/src/vm/exceptionhandling.cpp @@ -1006,23 +1006,13 @@ ProcessCLRException(IN PEXCEPTION_RECORD pExceptionRecord !(dwExceptionFlags & EXCEPTION_UNWINDING), &STState); -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // Only setup the Corruption Severity in the first pass if (!(dwExceptionFlags & EXCEPTION_UNWINDING)) { // Switch to COOP mode GCX_COOP(); - if (pTracker && pTracker->GetThrowable() != NULL) - { - // Setup the state in current exception tracker indicating the corruption severity - // of the active exception. - CEHelper::SetupCorruptionSeverityForActiveException((STState == ExceptionTracker::STS_FirstRethrowFrame), (pTracker->GetPreviousExceptionTracker() != NULL), - CEHelper::ShouldTreatActiveExceptionAsNonCorrupting()); - } - // Failfast if exception indicates corrupted process state - if (pTracker->GetCorruptionSeverity() == ProcessCorrupting) + if (IsProcessCorruptedStateException(pExceptionRecord->ExceptionCode, pTracker->GetThrowable())) { OBJECTREF oThrowable = NULL; SString message; @@ -1045,7 +1035,6 @@ ProcessCLRException(IN PEXCEPTION_RECORD pExceptionRecord EEPOLICY_HANDLE_FATAL_ERROR_WITH_MESSAGE(pExceptionRecord->ExceptionCode, (LPCWSTR)message); } } -#endif // FEATURE_CORRUPTING_EXCEPTIONS #ifndef TARGET_UNIX // Watson is on Windows only // Setup bucketing details for nested exceptions (rethrow and non-rethrow) only if we are in the first pass @@ -2446,25 +2435,6 @@ CLRUnwindStatus ExceptionTracker::ProcessManagedCallFrame( if (fIsILStub && !fIsFunclet) // only make this callback on the main method body of IL stubs pUserMDForILStub = GetUserMethodForILStub(pThread, sf.SP, pMD, &pILStubFrame); -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - BOOL fCanMethodHandleException = TRUE; - CorruptionSeverity currentSeverity = NotCorrupting; - { - // Switch to COOP mode since we are going to request throwable - GCX_COOP(); - - // We must defer to the MethodDesc of the user method instead of the IL stub - // itself because the user can specify the policy on a per-method basis and - // that won't be reflected via the IL stub's MethodDesc. - MethodDesc * pMDWithCEAttribute = (pUserMDForILStub != NULL) ? pUserMDForILStub : pMD; - - // Check if the exception can be delivered to the method? It will check if the exception - // is a CE or not. If it is, it will check if the method can process it or not. - currentSeverity = pThread->GetExceptionState()->GetCurrentExceptionTracker()->GetCorruptionSeverity(); - fCanMethodHandleException = CEHelper::CanMethodHandleException(currentSeverity, pMDWithCEAttribute); - } -#endif // FEATURE_CORRUPTING_EXCEPTIONS - // Doing rude abort. Skip all non-constrained execution region code. // When rude abort is initiated, we cannot intercept any exceptions. if (pThread->IsRudeAbortInitiated()) @@ -2673,27 +2643,7 @@ CLRUnwindStatus ExceptionTracker::ProcessManagedCallFrame( const METHODTOKEN& MethToken = pcfThisFrame->GetMethodToken(); EH_CLAUSE_ENUMERATOR EnumState; - unsigned EHCount; - -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // The method cannot handle the exception (e.g. cannot handle the CE), then simply bail out - // without examining the EH clauses in it. - if (!fCanMethodHandleException) - { - LOG((LF_EH, LL_INFO100, "ProcessManagedCallFrame - CEHelper decided not to look for exception handlers in the method(MD:%p).\n", pMD)); - - // Set the flag to skip this frame since the CE cannot be delivered - _ASSERTE(currentSeverity == ProcessCorrupting); - - // Force EHClause count to be zero - EHCount = 0; - } - else -#endif // FEATURE_CORRUPTING_EXCEPTIONS - { - EHCount = pJitMan->InitializeEHEnumeration(MethToken, &EnumState); - } - + unsigned EHCount = pJitMan->InitializeEHEnumeration(MethToken, &EnumState); if (!fIsFirstPass) { @@ -3961,20 +3911,6 @@ ExceptionTracker* ExceptionTracker::GetOrCreateTracker( } } } - -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - if (fCreateNewTracker) - { - // Exception tracker should be in the 2nd pass right now - _ASSERTE(!pTracker->IsInFirstPass()); - - // The corruption severity of a newly created tracker is NotSet - _ASSERTE(pTracker->GetCorruptionSeverity() == NotSet); - - // See comment in CEHelper::SetupCorruptionSeverityForActiveExceptionInUnwindPass for details - CEHelper::SetupCorruptionSeverityForActiveExceptionInUnwindPass(pThread, pTracker, FALSE, pExceptionRecord->ExceptionCode); - } -#endif // FEATURE_CORRUPTING_EXCEPTIONS } _ASSERTE(pTracker->m_pLimitFrame >= pThread->GetFrame()); @@ -4776,20 +4712,6 @@ VOID DECLSPEC_NORETURN DispatchManagedException(PAL_SEHException& ex, bool isHar ThreadExceptionState * pCurTES = pCurThread->GetExceptionState(); _ASSERTE(pCurTES != NULL); - -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - ExceptionTracker* pEHTracker = pCurTES->GetCurrentExceptionTracker(); - if (pEHTracker == NULL) - { - CorruptionSeverity severity = NotCorrupting; - if (CEHelper::IsProcessCorruptedStateException(ex.GetExceptionRecord()->ExceptionCode)) - { - severity = ProcessCorrupting; - } - - pCurTES->SetLastActiveExceptionCorruptionSeverity(severity); - } -#endif // FEATURE_CORRUPTING_EXCEPTIONS } throw std::move(ex); diff --git a/src/coreclr/src/vm/exceptionhandling.h b/src/coreclr/src/vm/exceptionhandling.h index 2f56f20340e775..dfdaf49726edcb 100644 --- a/src/coreclr/src/vm/exceptionhandling.h +++ b/src/coreclr/src/vm/exceptionhandling.h @@ -70,11 +70,6 @@ class ExceptionTracker m_WatsonBucketTracker.Init(); #endif // !TARGET_UNIX -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // Initialize the default exception severity to NotCorrupting - m_CorruptionSeverity = NotSet; -#endif // FEATURE_CORRUPTING_EXCEPTIONS - // By default, mark the tracker as not having delivered the first // chance exception notification m_fDeliveredFirstChanceNotification = FALSE; @@ -130,11 +125,6 @@ class ExceptionTracker m_WatsonBucketTracker.Init(); #endif // !TARGET_UNIX -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // Initialize the default exception severity to NotCorrupting - m_CorruptionSeverity = NotSet; -#endif // FEATURE_CORRUPTING_EXCEPTIONS - // By default, mark the tracker as not having delivered the first // chance exception notification m_fDeliveredFirstChanceNotification = FALSE; @@ -586,25 +576,6 @@ class ExceptionTracker } #endif // !TARGET_UNIX -#ifdef FEATURE_CORRUPTING_EXCEPTIONS -private: - CorruptionSeverity m_CorruptionSeverity; -public: - inline CorruptionSeverity GetCorruptionSeverity() - { - LIMITED_METHOD_CONTRACT; - - return (CorruptionSeverity)GET_CORRUPTION_SEVERITY(m_CorruptionSeverity); - } - - inline void SetCorruptionSeverity(CorruptionSeverity severityToSet) - { - LIMITED_METHOD_CONTRACT; - - m_CorruptionSeverity = severityToSet; - } -#endif // FEATURE_CORRUPTING_EXCEPTIONS - private: BOOL m_fDeliveredFirstChanceNotification; diff --git a/src/coreclr/src/vm/exceptmacros.h b/src/coreclr/src/vm/exceptmacros.h index 55bfec8f28ca38..31fb8c73cdf713 100644 --- a/src/coreclr/src/vm/exceptmacros.h +++ b/src/coreclr/src/vm/exceptmacros.h @@ -246,38 +246,6 @@ LONG WINAPI CLRVectoredExceptionHandler(PEXCEPTION_POINTERS pExceptionInfo); // Actual UEF worker prototype for use by GCUnhandledExceptionFilter. extern LONG InternalUnhandledExceptionFilter_Worker(PEXCEPTION_POINTERS pExceptionInfo); -//========================================================================== -// Installs a handler to unwind exception frames, but not catch the exception -//========================================================================== - -#ifdef FEATURE_CORRUPTING_EXCEPTIONS -// ----------------------------------------------------------------------- -// Support for Corrupted State Exceptions -// ----------------------------------------------------------------------- -// This enumeration defines the corruption severity of an exception and -// whether it should be reused for the next exception thrown or not. -enum CorruptionSeverity -{ - UseLast = 0x0, // When specified, the last active corruption severity from TES should be used - NotSet = 0x1, // Corruption Severity has not been set - this is the default/reset value - NotCorrupting = 0x2, // Indicates exception is not corrupting - ProcessCorrupting = 0x4, // Indicates exception represents process corrupted state - ReuseForReraise = 0x2000 // Indicates that the corruption severity should be reused for the next exception thrown, - // provided its not nested and isnt a rethrow. This flag is used typically for propagation of - // severity across boundaries like Reflection invocation, AD transition etc. -}; - -#define GET_CORRUPTION_SEVERITY(severity) (((severity) & (~ReuseForReraise))) -#define CAN_REUSE_CORRUPTION_SEVERITY(severity) (((severity) & ReuseForReraise) == ReuseForReraise) - -#endif // FEATURE_CORRUPTING_EXCEPTIONS - -VOID DECLSPEC_NORETURN RaiseTheException(OBJECTREF throwable, BOOL rethrow -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , CorruptionSeverity severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS -); - VOID DECLSPEC_NORETURN RaiseTheExceptionInternalOnly(OBJECTREF throwable, BOOL rethrow, BOOL fForStackOverflow = FALSE); #if defined(DACCESS_COMPILE) || defined(CROSSGEN_COMPILE) diff --git a/src/coreclr/src/vm/exinfo.cpp b/src/coreclr/src/vm/exinfo.cpp index 8a9ed80d257f5c..58e353a0160167 100644 --- a/src/coreclr/src/vm/exinfo.cpp +++ b/src/coreclr/src/vm/exinfo.cpp @@ -110,11 +110,6 @@ void ExInfo::Init() DestroyExceptionHandle(); m_hThrowable = NULL; -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // Initialize the default exception severity to NotCorrupting - m_CorruptionSeverity = NotSet; -#endif // FEATURE_CORRUPTING_EXCEPTIONS - // By default, mark the tracker as not having delivered the first // chance exception notification m_fDeliveredFirstChanceNotification = FALSE; diff --git a/src/coreclr/src/vm/exinfo.h b/src/coreclr/src/vm/exinfo.h index 5e57e0ce77ae88..332d2248342abe 100644 --- a/src/coreclr/src/vm/exinfo.h +++ b/src/coreclr/src/vm/exinfo.h @@ -90,25 +90,6 @@ class ExInfo } #endif -#ifdef FEATURE_CORRUPTING_EXCEPTIONS -private: - CorruptionSeverity m_CorruptionSeverity; -public: - inline CorruptionSeverity GetCorruptionSeverity() - { - LIMITED_METHOD_CONTRACT; - - return (CorruptionSeverity)GET_CORRUPTION_SEVERITY(m_CorruptionSeverity); - } - - inline void SetCorruptionSeverity(CorruptionSeverity severityToSet) - { - LIMITED_METHOD_CONTRACT; - - m_CorruptionSeverity = severityToSet; - } -#endif // FEATURE_CORRUPTING_EXCEPTIONS - private: BOOL m_fDeliveredFirstChanceNotification; public: diff --git a/src/coreclr/src/vm/exstate.cpp b/src/coreclr/src/vm/exstate.cpp index c2c2c0adb63f4a..db238df8bafe1b 100644 --- a/src/coreclr/src/vm/exstate.cpp +++ b/src/coreclr/src/vm/exstate.cpp @@ -43,13 +43,6 @@ ThreadExceptionState::ThreadExceptionState() // Init the UE Watson BucketTracker m_UEWatsonBucketTracker.Init(); #endif // !TARGET_UNIX - -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // Initialize the default exception severity to NotCorrupting - m_LastActiveExceptionCorruptionSeverity = NotSet; - m_fCanReflectionTargetHandleException = FALSE; -#endif // FEATURE_CORRUPTING_EXCEPTIONS - } ThreadExceptionState::~ThreadExceptionState() diff --git a/src/coreclr/src/vm/exstate.h b/src/coreclr/src/vm/exstate.h index 1ea8790a11dc10..e3971d356b5a7a 100644 --- a/src/coreclr/src/vm/exstate.h +++ b/src/coreclr/src/vm/exstate.h @@ -162,56 +162,6 @@ class ThreadExceptionState } #endif -#ifdef FEATURE_CORRUPTING_EXCEPTIONS -private: - CorruptionSeverity m_LastActiveExceptionCorruptionSeverity; - BOOL m_fCanReflectionTargetHandleException; - -public: - // Returns the corruption severity of the last active exception - inline CorruptionSeverity GetLastActiveExceptionCorruptionSeverity() - { - LIMITED_METHOD_CONTRACT; - - return (CorruptionSeverity)GET_CORRUPTION_SEVERITY(m_LastActiveExceptionCorruptionSeverity); - } - - // Set the corruption severity of the last active exception - inline void SetLastActiveExceptionCorruptionSeverity(CorruptionSeverity severityToSet) - { - LIMITED_METHOD_CONTRACT; - - m_LastActiveExceptionCorruptionSeverity = severityToSet; - } - - // Returns a bool indicating if the last active exception's corruption severity should - // be used when exception is reraised (e.g. Reflection Invocation, AD transition, etc) - inline BOOL ShouldLastActiveExceptionCorruptionSeverityBeReused() - { - LIMITED_METHOD_CONTRACT; - - return CAN_REUSE_CORRUPTION_SEVERITY(m_LastActiveExceptionCorruptionSeverity); - } - - // Returns a BOOL to indicate if reflection target can handle CSE or not. - // This is used in DispatchInfo::CanIDispatchTargetHandleException. - inline BOOL CanReflectionTargetHandleException() - { - LIMITED_METHOD_CONTRACT; - - return m_fCanReflectionTargetHandleException; - } - - // Sets a BOOL indicate if the Reflection invocation target can handle exception or not. - // Used in ReflectionInvocation.cpp. - inline void SetCanReflectionTargetHandleException(BOOL fCanReflectionTargetHandleException) - { - LIMITED_METHOD_CONTRACT; - - m_fCanReflectionTargetHandleException = fCanReflectionTargetHandleException; - } -#endif // FEATURE_CORRUPTING_EXCEPTIONS - private: ThreadExceptionFlag m_flag; diff --git a/src/coreclr/src/vm/frames.h b/src/coreclr/src/vm/frames.h index 5c8a1ca869d74f..3437030705f18d 100644 --- a/src/coreclr/src/vm/frames.h +++ b/src/coreclr/src/vm/frames.h @@ -742,11 +742,7 @@ class Frame : public FrameBase friend class StackFrameIterator; friend class TailCallFrame; friend class AppDomain; - friend VOID RealCOMPlusThrow(OBJECTREF -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , CorruptionSeverity severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ); + friend VOID RealCOMPlusThrow(OBJECTREF); friend FCDECL0(VOID, JIT_StressGC); #ifdef _DEBUG friend LONG WINAPI CLRVectoredExceptionHandlerShim(PEXCEPTION_POINTERS pExceptionInfo); diff --git a/src/coreclr/src/vm/i386/excepx86.cpp b/src/coreclr/src/vm/i386/excepx86.cpp index 5b333e9f9857e1..a89e7159566926 100644 --- a/src/coreclr/src/vm/i386/excepx86.cpp +++ b/src/coreclr/src/vm/i386/excepx86.cpp @@ -1065,18 +1065,11 @@ CPFH_RealFirstPassHandler( // ExceptionContinueSearch, etc. GCPROTECT_BEGIN(throwable); throwable = pThread->GetThrowable(); -#ifdef FEATURE_CORRUPTING_EXCEPTIONS + if (IsProcessCorruptedStateException(exceptionCode, throwable)) { - // Setup the state in current exception tracker indicating the corruption severity - // of the active exception. - CEHelper::SetupCorruptionSeverityForActiveException(bRethrownException, bNestedException, - CEHelper::ShouldTreatActiveExceptionAsNonCorrupting()); - // Failfast if exception indicates corrupted process state - if (pExInfo->GetCorruptionSeverity() == ProcessCorrupting) - EEPOLICY_HANDLE_FATAL_ERROR(exceptionCode); + EEPOLICY_HANDLE_FATAL_ERROR(exceptionCode); } -#endif // FEATURE_CORRUPTING_EXCEPTIONS // If we're out of memory, then we figure there's probably not memory to maintain a stack trace, so we skip it. // If we've got a stack overflow, then we figure the stack will be so huge as to make tracking the stack trace @@ -1392,10 +1385,6 @@ CPFH_UnwindFrames1(Thread* pThread, EXCEPTION_REGISTRATION_RECORD* pEstablisherF tct.pTopFrame = GetCurrFrame(pEstablisherFrame); // highest frame to search to tct.pBottomFrame = NULL; - // Set the flag indicating if the current exception represents a longjmp. - // See comment in COMPlusUnwindCallback for details. - CORRUPTING_EXCEPTIONS_ONLY(tct.m_fIsLongJump = (exceptionCode == STATUS_LONGJUMP);) - #ifdef _DEBUG tct.pCurrentExceptionRecord = pEstablisherFrame; tct.pPrevExceptionRecord = GetPrevSEHRecord(pEstablisherFrame); @@ -2366,20 +2355,6 @@ StackWalkAction COMPlusThrowCallback( // SWA value if (fIsILStub) pUserMDForILStub = GetUserMethodForILStub(pThread, currentSP, pFunc, &pILStubFrame); -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - CorruptionSeverity currentSeverity = pThread->GetExceptionState()->GetCurrentExceptionTracker()->GetCorruptionSeverity(); - { - // We must defer to the MethodDesc of the user method instead of the IL stub - // itself because the user can specify the policy on a per-method basis and - // that won't be reflected via the IL stub's MethodDesc. - MethodDesc * pMDWithCEAttribute = fIsILStub ? pUserMDForILStub : pFunc; - - // Check if the exception can be delivered to the method? It will check if the exception - // is a CE or not. If it is, it will check if the method can process it or not. - fMethodCanHandleException = CEHelper::CanMethodHandleException(currentSeverity, pMDWithCEAttribute); - } -#endif // FEATURE_CORRUPTING_EXCEPTIONS - // Let the profiler know that we are searching for a handler within this function instance if (fGiveDebuggerAndProfilerNotification) EEToProfilerExceptionInterfaceWrapper::ExceptionSearchFunctionEnter(pFunc); @@ -2406,29 +2381,12 @@ StackWalkAction COMPlusThrowCallback( // SWA value ExceptionNotifications::DeliverFirstChanceNotification(); } } + IJitManager* pJitManager = pCf->GetJitManager(); _ASSERTE(pJitManager); - EH_CLAUSE_ENUMERATOR pEnumState; - unsigned EHCount = 0; - -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // If exception cannot be handled, then just bail out. We shouldnt examine the EH clauses - // in such a method. - if (!fMethodCanHandleException) - { - LOG((LF_EH, LL_INFO100, "COMPlusThrowCallback - CEHelper decided not to look for exception handlers in the method(MD:%p).\n", pFunc)); - // Set the flag to skip this frame since the CE cannot be delivered - _ASSERTE(currentSeverity == ProcessCorrupting); - - // Ensure EHClause count is zero - EHCount = 0; - } - else -#endif // FEATURE_CORRUPTING_EXCEPTIONS - { - EHCount = pJitManager->InitializeEHEnumeration(pCf->GetMethodToken(), &pEnumState); - } + EH_CLAUSE_ENUMERATOR pEnumState; + unsigned EHCount = pJitManager->InitializeEHEnumeration(pCf->GetMethodToken(), &pEnumState); if (EHCount == 0) { @@ -2708,59 +2666,6 @@ StackWalkAction COMPlusUnwindCallback (CrawlFrame *pCf, ThrowCallbackType *pData TypeHandle thrownType = TypeHandle(); - BOOL fCanMethodHandleException = TRUE; -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // MethodDesc's security information (i.e. whether it is critical or transparent) is calculated lazily. - // If this method's security information was not precalculated, then it would have been in the first pass - // already using Security::IsMethodCritical which could take have taken us down a path which is GC_TRIGGERS. - // - // - // However, this unwind callback (for X86) is GC_NOTRIGGER and at this point the security information would have been - // calculated already. Hence, we wouldnt endup in the GC_TRIGGERS path. Thus, to keep SCAN.EXE (static contract analyzer) happy, - // we will pass a FALSE to the CanMethodHandleException call, indicating we dont need to calculate security information (and thus, - // not go down the GC_TRIGGERS path. - // - // Check if the exception can be delivered to the method? It will check if the exception - // is a CE or not. If it is, it will check if the method can process it or not. - CorruptionSeverity currentSeverity = pThread->GetExceptionState()->GetCurrentExceptionTracker()->GetCorruptionSeverity(); - - // We have to do this check for x86 since, unlike 64bit which will setup a new exception tracker for longjmp, - // x86 only sets up new trackers in the first pass (and longjmp is 2nd pass only exception). Hence, we pass - // this information in the callback structure without affecting any existing exception tracker (incase longjmp was - // a nested exception). - if (pData->m_fIsLongJump) - { - // Longjump is not a CSE. With a CSE in progress, this can be invoked by either: - // - // 1) Managed code (e.g. finally/fault/catch), OR - // 2) By native code - // - // In scenario (1), managed code can invoke it only if it was attributed with HPCSE attribute. Thus, - // longjmp is no different than managed code doing a "throw new Exception();". - // - // In scenario (2), longjmp is no different than any other non-CSE native exception raised. - // - // In both these case, longjmp should be treated as non-CSE. Since x86 does not setup a tracker for - // it (see comment above), we pass this information (of whether the current exception is a longjmp or not) - // to this callback (from UnwindFrames) to setup the correct corruption severity. - // - // http://www.nynaeve.net/?p=105 has a brief description of how exception-safe setjmp/longjmp works. - currentSeverity = NotCorrupting; - } - { - MethodDesc * pFuncWithCEAttribute = pFunc; - Frame * pILStubFrame = NULL; - if (pFunc->IsILStub()) - { - // We must defer to the MethodDesc of the user method instead of the IL stub - // itself because the user can specify the policy on a per-method basis and - // that won't be reflected via the IL stub's MethodDesc. - pFuncWithCEAttribute = GetUserMethodForILStub(pThread, (UINT_PTR)pStack, pFunc, &pILStubFrame); - } - fCanMethodHandleException = CEHelper::CanMethodHandleException(currentSeverity, pFuncWithCEAttribute); - } -#endif // FEATURE_CORRUPTING_EXCEPTIONS - #ifdef DEBUGGING_SUPPORTED LOG((LF_EH, LL_INFO1000, "COMPlusUnwindCallback: Intercept %d, pData->pFunc 0x%X, pFunc 0x%X, pData->pStack 0x%X, pStack 0x%X\n", pExInfo->m_ExceptionFlags.DebuggerInterceptInfo(), @@ -2786,24 +2691,7 @@ StackWalkAction COMPlusUnwindCallback (CrawlFrame *pCf, ThrowCallbackType *pData EEToProfilerExceptionInterfaceWrapper::ExceptionUnwindFunctionEnter(pFunc); EH_CLAUSE_ENUMERATOR pEnumState; - unsigned EHCount; - -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - if (!fCanMethodHandleException) - { - LOG((LF_EH, LL_INFO100, "COMPlusUnwindCallback - CEHelper decided not to look for exception handlers in the method(MD:%p).\n", pFunc)); - - // Set the flag to skip this frame since the CE cannot be delivered - _ASSERTE(currentSeverity == ProcessCorrupting); - - // Force EHClause count to be zero - EHCount = 0; - } - else -#endif // FEATURE_CORRUPTING_EXCEPTIONS - { - EHCount = pJitManager->InitializeEHEnumeration(pCf->GetMethodToken(), &pEnumState); - } + unsigned EHCount = pJitManager->InitializeEHEnumeration(pCf->GetMethodToken(), &pEnumState); if (EHCount == 0) { diff --git a/src/coreclr/src/vm/interopconverter.cpp b/src/coreclr/src/vm/interopconverter.cpp index 64312e14382146..2c67182df9bd3c 100644 --- a/src/coreclr/src/vm/interopconverter.cpp +++ b/src/coreclr/src/vm/interopconverter.cpp @@ -80,7 +80,7 @@ namespace //-------------------------------------------------------------------------------- // IUnknown *GetComIPFromObjectRef(OBJECTREF *poref, MethodTable *pMT, ...) // Convert ObjectRef to a COM IP, based on MethodTable* pMT. -IUnknown *GetComIPFromObjectRef(OBJECTREF *poref, MethodTable *pMT, BOOL bSecurityCheck, BOOL bEnableCustomizedQueryInterface) +IUnknown *GetComIPFromObjectRef(OBJECTREF *poref, MethodTable *pMT, BOOL bEnableCustomizedQueryInterface) { CONTRACT (IUnknown*) { @@ -119,7 +119,6 @@ IUnknown *GetComIPFromObjectRef(OBJECTREF *poref, MethodTable *pMT, BOOL bSecuri CCWHolder pCCWHold = ComCallWrapper::InlineGetWrapper(poref); GetComIPFromCCW::flags flags = GetComIPFromCCW::None; - if (!bSecurityCheck) { flags |= GetComIPFromCCW::SuppressSecurityCheck; } if (!bEnableCustomizedQueryInterface) { flags |= GetComIPFromCCW::SuppressCustomizedQueryInterface; } pUnk = ComCallWrapper::GetComIPFromCCW(pCCWHold, GUID_NULL, pMT, flags); diff --git a/src/coreclr/src/vm/interopconverter.h b/src/coreclr/src/vm/interopconverter.h index ad6b9a0004d135..a41c169b716b50 100644 --- a/src/coreclr/src/vm/interopconverter.h +++ b/src/coreclr/src/vm/interopconverter.h @@ -113,7 +113,7 @@ enum ComIpType //-------------------------------------------------------------------------------- // IUnknown *GetComIPFromObjectRef(OBJECTREF *poref, MethodTable *pMT, ...); // Convert ObjectRef to a COM IP, based on MethodTable* pMT. -IUnknown *GetComIPFromObjectRef(OBJECTREF *poref, MethodTable *pMT, BOOL bSecurityCheck = TRUE, BOOL bEnableCustomizedQueryInterface = TRUE); +IUnknown *GetComIPFromObjectRef(OBJECTREF *poref, MethodTable *pMT, BOOL bEnableCustomizedQueryInterface = TRUE); //-------------------------------------------------------------------------------- diff --git a/src/coreclr/src/vm/jithelpers.cpp b/src/coreclr/src/vm/jithelpers.cpp index 8e5d20d993ff6a..38a6af10e6dfa7 100644 --- a/src/coreclr/src/vm/jithelpers.cpp +++ b/src/coreclr/src/vm/jithelpers.cpp @@ -4185,23 +4185,6 @@ HCIMPL1(void, IL_Throw, Object* obj) } } -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - if (!g_pConfig->LegacyCorruptedStateExceptionsPolicy()) - { - // Within the VM, we could have thrown and caught a managed exception. This is done by - // RaiseTheException that will flag that exception's corruption severity to be used - // incase it leaks out to managed code. - // - // If it does not leak out, but ends up calling into managed code that throws, - // we will come here. In such a case, simply reset the corruption-severity - // since we want the exception being thrown to have its correct severity set - // when CLR's managed code exception handler sets it. - - ThreadExceptionState *pExState = GetThread()->GetExceptionState(); - pExState->SetLastActiveExceptionCorruptionSeverity(NotSet); - } -#endif // FEATURE_CORRUPTING_EXCEPTIONS - RaiseTheExceptionInternalOnly(oref, FALSE); HELPER_METHOD_FRAME_END(); diff --git a/src/coreclr/src/vm/listlock.h b/src/coreclr/src/vm/listlock.h index 0fdaf6e68c91c6..2b135b19d784bc 100644 --- a/src/coreclr/src/vm/listlock.h +++ b/src/coreclr/src/vm/listlock.h @@ -55,10 +55,6 @@ class ListLockEntryBase HRESULT m_hrResultCode; LOADERHANDLE m_hInitException; PTR_LoaderAllocator m_pLoaderAllocator; -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // Field to maintain the corruption severity of the exception - CorruptionSeverity m_CorruptionSeverity; -#endif // FEATURE_CORRUPTING_EXCEPTIONS ListLockEntryBase(List_t *pList, ELEMENT data, const char *description = NULL) : m_deadlock(description), @@ -72,10 +68,6 @@ class ListLockEntryBase m_hrResultCode(S_FALSE), m_hInitException(NULL), m_pLoaderAllocator(dac_cast(nullptr)) -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , - m_CorruptionSeverity(NotCorrupting) -#endif // FEATURE_CORRUPTING_EXCEPTIONS { WRAPPER_NO_CONTRACT; } diff --git a/src/coreclr/src/vm/marshalnative.cpp b/src/coreclr/src/vm/marshalnative.cpp index 56657944eb8a5e..2e068019c2ab27 100644 --- a/src/coreclr/src/vm/marshalnative.cpp +++ b/src/coreclr/src/vm/marshalnative.cpp @@ -923,7 +923,7 @@ FCIMPL4(IUnknown*, MarshalNative::GetComInterfaceForObjectNative, Object* orefUN if (fOnlyInContext && !IsObjectInContext(&oref)) retVal = NULL; else - retVal = GetComIPFromObjectRef(&oref, th.GetMethodTable(), TRUE, bEnableCustomizedQueryInterface); + retVal = GetComIPFromObjectRef(&oref, th.GetMethodTable(), bEnableCustomizedQueryInterface); HELPER_METHOD_FRAME_END(); return retVal; diff --git a/src/coreclr/src/vm/methodtable.cpp b/src/coreclr/src/vm/methodtable.cpp index 1706f0c327c4e4..60925514bb7152 100644 --- a/src/coreclr/src/vm/methodtable.cpp +++ b/src/coreclr/src/vm/methodtable.cpp @@ -3123,39 +3123,6 @@ BOOL MethodTable::RunClassInitEx(OBJECTREF *pThrowable) // a subclass of Error *pThrowable = GET_THROWABLE(); _ASSERTE(fRet == FALSE); - -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // If active thread state does not have a CorruptionSeverity set for the exception, - // then set one up based upon the current exception code and/or the throwable. - // - // When can we be here and current exception tracker may not have corruption severity set? - // Incase of SO in managed code, SO is never seen by CLR's exception handler for managed code - // and if this happens in cctor, we can end up here without the corruption severity set. - Thread *pThread = GetThread(); - _ASSERTE(pThread != NULL); - ThreadExceptionState *pCurTES = pThread->GetExceptionState(); - _ASSERTE(pCurTES != NULL); - if (pCurTES->GetLastActiveExceptionCorruptionSeverity() == NotSet) - { - if (CEHelper::IsProcessCorruptedStateException(GetCurrentExceptionCode()) || - CEHelper::IsProcessCorruptedStateException(*pThrowable)) - { - // Process Corrupting - pCurTES->SetLastActiveExceptionCorruptionSeverity(ProcessCorrupting); - LOG((LF_EH, LL_INFO100, "MethodTable::RunClassInitEx - Exception treated as ProcessCorrupting.\n")); - } - else - { - // Not Corrupting - pCurTES->SetLastActiveExceptionCorruptionSeverity(NotCorrupting); - LOG((LF_EH, LL_INFO100, "MethodTable::RunClassInitEx - Exception treated as non-corrupting.\n")); - } - } - else - { - LOG((LF_EH, LL_INFO100, "MethodTable::RunClassInitEx - Exception already has corruption severity set.\n")); - } -#endif // FEATURE_CORRUPTING_EXCEPTIONS } EX_END_CATCH(SwallowAllExceptions) @@ -3289,17 +3256,7 @@ void MethodTable::DoRunClassInitThrowing() ((EXCEPTIONREF)(gc.pThrowable))->ClearStackTraceForThrow(); } - // - // Specify the corruption severity to be used to raise this exception in COMPlusThrow below. - // This will ensure that when the exception is seen by the managed code personality routine, - // it will setup the correct corruption severity in the exception tracker. - // - - COMPlusThrow(gc.pThrowable -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , pEntry->m_CorruptionSeverity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ); + COMPlusThrow(gc.pThrowable); } description = ".cctor lock"; @@ -3389,21 +3346,7 @@ void MethodTable::DoRunClassInitThrowing() pEntry->m_hrResultCode = E_FAIL; SetClassInitError(); - #ifdef FEATURE_CORRUPTING_EXCEPTIONS - // Save the corruption severity of the exception so that if the type system - // attempts to pick it up from its cache list and throw again, it should - // treat the exception as corrupting, if applicable. - pEntry->m_CorruptionSeverity = pThread->GetExceptionState()->GetLastActiveExceptionCorruptionSeverity(); - - // We should be having a valid corruption severity at this point - _ASSERTE(pEntry->m_CorruptionSeverity != NotSet); - #endif // FEATURE_CORRUPTING_EXCEPTIONS - - COMPlusThrow(gc.pThrowable - #ifdef FEATURE_CORRUPTING_EXCEPTIONS - , pEntry->m_CorruptionSeverity - #endif // FEATURE_CORRUPTING_EXCEPTIONS - ); + COMPlusThrow(gc.pThrowable); } GCPROTECT_END(); diff --git a/src/coreclr/src/vm/rcwwalker.cpp b/src/coreclr/src/vm/rcwwalker.cpp index 5c94a3ea536909..e10da3f46a133f 100644 --- a/src/coreclr/src/vm/rcwwalker.cpp +++ b/src/coreclr/src/vm/rcwwalker.cpp @@ -570,7 +570,7 @@ void RCWWalker::WalkRCWs() { hr = GET_EXCEPTION()->GetHR(); } - EX_END_CATCH(RethrowCorruptingExceptions) // Make sure we crash on AV (instead of swallowing everything) + EX_END_CATCH(RethrowTerminalExceptions) if (FAILED(hr)) { diff --git a/src/coreclr/src/vm/reflectioninvocation.cpp b/src/coreclr/src/vm/reflectioninvocation.cpp index 2724de4771b1fa..b604b1a52d9133 100644 --- a/src/coreclr/src/vm/reflectioninvocation.cpp +++ b/src/coreclr/src/vm/reflectioninvocation.cpp @@ -882,15 +882,6 @@ void DECLSPEC_NORETURN ThrowInvokeMethodException(MethodDesc * pMethod, OBJECTRE } #endif // _DEBUG && !TARGET_UNIX -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // Get the corruption severity of the exception that came in through reflection invocation. - CorruptionSeverity severity = GetThread()->GetExceptionState()->GetLastActiveExceptionCorruptionSeverity(); - - // Since we are dealing with an exception, set the flag indicating if the target of Reflection can handle exception or not. - // This flag is used in CEHelper::CanIDispatchTargetHandleException. - GetThread()->GetExceptionState()->SetCanReflectionTargetHandleException(CEHelper::CanMethodHandleException(severity, pMethod)); -#endif // FEATURE_CORRUPTING_EXCEPTIONS - OBJECTREF except = InvokeUtil::CreateTargetExcept(&targetException); #ifndef TARGET_UNIX @@ -944,11 +935,7 @@ void DECLSPEC_NORETURN ThrowInvokeMethodException(MethodDesc * pMethod, OBJECTRE // Since VM is throwing the exception, we set it to use the same corruption severity // that the original exception came in with from reflection invocation. - COMPlusThrow(except -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - , severity -#endif // FEATURE_CORRUPTING_EXCEPTIONS - ); + COMPlusThrow(except); GCPROTECT_END(); } @@ -1254,12 +1241,6 @@ FCIMPL5(Object*, RuntimeMethodHandle::InvokeMethod, ENDFORBIDGC(); } -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // By default, set the flag in TES indicating the reflection target can handle CSE. - // This flag is used in CEHelper::CanIDispatchTargetHandleException. - pThread->GetExceptionState()->SetCanReflectionTargetHandleException(TRUE); -#endif // FEATURE_CORRUPTING_EXCEPTIONS - if (pValueClasses != NULL) { pProtectValueClassFrame = new (_alloca (sizeof (FrameWithCookie))) diff --git a/src/coreclr/src/vm/stdinterfaces.cpp b/src/coreclr/src/vm/stdinterfaces.cpp index 7ca4975c326785..240bdc926bc3ee 100644 --- a/src/coreclr/src/vm/stdinterfaces.cpp +++ b/src/coreclr/src/vm/stdinterfaces.cpp @@ -1502,7 +1502,7 @@ InternalDispatchImpl_Invoke hr = pDispInfo->InvokeMember(pSimpleWrap, dispidMember, lcid, wFlags, pdispparams, pvarResult, pexcepinfo, NULL, puArgErr); } - END_EXTERNAL_ENTRYPOINT_RETHROW_CORRUPTING_EXCEPTIONS; // This will ensure that entry points wont swallow CE and continue to let them propagate out. + END_EXTERNAL_ENTRYPOINT; return hr; } diff --git a/src/coreclr/src/vm/threads.cpp b/src/coreclr/src/vm/threads.cpp index 19b318e58d598c..324c65d67ce8c4 100644 --- a/src/coreclr/src/vm/threads.cpp +++ b/src/coreclr/src/vm/threads.cpp @@ -4500,17 +4500,6 @@ void Thread::SyncManagedExceptionState(bool fIsDebuggerThread) // Syncup the LastThrownObject on the managed thread SafeUpdateLastThrownObject(); } - -#ifdef FEATURE_CORRUPTING_EXCEPTIONS - // Since the catch clause has successfully executed and we are exiting it, reset the corruption severity - // in the ThreadExceptionState for the last active exception. This will ensure that when the next exception - // gets thrown/raised, EH tracker wont pick up an invalid value. - if (!fIsDebuggerThread) - { - CEHelper::ResetLastActiveCorruptionSeverityPostCatchHandler(this); - } -#endif // FEATURE_CORRUPTING_EXCEPTIONS - } void Thread::SetLastThrownObjectHandle(OBJECTHANDLE h)