diff options
author | Jan Vorlicek <janvorli@microsoft.com> | 2015-09-08 13:23:13 +0200 |
---|---|---|
committer | Jan Vorlicek <janvorli@microsoft.com> | 2015-09-08 13:42:29 +0200 |
commit | 468666bc8bd0c58268187cea5749cef63479b30e (patch) | |
tree | 4627399a7dd80737b91bb5375d87d46faea78878 /src | |
parent | 1165038551b7ca20f230d867dc5fd2357ede14fe (diff) | |
download | coreclr-468666bc8bd0c58268187cea5749cef63479b30e.tar.gz coreclr-468666bc8bd0c58268187cea5749cef63479b30e.tar.bz2 coreclr-468666bc8bd0c58268187cea5749cef63479b30e.zip |
Fix managed exception dispatching
The managed exception dispatching is initiated from the UNINSTALL_MANAGED_EXCEPTION_DISPATCHER
macro and it should be used only at the border between managed and native code, when managed
code calls native one. This macro is part of the UNINSTALL_UNWIND_AND_CONTINUE_HANDLER_NO_PROBE
macro. However, it turns out that the UNINSTALL_UNWIND_AND_CONTINUE_HANDLER_NO_PROBE
(or the UNINSTALL_UNWIND_AND_CONTINUE_HANDLER that uses it) is also used at places where
there is no managed / native border. In that case, the managed dispatching results incorrectly
in skipping native frames that would otherwise handle the exception.
The fix removes the INSTALL_MANAGED_EXCEPTION_DISPATCHER / UNINSTALL_MANAGED_EXCEPTION_DISPATCHER
from the INSTALL_UNWIND_AND_CONTINUE_HANDLER_NO_PROBE / UNINSTALL_UNWIND_AND_CONTINUE_HANDLER_NO_PROBE
and puts them to specific places where INSTALL_UNWIND_AND_CONTINUE_HANDLER_NO_PROBE /
UNINSTALL_UNWIND_AND_CONTINUE_HANDLER_NO_PROBE and INSTALL_UNWIND_AND_CONTINUE_HANDLER /
UNINSTALL_UNWIND_AND_CONTINUE_HANDLER are used at the border between managed and native code.
Diffstat (limited to 'src')
-rw-r--r-- | src/vm/amd64/cgenamd64.cpp | 2 | ||||
-rw-r--r-- | src/vm/dllimport.cpp | 4 | ||||
-rw-r--r-- | src/vm/dllimportcallback.cpp | 4 | ||||
-rw-r--r-- | src/vm/exceptmacros.h | 3 | ||||
-rw-r--r-- | src/vm/fcall.h | 2 | ||||
-rw-r--r-- | src/vm/frames.cpp | 5 | ||||
-rw-r--r-- | src/vm/prestub.cpp | 6 | ||||
-rw-r--r-- | src/vm/virtualcallstub.cpp | 4 |
8 files changed, 24 insertions, 6 deletions
diff --git a/src/vm/amd64/cgenamd64.cpp b/src/vm/amd64/cgenamd64.cpp index 27f1a4a339..e9c1ad468b 100644 --- a/src/vm/amd64/cgenamd64.cpp +++ b/src/vm/amd64/cgenamd64.cpp @@ -866,6 +866,7 @@ EXTERN_C PCODE VirtualMethodFixupWorker(TransitionBlock * pTransitionBlock, CORC pEMFrame->SetFunction(pMD); // We will use the pMD to enumerate the GC refs in the arguments pEMFrame->Push(CURRENT_THREAD); + INSTALL_MANAGED_EXCEPTION_DISPATCHER; INSTALL_UNWIND_AND_CONTINUE_HANDLER_NO_PROBE; // Skip fixup precode jump for better perf @@ -892,6 +893,7 @@ EXTERN_C PCODE VirtualMethodFixupWorker(TransitionBlock * pTransitionBlock, CORC } UNINSTALL_UNWIND_AND_CONTINUE_HANDLER_NO_PROBE; + UNINSTALL_MANAGED_EXCEPTION_DISPATCHER; pEMFrame->Pop(CURRENT_THREAD); } diff --git a/src/vm/dllimport.cpp b/src/vm/dllimport.cpp index a57353f65b..71842eef9c 100644 --- a/src/vm/dllimport.cpp +++ b/src/vm/dllimport.cpp @@ -7336,6 +7336,7 @@ EXTERN_C LPVOID STDCALL NDirectImportWorker(NDirectMethodDesc* pMD) } CONTRACTL_END; + INSTALL_MANAGED_EXCEPTION_DISPATCHER; // this function is called by CLR to native assembly stubs which are called by // managed code as a result, we need an unwind and continue handler to translate // any of our internal exceptions into managed exceptions. @@ -7392,6 +7393,7 @@ EXTERN_C LPVOID STDCALL NDirectImportWorker(NDirectMethodDesc* pMD) ret = pMD->GetNDirectTarget(); UNINSTALL_UNWIND_AND_CONTINUE_HANDLER; + UNINSTALL_MANAGED_EXCEPTION_DISPATCHER; END_PRESERVE_LAST_ERROR; @@ -7478,6 +7480,7 @@ PCODE GetILStubForCalli(VASigCookie *pVASigCookie, MethodDesc *pMD) PCODE pTempILStub = NULL; + INSTALL_MANAGED_EXCEPTION_DISPATCHER; // this function is called by CLR to native assembly stubs which are called by // managed code as a result, we need an unwind and continue handler to translate // any of our internal exceptions into managed exceptions. @@ -7576,6 +7579,7 @@ PCODE GetILStubForCalli(VASigCookie *pVASigCookie, MethodDesc *pMD) NULL); UNINSTALL_UNWIND_AND_CONTINUE_HANDLER; + UNINSTALL_MANAGED_EXCEPTION_DISPATCHER; RETURN pVASigCookie->pNDirectILStub; } diff --git a/src/vm/dllimportcallback.cpp b/src/vm/dllimportcallback.cpp index e3570ef129..0c4ac1784f 100644 --- a/src/vm/dllimportcallback.cpp +++ b/src/vm/dllimportcallback.cpp @@ -150,6 +150,7 @@ EXTERN_C void STDCALL UM2MDoADCallBack(UMEntryThunk *pEntryThunk, UM2MThunk_Args args = { pEntryThunk, pAddr, pArgs, argLen }; + INSTALL_MANAGED_EXCEPTION_DISPATCHER; INSTALL_UNWIND_AND_CONTINUE_HANDLER; { AppDomainFromIDHolder domain(pEntryThunk->GetDomainId(),FALSE); @@ -161,6 +162,7 @@ EXTERN_C void STDCALL UM2MDoADCallBack(UMEntryThunk *pEntryThunk, GetThread()->DoADCallBack(pEntryThunk->GetDomainId(), UM2MThunk_Wrapper, &args); UNINSTALL_UNWIND_AND_CONTINUE_HANDLER; + UNINSTALL_MANAGED_EXCEPTION_DISPATCHER; } #ifdef _TARGET_X86_ @@ -1178,6 +1180,7 @@ void STDCALL UMEntryThunk::DoRunTimeInit(UMEntryThunk* pUMEntryThunk) } CONTRACTL_END; + INSTALL_MANAGED_EXCEPTION_DISPATCHER; // this method is called by stubs which are called by managed code, // so we need an unwind and continue handler so that our internal // exceptions don't leak out into managed code. @@ -1198,6 +1201,7 @@ void STDCALL UMEntryThunk::DoRunTimeInit(UMEntryThunk* pUMEntryThunk) } UNINSTALL_UNWIND_AND_CONTINUE_HANDLER; + UNINSTALL_MANAGED_EXCEPTION_DISPATCHER; } UMEntryThunk* UMEntryThunk::CreateUMEntryThunk() diff --git a/src/vm/exceptmacros.h b/src/vm/exceptmacros.h index 0d162951eb..e712f217e7 100644 --- a/src/vm/exceptmacros.h +++ b/src/vm/exceptmacros.h @@ -345,7 +345,6 @@ VOID DECLSPEC_NORETURN DispatchManagedException(PAL_SEHException& ex); Exception* __pUnCException = NULL; \ Frame* __pUnCEntryFrame = CURRENT_THREAD->GetFrame(); \ bool __fExceptionCatched = false; \ - INSTALL_MANAGED_EXCEPTION_DISPATCHER \ SCAN_EHMARKER(); \ if (true) PAL_CPP_TRY { \ SCAN_EHMARKER_TRY(); \ @@ -368,7 +367,6 @@ VOID DECLSPEC_NORETURN DispatchManagedException(PAL_SEHException& ex); Exception* __pUnCException = NULL; \ Frame* __pUnCEntryFrame = (pHelperFrame); \ bool __fExceptionCatched = false; \ - INSTALL_MANAGED_EXCEPTION_DISPATCHER \ SCAN_EHMARKER(); \ if (true) PAL_CPP_TRY { \ SCAN_EHMARKER_TRY(); \ @@ -394,7 +392,6 @@ VOID DECLSPEC_NORETURN DispatchManagedException(PAL_SEHException& ex); SCAN_EHMARKER_CATCH(); \ UnwindAndContinueRethrowHelperAfterCatch(__pUnCEntryFrame, __pUnCException); \ } \ - UNINSTALL_MANAGED_EXCEPTION_DISPATCHER \ } \ #define UNINSTALL_UNWIND_AND_CONTINUE_HANDLER \ diff --git a/src/vm/fcall.h b/src/vm/fcall.h index 1e015a34b2..2bf6080706 100644 --- a/src/vm/fcall.h +++ b/src/vm/fcall.h @@ -563,6 +563,7 @@ LPVOID __FCThrowArgument(LPVOID me, enum RuntimeExceptionKind reKind, LPCWSTR ar TESTHOOKCALL(AppDomainCanBeUnloaded(GET_THREAD()->GetDomain()->GetId().m_dwId,!allowGC)); \ /* <TODO>TODO TURN THIS ON!!! </TODO> */ \ /* gcpoll; */ \ + INSTALL_MANAGED_EXCEPTION_DISPATCHER; \ INSTALL_UNWIND_AND_CONTINUE_HANDLER_FOR_HMF(&__helperframe); #define HELPER_METHOD_FRAME_BEGIN_EX_NOTHROW(ret, helperFrame, gcpoll, allowGC, probeFailExpr) \ @@ -595,6 +596,7 @@ LPVOID __FCThrowArgument(LPVOID me, enum RuntimeExceptionKind reKind, LPCWSTR ar #define HELPER_METHOD_FRAME_END_EX(gcpoll,allowGC) \ UNINSTALL_UNWIND_AND_CONTINUE_HANDLER; \ + UNINSTALL_MANAGED_EXCEPTION_DISPATCHER; \ TESTHOOKCALL(AppDomainCanBeUnloaded(GET_THREAD()->GetDomain()->GetId().m_dwId,!allowGC)); \ HELPER_METHOD_FRAME_END_EX_BODY(gcpoll,allowGC); diff --git a/src/vm/frames.cpp b/src/vm/frames.cpp index 6e0a424c81..1e3e9e050d 100644 --- a/src/vm/frames.cpp +++ b/src/vm/frames.cpp @@ -1998,7 +1998,7 @@ VOID InlinedCallFrame::Init() m_pCallerReturnAddress = NULL; } -#ifdef _WIN64 +#if defined(_WIN64) && !defined(FEATURE_PAL) EXTERN_C void PInvokeStubForHostInner(DWORD dwStackSize, LPVOID pStackFrame, LPVOID pTarget); @@ -2077,8 +2077,7 @@ void __stdcall PInvokeStubForHostWorker(DWORD dwStackSize, LPVOID pStackFrame, L PInvokeStubForHostInner(dwStackSize, pStackFrame, pTarget); } } - -#endif // _WIN64 +#endif // _WIN64 && !FEATURE_PAL diff --git a/src/vm/prestub.cpp b/src/vm/prestub.cpp index ff455b9e00..06d1967313 100644 --- a/src/vm/prestub.cpp +++ b/src/vm/prestub.cpp @@ -968,6 +968,7 @@ extern "C" PCODE STDCALL PreStubWorker(TransitionBlock * pTransitionBlock, Metho pPFrame->Push(CURRENT_THREAD); + INSTALL_MANAGED_EXCEPTION_DISPATCHER; INSTALL_UNWIND_AND_CONTINUE_HANDLER; ETWOnStartup (PrestubWorker_V1,PrestubWorkerEnd_V1); @@ -1036,6 +1037,7 @@ extern "C" PCODE STDCALL PreStubWorker(TransitionBlock * pTransitionBlock, Metho pbRetVal = pMD->DoPrestub(pDispatchingMT); UNINSTALL_UNWIND_AND_CONTINUE_HANDLER; + UNINSTALL_MANAGED_EXCEPTION_DISPATCHER; // Give debugger opportunity to stop here ThePreStubPatch(); @@ -1822,6 +1824,7 @@ EXTERN_C PCODE STDCALL ExternalMethodFixupWorker(TransitionBlock * pTransitionBl pEMFrame->Push(CURRENT_THREAD); // Push the new ExternalMethodFrame onto the frame stack + INSTALL_MANAGED_EXCEPTION_DISPATCHER; INSTALL_UNWIND_AND_CONTINUE_HANDLER; bool fVirtual = false; @@ -2048,6 +2051,7 @@ EXTERN_C PCODE STDCALL ExternalMethodFixupWorker(TransitionBlock * pTransitionBl // Ready to return UNINSTALL_UNWIND_AND_CONTINUE_HANDLER; + UNINSTALL_MANAGED_EXCEPTION_DISPATCHER; pEMFrame->Pop(CURRENT_THREAD); // Pop the ExternalMethodFrame from the frame stack @@ -2586,6 +2590,7 @@ extern "C" SIZE_T STDCALL DynamicHelperWorker(TransitionBlock * pTransitionBlock pFrame->Push(CURRENT_THREAD); + INSTALL_MANAGED_EXCEPTION_DISPATCHER; INSTALL_UNWIND_AND_CONTINUE_HANDLER; #if defined(_TARGET_X86_) || defined(_TARGET_AMD64_) @@ -2689,6 +2694,7 @@ extern "C" SIZE_T STDCALL DynamicHelperWorker(TransitionBlock * pTransitionBlock } UNINSTALL_UNWIND_AND_CONTINUE_HANDLER; + UNINSTALL_MANAGED_EXCEPTION_DISPATCHER; pFrame->Pop(CURRENT_THREAD); diff --git a/src/vm/virtualcallstub.cpp b/src/vm/virtualcallstub.cpp index c234e8c470..729d90c770 100644 --- a/src/vm/virtualcallstub.cpp +++ b/src/vm/virtualcallstub.cpp @@ -1228,6 +1228,7 @@ extern "C" PCODE STDCALL StubDispatchFixupWorker(TransitionBlock * pTransitionBl pSDFrame->SetCallSite(pModule, pIndirectCell); pSDFrame->Push(CURRENT_THREAD); + INSTALL_MANAGED_EXCEPTION_DISPATCHER; INSTALL_UNWIND_AND_CONTINUE_HANDLER; PEImageLayout *pNativeImage = pModule->GetNativeOrReadyToRunImage(); @@ -1296,6 +1297,7 @@ extern "C" PCODE STDCALL StubDispatchFixupWorker(TransitionBlock * pTransitionBl // Ready to return UNINSTALL_UNWIND_AND_CONTINUE_HANDLER; + UNINSTALL_MANAGED_EXCEPTION_DISPATCHER; pSDFrame->Pop(CURRENT_THREAD); return pTarget; @@ -1575,6 +1577,7 @@ PCODE VSD_ResolveWorker(TransitionBlock * pTransitionBlock, pSDFrame->SetRepresentativeSlot(pRepresentativeMT, representativeToken.GetSlotNumber()); pSDFrame->Push(CURRENT_THREAD); + INSTALL_MANAGED_EXCEPTION_DISPATCHER; INSTALL_UNWIND_AND_CONTINUE_HANDLER; // For Virtual Delegates the m_siteAddr is a field of a managed object @@ -1604,6 +1607,7 @@ PCODE VSD_ResolveWorker(TransitionBlock * pTransitionBlock, GCPROTECT_END(); UNINSTALL_UNWIND_AND_CONTINUE_HANDLER; + UNINSTALL_MANAGED_EXCEPTION_DISPATCHER; pSDFrame->Pop(CURRENT_THREAD); return target; |