diff options
author | Koundinya Veluri <kouvel@microsoft.com> | 2017-03-27 22:38:53 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-03-27 22:38:53 -0700 |
commit | 54b2c88f5a8c4623a4a465218a9cef94b92642bf (patch) | |
tree | 938bd5dcdbe8720f01cab4d911221bdc639e45c6 /src/vm/comdelegate.cpp | |
parent | 440a2871f11d75defe58edd1bf8b535edfd17b42 (diff) | |
download | coreclr-54b2c88f5a8c4623a4a465218a9cef94b92642bf.tar.gz coreclr-54b2c88f5a8c4623a4a465218a9cef94b92642bf.tar.bz2 coreclr-54b2c88f5a8c4623a4a465218a9cef94b92642bf.zip |
Don't ignore exceptions thrown from handlers of some events (#10502)
Fixes dotnet/corefx#14747:
- Events include: AssemblyLoadContext.Unloading, AppDomain.ProcessExit
- Made the same change for AppDomain.DomainUnload for consistency, but it's not raised
Diffstat (limited to 'src/vm/comdelegate.cpp')
-rw-r--r-- | src/vm/comdelegate.cpp | 139 |
1 files changed, 39 insertions, 100 deletions
diff --git a/src/vm/comdelegate.cpp b/src/vm/comdelegate.cpp index 075c473285..20ae6953b8 100644 --- a/src/vm/comdelegate.cpp +++ b/src/vm/comdelegate.cpp @@ -3960,55 +3960,12 @@ static void InvokeUnhandledSwallowing(OBJECTREF *pDelegate, } -// cannot combine SEH & C++ exceptions in one method. Split out from InvokeNotify. -static void InvokeNotifyInner(OBJECTREF *pDelegate, OBJECTREF *pDomain) -{ - // static contract, since we use SEH. - STATIC_CONTRACT_GC_TRIGGERS; - STATIC_CONTRACT_THROWS; - STATIC_CONTRACT_MODE_COOPERATIVE; - - _ASSERTE(pDelegate != NULL && IsProtectedByGCFrame(pDelegate)); - _ASSERTE(pDomain != NULL && IsProtectedByGCFrame(pDomain)); - - struct Param : ThreadBaseExceptionFilterParam - { - OBJECTREF *pDelegate; - OBJECTREF *pDomain; - } param; - param.location = SystemNotification; - param.pDelegate = pDelegate; - param.pDomain = pDomain; - - PAL_TRY(Param *, pParam, ¶m) - { - PREPARE_NONVIRTUAL_CALLSITE_USING_CODE(DELEGATEREF(*pParam->pDelegate)->GetMethodPtr()); - - DECLARE_ARGHOLDER_ARRAY(args, 3); - - args[ARGNUM_0] = OBJECTREF_TO_ARGHOLDER(DELEGATEREF(*pParam->pDelegate)->GetTarget()); - args[ARGNUM_1] = OBJECTREF_TO_ARGHOLDER(*pParam->pDomain); - args[ARGNUM_2] = NULL; - - CALL_MANAGED_METHOD_NORET(args); - } - PAL_EXCEPT_FILTER(ThreadBaseExceptionFilter) - { - _ASSERTE(!"ThreadBaseExceptionFilter returned EXECUTE_HANDLER."); - } - PAL_ENDTRY; -} - - - -// Helper to dispatch a single event notification. If anything goes wrong, we cause -// an unhandled exception notification to occur out of our first pass, and then we -// swallow and continue. +// Helper to dispatch a single event notification. static void InvokeNotify(OBJECTREF *pDelegate, OBJECTREF *pDomain) { CONTRACTL { - NOTHROW; + THROWS; GC_TRIGGERS; MODE_COOPERATIVE; } @@ -4030,19 +3987,15 @@ static void InvokeNotify(OBJECTREF *pDelegate, OBJECTREF *pDomain) _ASSERTE(!pThread->HasCriticalRegion()); _ASSERTE(!pThread->HasThreadAffinity()); - EX_TRY - { - InvokeNotifyInner(pDelegate, pDomain); - } - EX_CATCH - { - // It's not even worth asserting, because these aren't our bugs. At - // some point, a MDA may be warranted. - // This is an early check for condition that we assert in Thread::InternalReset called from DoOneFinalization later. - _ASSERTE(!pThread->HasCriticalRegion()); - _ASSERTE(!pThread->HasThreadAffinity()); - } - EX_END_CATCH(SwallowAllExceptions) + PREPARE_NONVIRTUAL_CALLSITE_USING_CODE(DELEGATEREF(*pDelegate)->GetMethodPtr()); + + DECLARE_ARGHOLDER_ARRAY(args, 3); + + args[ARGNUM_0] = OBJECTREF_TO_ARGHOLDER(DELEGATEREF(*pDelegate)->GetTarget()); + args[ARGNUM_1] = OBJECTREF_TO_ARGHOLDER(*pDomain); + args[ARGNUM_2] = NULL; + + CALL_MANAGED_METHOD_NORET(args); // This is an early check for condition that we assert in Thread::InternalReset called from DoOneFinalization later. _ASSERTE(!pThread->HasCriticalRegion()); @@ -4050,16 +4003,11 @@ static void InvokeNotify(OBJECTREF *pDelegate, OBJECTREF *pDomain) } -// For critical system events, ensure that each handler gets a notification -- -// even if prior handlers in the chain have thrown an exception. Also, try -// to deliver an unhandled exception event if we ever swallow an exception -// out of a reliable notification. Note that the add_ event handers are -// responsible for any reliable preparation of the target, like eager JITting. -void DistributeEventReliably(OBJECTREF *pDelegate, OBJECTREF *pDomain) +void DistributeEvent(OBJECTREF *pDelegate, OBJECTREF *pDomain) { CONTRACTL { - NOTHROW; + THROWS; GC_TRIGGERS; MODE_COOPERATIVE; } @@ -4070,51 +4018,42 @@ void DistributeEventReliably(OBJECTREF *pDelegate, OBJECTREF *pDomain) Thread *pThread = GetThread(); - EX_TRY + struct _gc { - struct _gc - { - PTRARRAYREF Array; - OBJECTREF InnerDelegate; - } gc; - ZeroMemory(&gc, sizeof(gc)); + PTRARRAYREF Array; + OBJECTREF InnerDelegate; + } gc; + ZeroMemory(&gc, sizeof(gc)); - GCPROTECT_BEGIN(gc); + GCPROTECT_BEGIN(gc); - gc.Array = (PTRARRAYREF) ((DELEGATEREF)(*pDelegate))->GetInvocationList(); - if (gc.Array == NULL || !gc.Array->GetMethodTable()->IsArray()) - { - InvokeNotify(pDelegate, pDomain); - } - else - { - // The _invocationCount could be less than the array size, if we are sharing - // immutable arrays cleverly. - INT_PTR invocationCount = ((DELEGATEREF)(*pDelegate))->GetInvocationCount(); + gc.Array = (PTRARRAYREF) ((DELEGATEREF)(*pDelegate))->GetInvocationList(); + if (gc.Array == NULL || !gc.Array->GetMethodTable()->IsArray()) + { + InvokeNotify(pDelegate, pDomain); + } + else + { + // The _invocationCount could be less than the array size, if we are sharing + // immutable arrays cleverly. + INT_PTR invocationCount = ((DELEGATEREF)(*pDelegate))->GetInvocationCount(); - _ASSERTE(FitsInU4(invocationCount)); - DWORD cnt = static_cast<DWORD>(invocationCount); + _ASSERTE(FitsInU4(invocationCount)); + DWORD cnt = static_cast<DWORD>(invocationCount); - _ASSERTE(cnt <= gc.Array->GetNumComponents()); + _ASSERTE(cnt <= gc.Array->GetNumComponents()); - for (DWORD i=0; i<cnt; i++) + for (DWORD i=0; i<cnt; i++) + { + gc.InnerDelegate = gc.Array->m_Array[i]; + InvokeNotify(&gc.InnerDelegate, pDomain); + if (pThread->IsAbortRequested()) { - gc.InnerDelegate = gc.Array->m_Array[i]; - InvokeNotify(&gc.InnerDelegate, pDomain); - if (pThread->IsAbortRequested()) - { - pThread->UnmarkThreadForAbort(Thread::TAR_Thread); - } + pThread->UnmarkThreadForAbort(Thread::TAR_Thread); } } - GCPROTECT_END(); } - EX_CATCH - { - // It's not even worth asserting, because these aren't our bugs. At - // some point, a MDA may be warranted. - } - EX_END_CATCH(SwallowAllExceptions) + GCPROTECT_END(); } // The unhandled exception event is a little easier to distribute, because |