From 5be7645cbe58aa02989410c5094fe8159bd5aed7 Mon Sep 17 00:00:00 2001 From: Filip Navara Date: Mon, 24 Mar 2025 08:06:37 +0100 Subject: [PATCH 1/3] Use EXCEPTION_HANDLER_IMPL/DECL macros for declaring exception handlers --- src/coreclr/cpp.hint | 2 +- src/coreclr/vm/exceptionhandling.cpp | 137 ++++++--------------------- src/coreclr/vm/exceptionhandling.h | 8 +- src/coreclr/vm/exceptmacros.h | 2 +- 4 files changed, 35 insertions(+), 114 deletions(-) diff --git a/src/coreclr/cpp.hint b/src/coreclr/cpp.hint index 1eb32d3f9da824..1345f7c61f2a3a 100644 --- a/src/coreclr/cpp.hint +++ b/src/coreclr/cpp.hint @@ -36,7 +36,7 @@ extern "C" _EXCEPTION_HANDLER_DECL(funcname) #define EXCEPTION_HANDLER_IMPL(funcname) \ - _EXCEPTION_HANDLER_DECL(funcname) + extern "C" _EXCEPTION_HANDLER_DECL(funcname) #define EXCEPTION_HANDLER_FWD(funcname) \ funcname(pExceptionRecord, pEstablisherFrame, pContext, pDispatcherContext) diff --git a/src/coreclr/vm/exceptionhandling.cpp b/src/coreclr/vm/exceptionhandling.cpp index c4786039f7b5c1..c8e38aa73205ac 100644 --- a/src/coreclr/vm/exceptionhandling.cpp +++ b/src/coreclr/vm/exceptionhandling.cpp @@ -915,12 +915,7 @@ static void PopExplicitFrames(Thread *pThread, void *targetSp, void *targetCalle } } -EXTERN_C EXCEPTION_DISPOSITION -ProcessCLRExceptionNew(IN PEXCEPTION_RECORD pExceptionRecord, - IN PVOID pEstablisherFrame, - IN OUT PCONTEXT pContextRecord, - IN OUT PDISPATCHER_CONTEXT pDispatcherContext - ) +EXCEPTION_HANDLER_IMPL(ProcessCLRExceptionNew) { // // This method doesn't always return, so it will leave its @@ -977,7 +972,7 @@ ProcessCLRExceptionNew(IN PEXCEPTION_RECORD pExceptionRecord, else { OBJECTREF oref = ExceptionTracker::CreateThrowable(pExceptionRecord, FALSE); - DispatchManagedException(oref, pContextRecord, pExceptionRecord); + DispatchManagedException(oref, pContext, pExceptionRecord); } } #endif // !HOST_UNIX @@ -985,12 +980,7 @@ ProcessCLRExceptionNew(IN PEXCEPTION_RECORD pExceptionRecord, UNREACHABLE(); } -EXTERN_C EXCEPTION_DISPOSITION -ProcessCLRException(IN PEXCEPTION_RECORD pExceptionRecord, - IN PVOID pEstablisherFrame, - IN OUT PCONTEXT pContextRecord, - IN OUT PDISPATCHER_CONTEXT pDispatcherContext - ) +EXCEPTION_HANDLER_IMPL(ProcessCLRException) { // // This method doesn't always return, so it will leave its @@ -1002,7 +992,7 @@ ProcessCLRException(IN PEXCEPTION_RECORD pExceptionRecord, if (g_isNewExceptionHandlingEnabled) { - return ProcessCLRExceptionNew(pExceptionRecord, pEstablisherFrame, pContextRecord, pDispatcherContext); + return ProcessCLRExceptionNew(pExceptionRecord, pEstablisherFrame, pContext, pDispatcherContext); } // We must preserve this so that GCStress=4 eh processing doesnt kill last error. @@ -1013,8 +1003,8 @@ ProcessCLRException(IN PEXCEPTION_RECORD pExceptionRecord, STRESS_LOG5(LF_EH, LL_INFO10, "Processing exception at establisher=%p, ip=%p disp->cxr: %p, sp: %p, cxr @ exception: %p\n", pEstablisherFrame, pDispatcherContext->ControlPc, pDispatcherContext->ContextRecord, - GetSP(pDispatcherContext->ContextRecord), pContextRecord); - AMD64_ONLY(STRESS_LOG3(LF_EH, LL_INFO10, " rbx=%p, rsi=%p, rdi=%p\n", pContextRecord->Rbx, pContextRecord->Rsi, pContextRecord->Rdi)); + GetSP(pDispatcherContext->ContextRecord), pContext); + AMD64_ONLY(STRESS_LOG3(LF_EH, LL_INFO10, " rbx=%p, rsi=%p, rdi=%p\n", pContext->Rbx, pContext->Rsi, pContext->Rdi)); // sample flags early on because we may change pExceptionRecord below // if we are seeing a STATUS_UNWIND_CONSOLIDATE @@ -1130,7 +1120,7 @@ ProcessCLRException(IN PEXCEPTION_RECORD pExceptionRecord, (pExceptionRecord->ExceptionCode == STATUS_SINGLE_STEP)) { // It is a breakpoint; is it from the runtime or managed code? - PCODE ip = GetIP(pContextRecord); // IP of the fault. + PCODE ip = GetIP(pContext); // IP of the fault. BOOL fExternalException; @@ -1160,7 +1150,7 @@ ProcessCLRException(IN PEXCEPTION_RECORD pExceptionRecord, pDispatcherContext->ControlPc, sf, pExceptionRecord, - pContextRecord, + pContext, bAsynchronousThreadStop, !(dwExceptionFlags & EXCEPTION_UNWINDING), &STState); @@ -1214,7 +1204,7 @@ ProcessCLRException(IN PEXCEPTION_RECORD pExceptionRecord, status = pTracker->ProcessOSExceptionNotification( pExceptionRecord, - pContextRecord, + pContext, pDispatcherContext, dwExceptionFlags, sf, @@ -1268,11 +1258,11 @@ ProcessCLRException(IN PEXCEPTION_RECORD pExceptionRecord, { bool fAborting = false; UINT_PTR uResumePC = (UINT_PTR)-1; - UINT_PTR uOriginalSP = GetSP(pContextRecord); + UINT_PTR uOriginalSP = GetSP(pContext); Frame* pLimitFrame = pTracker->GetLimitFrame(); - pDispatcherContext->ContextRecord = pContextRecord; + pDispatcherContext->ContextRecord = pContext; // We may be in COOP mode at this point - the indefinite switch was done // in ExceptionTracker::ProcessManagedCallFrame. @@ -1291,7 +1281,7 @@ ProcessCLRException(IN PEXCEPTION_RECORD pExceptionRecord, // // Since CallCatchHandler expects to be in COOP mode, perform the switch here. GCX_COOP_NO_DTOR(); - uResumePC = pTracker->CallCatchHandler(pContextRecord, &fAborting); + uResumePC = pTracker->CallCatchHandler(pContext, &fAborting); { // @@ -1318,11 +1308,11 @@ ProcessCLRException(IN PEXCEPTION_RECORD pExceptionRecord, INDEBUG(pTracker = (ExceptionTracker*)POISONC); // Note that we should only fail to fix up for SO. - bool fFixedUp = FixNonvolatileRegisters(uOriginalSP, pThread, pContextRecord, fAborting); + bool fFixedUp = FixNonvolatileRegisters(uOriginalSP, pThread, pContext, fAborting); _ASSERTE(fFixedUp || (pExceptionRecord->ExceptionCode == STATUS_STACK_OVERFLOW)); - CONSISTENCY_CHECK(pLimitFrame > dac_cast(GetSP(pContextRecord))); + CONSISTENCY_CHECK(pLimitFrame > dac_cast(GetSP(pContext))); if (pICFSetAsLimitFrame != NULL) { _ASSERTE(pICFSetAsLimitFrame == pLimitFrame); @@ -1337,9 +1327,9 @@ ProcessCLRException(IN PEXCEPTION_RECORD pExceptionRecord, pThread->SetFrame(pLimitFrame); - FixContext(pContextRecord); + FixContext(pContext); - SetIP(pContextRecord, (PCODE)uResumePC); + SetIP(pContext, (PCODE)uResumePC); } #ifdef STACK_GUARDS_DEBUG @@ -1351,10 +1341,10 @@ ProcessCLRException(IN PEXCEPTION_RECORD pExceptionRecord, #ifdef TARGET_AMD64 // OSes older than Win8 have a bug where RtlUnwindEx passes meaningless ContextFlags to the personality routine in // some cases. - pContextRecord->ContextFlags |= CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT; + pContext->ContextFlags |= CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT; #endif - ExceptionTracker::ResumeExecution(pContextRecord); + ExceptionTracker::ResumeExecution(pContext); UNREACHABLE(); } } @@ -4656,7 +4646,7 @@ VOID UnwindManagedExceptionPass2(PAL_SEHException& ex, CONTEXT* unwindStartConte // Perform unwinding of the current frame disposition = ProcessCLRException(exceptionRecord, - (void*)establisherFrame, + (struct _EXCEPTION_REGISTRATION_RECORD *)establisherFrame, currentFrameContext, &dispatcherContext); @@ -4849,7 +4839,7 @@ VOID DECLSPEC_NORETURN UnwindManagedExceptionPass1(PAL_SEHException& ex, CONTEXT // Find exception handler in the current frame disposition = ProcessCLRException(ex.GetExceptionRecord(), - (void*)establisherFrame, + (struct _EXCEPTION_REGISTRATION_RECORD *)establisherFrame, ex.GetContextRecord(), &dispatcherContext); @@ -6050,12 +6040,7 @@ BOOL FirstCallToHandler ( } -EXTERN_C EXCEPTION_DISPOSITION -HijackHandler(IN PEXCEPTION_RECORD pExceptionRecord, - IN PVOID pEstablisherFrame, - IN OUT PCONTEXT pContextRecord, - IN OUT PDISPATCHER_CONTEXT pDispatcherContext - ) +EXCEPTION_HANDLER_IMPL(HijackHandler) { CONTRACTL { @@ -6069,7 +6054,7 @@ HijackHandler(IN PEXCEPTION_RECORD pExceptionRecord, pDispatcherContext->EstablisherFrame, pDispatcherContext->ContextRecord, GetSP(pDispatcherContext->ContextRecord), - pContextRecord); + pContext); Thread* pThread = GetThread(); CONTEXT *pNewContext = NULL; @@ -6240,12 +6225,7 @@ UnhandledExceptionHandlerUnix( #else // TARGET_UNIX -EXTERN_C EXCEPTION_DISPOSITION -UMThunkUnwindFrameChainHandler(IN PEXCEPTION_RECORD pExceptionRecord, - IN PVOID pEstablisherFrame, - IN OUT PCONTEXT pContextRecord, - IN OUT PDISPATCHER_CONTEXT pDispatcherContext - ) +EXCEPTION_HANDLER_IMPL(UMThunkUnwindFrameChainHandler) { Thread* pThread = GetThreadNULLOk(); if (pThread == NULL) { @@ -6284,68 +6264,22 @@ UMThunkUnwindFrameChainHandler(IN PEXCEPTION_RECORD pExceptionRecord, return ExceptionContinueSearch; } -EXTERN_C EXCEPTION_DISPOSITION -UMEntryPrestubUnwindFrameChainHandler( - IN PEXCEPTION_RECORD pExceptionRecord, - IN PVOID pEstablisherFrame, - IN OUT PCONTEXT pContextRecord, - IN OUT PDISPATCHER_CONTEXT pDispatcherContext - ) +EXCEPTION_HANDLER_IMPL(UMEntryPrestubUnwindFrameChainHandler) { EXCEPTION_DISPOSITION disposition = UMThunkUnwindFrameChainHandler( pExceptionRecord, pEstablisherFrame, - pContextRecord, + pContext, pDispatcherContext ); return disposition; } -EXTERN_C EXCEPTION_DISPOSITION -UMThunkStubUnwindFrameChainHandler( - IN PEXCEPTION_RECORD pExceptionRecord, - IN PVOID pEstablisherFrame, - IN OUT PCONTEXT pContextRecord, - IN OUT PDISPATCHER_CONTEXT pDispatcherContext - ) -{ - -#ifdef _DEBUG - // If the exception is escaping the last CLR personality routine on the stack, - // then state a flag on the thread to indicate so. - // - // We check for thread object since this function is the personality routine of the UMThunk - // and we can landup here even when thread creation (within the thunk) fails. - if (GetThreadNULLOk() != NULL) - { - SetReversePInvokeEscapingUnhandledExceptionStatus(IS_UNWINDING(pExceptionRecord->ExceptionFlags), - pEstablisherFrame - ); - } -#endif // _DEBUG - - EXCEPTION_DISPOSITION disposition = UMThunkUnwindFrameChainHandler( - pExceptionRecord, - pEstablisherFrame, - pContextRecord, - pDispatcherContext - ); - - return disposition; -} - - // This is the personality routine setup for the assembly helper (CallDescrWorker) that calls into // managed code. -EXTERN_C EXCEPTION_DISPOSITION -CallDescrWorkerUnwindFrameChainHandler(IN PEXCEPTION_RECORD pExceptionRecord, - IN PVOID pEstablisherFrame, - IN OUT PCONTEXT pContextRecord, - IN OUT PDISPATCHER_CONTEXT pDispatcherContext - ) +EXCEPTION_HANDLER_IMPL(CallDescrWorkerUnwindFrameChainHandler) { - Thread* pThread = GetThread(); if (pExceptionRecord->ExceptionCode == STATUS_STACK_OVERFLOW) { @@ -6366,7 +6300,7 @@ CallDescrWorkerUnwindFrameChainHandler(IN PEXCEPTION_RECORD pExceptionReco { retVal = ProcessCLRException(pExceptionRecord, pEstablisherFrame, - pContextRecord, + pContext, pDispatcherContext); } else @@ -6393,12 +6327,7 @@ CallDescrWorkerUnwindFrameChainHandler(IN PEXCEPTION_RECORD pExceptionReco #endif // TARGET_UNIX #ifdef FEATURE_COMINTEROP -EXTERN_C EXCEPTION_DISPOSITION -ReverseComUnwindFrameChainHandler(IN PEXCEPTION_RECORD pExceptionRecord, - IN PVOID pEstablisherFrame, - IN OUT PCONTEXT pContextRecord, - IN OUT PDISPATCHER_CONTEXT pDispatcherContext - ) +EXCEPTION_HANDLER_IMPL(ReverseComUnwindFrameChainHandler) { if (IS_UNWINDING(pExceptionRecord->ExceptionFlags)) { @@ -6409,13 +6338,7 @@ ReverseComUnwindFrameChainHandler(IN PEXCEPTION_RECORD pExceptionRecord, #endif // FEATURE_COMINTEROP #ifndef TARGET_UNIX -EXTERN_C EXCEPTION_DISPOSITION -FixRedirectContextHandler( - IN PEXCEPTION_RECORD pExceptionRecord, - IN PVOID pEstablisherFrame, - IN OUT PCONTEXT pContextRecord, - IN OUT PDISPATCHER_CONTEXT pDispatcherContext - ) +EXCEPTION_HANDLER_IMPL(FixRedirectContextHandler) { CONTRACTL { @@ -6428,7 +6351,7 @@ FixRedirectContextHandler( STRESS_LOG4(LF_EH, LL_INFO10, "FixRedirectContextHandler: sp %p, establisher %p, cxr: %p, disp cxr: %p\n", GetSP(pDispatcherContext->ContextRecord), pDispatcherContext->EstablisherFrame, - pContextRecord, + pContext, pDispatcherContext->ContextRecord); CONTEXT *pRedirectedContext = GetCONTEXTFromRedirectedStubStackFrame(pDispatcherContext); diff --git a/src/coreclr/vm/exceptionhandling.h b/src/coreclr/vm/exceptionhandling.h index e8f6ac5f9a9d29..07a5fac86b2fcd 100644 --- a/src/coreclr/vm/exceptionhandling.h +++ b/src/coreclr/vm/exceptionhandling.h @@ -16,11 +16,9 @@ // Accessing it will result in AV. #define INVALID_RESUME_ADDRESS 0x000000000000bad0 -EXTERN_C EXCEPTION_DISPOSITION -ProcessCLRException(IN PEXCEPTION_RECORD pExceptionRecord, - IN PVOID pEstablisherFrame, - IN OUT PT_CONTEXT pContextRecord, - IN OUT PT_DISPATCHER_CONTEXT pDispatcherContext); +#ifndef DACCESS_COMPILE +EXCEPTION_HANDLER_DECL(ProcessCLRException); +#endif VOID DECLSPEC_NORETURN DispatchManagedException(OBJECTREF throwable, CONTEXT *pExceptionContext, EXCEPTION_RECORD *pExceptionRecord = NULL); VOID DECLSPEC_NORETURN DispatchManagedException(OBJECTREF throwable); diff --git a/src/coreclr/vm/exceptmacros.h b/src/coreclr/vm/exceptmacros.h index 2c11c059853ba9..1e3d1204d6ab9f 100644 --- a/src/coreclr/vm/exceptmacros.h +++ b/src/coreclr/vm/exceptmacros.h @@ -202,7 +202,7 @@ VOID DECLSPEC_NORETURN RealCOMPlusThrowOM(); extern "C" _EXCEPTION_HANDLER_DECL(funcname) #define EXCEPTION_HANDLER_IMPL(funcname) \ - _EXCEPTION_HANDLER_DECL(funcname) + extern "C" _EXCEPTION_HANDLER_DECL(funcname) #define EXCEPTION_HANDLER_FWD(funcname) \ funcname(pExceptionRecord, pEstablisherFrame, pContext, pDispatcherContext) From fd2ea20cdc46b3631937a146248d9befdcf06a56 Mon Sep 17 00:00:00 2001 From: Filip Navara Date: Mon, 24 Mar 2025 08:49:31 +0100 Subject: [PATCH 2/3] Fix win-x86 build --- src/coreclr/vm/exstate.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/coreclr/vm/exstate.h b/src/coreclr/vm/exstate.h index 07432c32c1e61f..02d749a8e56d96 100644 --- a/src/coreclr/vm/exstate.h +++ b/src/coreclr/vm/exstate.h @@ -202,7 +202,11 @@ class ThreadExceptionState ThrowCallbackType& tct, Frame *pStartFrame); - friend EXCEPTION_HANDLER_IMPL(COMPlusFrameHandler); + friend EXCEPTION_DISPOSITION __cdecl + COMPlusFrameHandler(EXCEPTION_RECORD *pExceptionRecord, + EXCEPTION_REGISTRATION_RECORD *pEstablisherFrame, + CONTEXT *pContext, + DISPATCHER_CONTEXT *pDispatcherContext); friend EXCEPTION_DISPOSITION __cdecl CPFH_RealFirstPassHandler(EXCEPTION_RECORD *pExceptionRecord, From b58006bb98d2512982b06a73b7c38617c1ce915b Mon Sep 17 00:00:00 2001 From: Filip Navara Date: Mon, 24 Mar 2025 19:22:10 +0100 Subject: [PATCH 3/3] Address initial feedback --- src/coreclr/cpp.hint | 2 +- src/coreclr/vm/exceptionhandling.cpp | 6 ++++++ src/coreclr/vm/exceptmacros.h | 2 +- src/coreclr/vm/exstate.h | 6 +----- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/coreclr/cpp.hint b/src/coreclr/cpp.hint index 1345f7c61f2a3a..1eb32d3f9da824 100644 --- a/src/coreclr/cpp.hint +++ b/src/coreclr/cpp.hint @@ -36,7 +36,7 @@ extern "C" _EXCEPTION_HANDLER_DECL(funcname) #define EXCEPTION_HANDLER_IMPL(funcname) \ - extern "C" _EXCEPTION_HANDLER_DECL(funcname) + _EXCEPTION_HANDLER_DECL(funcname) #define EXCEPTION_HANDLER_FWD(funcname) \ funcname(pExceptionRecord, pEstablisherFrame, pContext, pDispatcherContext) diff --git a/src/coreclr/vm/exceptionhandling.cpp b/src/coreclr/vm/exceptionhandling.cpp index c8e38aa73205ac..9f4b9f5000c91d 100644 --- a/src/coreclr/vm/exceptionhandling.cpp +++ b/src/coreclr/vm/exceptionhandling.cpp @@ -49,6 +49,12 @@ ClrUnwindEx(EXCEPTION_RECORD* pExceptionRecord, UINT_PTR TargetFrameSp); #endif // !TARGET_UNIX +EXCEPTION_HANDLER_DECL(CallDescrWorkerUnwindFrameChainHandler); +EXCEPTION_HANDLER_DECL(ReverseComUnwindFrameChainHandler); +EXCEPTION_HANDLER_DECL(HijackHandler); +EXCEPTION_HANDLER_DECL(FixRedirectContextHandler); +EXCEPTION_HANDLER_DECL(UMEntryPrestubUnwindFrameChainHandler); + #if defined(TARGET_UNIX) && !defined(DACCESS_COMPILE) VOID UnwindManagedExceptionPass2(PAL_SEHException& ex, CONTEXT* unwindStartContext); #endif // TARGET_UNIX && !DACCESS_COMPILE diff --git a/src/coreclr/vm/exceptmacros.h b/src/coreclr/vm/exceptmacros.h index 1e3d1204d6ab9f..2c11c059853ba9 100644 --- a/src/coreclr/vm/exceptmacros.h +++ b/src/coreclr/vm/exceptmacros.h @@ -202,7 +202,7 @@ VOID DECLSPEC_NORETURN RealCOMPlusThrowOM(); extern "C" _EXCEPTION_HANDLER_DECL(funcname) #define EXCEPTION_HANDLER_IMPL(funcname) \ - extern "C" _EXCEPTION_HANDLER_DECL(funcname) + _EXCEPTION_HANDLER_DECL(funcname) #define EXCEPTION_HANDLER_FWD(funcname) \ funcname(pExceptionRecord, pEstablisherFrame, pContext, pDispatcherContext) diff --git a/src/coreclr/vm/exstate.h b/src/coreclr/vm/exstate.h index 02d749a8e56d96..69eda9b6299ead 100644 --- a/src/coreclr/vm/exstate.h +++ b/src/coreclr/vm/exstate.h @@ -202,11 +202,7 @@ class ThreadExceptionState ThrowCallbackType& tct, Frame *pStartFrame); - friend EXCEPTION_DISPOSITION __cdecl - COMPlusFrameHandler(EXCEPTION_RECORD *pExceptionRecord, - EXCEPTION_REGISTRATION_RECORD *pEstablisherFrame, - CONTEXT *pContext, - DISPATCHER_CONTEXT *pDispatcherContext); + friend _EXCEPTION_HANDLER_DECL(COMPlusFrameHandler); friend EXCEPTION_DISPOSITION __cdecl CPFH_RealFirstPassHandler(EXCEPTION_RECORD *pExceptionRecord,