Skip to content

Commit 87ceb89

Browse files
authored
Revert "Fix exception handling in the prestub worker (#111937)"
This reverts commit 12fa864.
1 parent 8c92ae7 commit 87ceb89

12 files changed

+62
-270
lines changed

src/coreclr/vm/excep.cpp

+7-10
Original file line numberDiff line numberDiff line change
@@ -3053,17 +3053,14 @@ void StackTraceInfo::AppendElement(OBJECTHANDLE hThrowable, UINT_PTR currentIP,
30533053
// This is a workaround to fix the generation of stack traces from exception objects so that
30543054
// they point to the line that actually generated the exception instead of the line
30553055
// following.
3056-
if (pCf != NULL)
3056+
if (pCf->IsIPadjusted())
30573057
{
3058-
if (pCf->IsIPadjusted())
3059-
{
3060-
stackTraceElem.flags |= STEF_IP_ADJUSTED;
3061-
}
3062-
else if (!pCf->HasFaulted() && stackTraceElem.ip != 0)
3063-
{
3064-
stackTraceElem.ip -= STACKWALK_CONTROLPC_ADJUST_OFFSET;
3065-
stackTraceElem.flags |= STEF_IP_ADJUSTED;
3066-
}
3058+
stackTraceElem.flags |= STEF_IP_ADJUSTED;
3059+
}
3060+
else if (!pCf->HasFaulted() && stackTraceElem.ip != 0)
3061+
{
3062+
stackTraceElem.ip -= STACKWALK_CONTROLPC_ADJUST_OFFSET;
3063+
stackTraceElem.flags |= STEF_IP_ADJUSTED;
30673064
}
30683065

30693066
#ifndef TARGET_UNIX // Watson is supported on Windows only

src/coreclr/vm/exceptionhandling.cpp

+4-8
Original file line numberDiff line numberDiff line change
@@ -932,12 +932,7 @@ ProcessCLRExceptionNew(IN PEXCEPTION_RECORD pExceptionRecord,
932932

933933
Thread* pThread = GetThread();
934934

935-
// Skip native frames of asm helpers that have the ProcessCLRException set as their personality routine.
936-
// There is nothing to do for those with the new exception handling.
937-
// Also skip all frames when processing unhandled exceptions. That allows them to reach the host app
938-
// level and let 3rd party the chance to handle them.
939-
if (!ExecutionManager::IsManagedCode((PCODE)pDispatcherContext->ControlPc) ||
940-
pThread->HasThreadStateNC(Thread::TSNC_ProcessedUnhandledException))
935+
if (pThread->HasThreadStateNC(Thread::TSNC_ProcessedUnhandledException))
941936
{
942937
if ((pExceptionRecord->ExceptionFlags & EXCEPTION_UNWINDING))
943938
{
@@ -8519,7 +8514,7 @@ static StackWalkAction MoveToNextNonSkippedFrame(StackFrameIterator* pStackFrame
85198514
return retVal;
85208515
}
85218516

8522-
bool IsCallDescrWorkerInternalReturnAddress(PCODE pCode);
8517+
extern "C" size_t CallDescrWorkerInternalReturnAddressOffset;
85238518

85248519
extern "C" bool QCALLTYPE SfiNext(StackFrameIterator* pThis, uint* uExCollideClauseIdx, bool* fUnwoundReversePInvoke, bool* pfIsExceptionIntercepted)
85258520
{
@@ -8574,7 +8569,8 @@ extern "C" bool QCALLTYPE SfiNext(StackFrameIterator* pThis, uint* uExCollideCla
85748569
}
85758570
else
85768571
{
8577-
if (IsCallDescrWorkerInternalReturnAddress(GetIP(pThis->m_crawl.GetRegisterSet()->pCallerContext)))
8572+
size_t CallDescrWorkerInternalReturnAddress = (size_t)CallDescrWorkerInternal + CallDescrWorkerInternalReturnAddressOffset;
8573+
if (GetIP(pThis->m_crawl.GetRegisterSet()->pCallerContext) == CallDescrWorkerInternalReturnAddress)
85788574
{
85798575
invalidRevPInvoke = true;
85808576
}

src/coreclr/vm/exceptmacros.h

+2-14
Original file line numberDiff line numberDiff line change
@@ -277,22 +277,15 @@ VOID DECLSPEC_NORETURN UnwindAndContinueRethrowHelperAfterCatch(Frame* pEntryFra
277277
#ifdef TARGET_UNIX
278278
VOID DECLSPEC_NORETURN DispatchManagedException(PAL_SEHException& ex, bool isHardwareException);
279279

280-
#define INSTALL_MANAGED_EXCEPTION_DISPATCHER_EX \
280+
#define INSTALL_MANAGED_EXCEPTION_DISPATCHER \
281281
PAL_SEHException exCopy; \
282282
bool hasCaughtException = false; \
283283
try {
284284

285-
#define INSTALL_MANAGED_EXCEPTION_DISPATCHER \
286-
INSTALL_MANAGED_EXCEPTION_DISPATCHER_EX
287-
288-
#define UNINSTALL_MANAGED_EXCEPTION_DISPATCHER_EX(nativeRethrow) \
285+
#define UNINSTALL_MANAGED_EXCEPTION_DISPATCHER \
289286
} \
290287
catch (PAL_SEHException& ex) \
291288
{ \
292-
if (nativeRethrow) \
293-
{ \
294-
throw; \
295-
} \
296289
exCopy = std::move(ex); \
297290
hasCaughtException = true; \
298291
} \
@@ -301,9 +294,6 @@ VOID DECLSPEC_NORETURN DispatchManagedException(PAL_SEHException& ex, bool isHar
301294
DispatchManagedException(exCopy, false);\
302295
}
303296

304-
#define UNINSTALL_MANAGED_EXCEPTION_DISPATCHER \
305-
UNINSTALL_MANAGED_EXCEPTION_DISPATCHER_EX(false)
306-
307297
// Install trap that catches unhandled managed exception and dumps its stack
308298
#define INSTALL_UNHANDLED_MANAGED_EXCEPTION_TRAP \
309299
try {
@@ -325,9 +315,7 @@ VOID DECLSPEC_NORETURN DispatchManagedException(PAL_SEHException& ex, bool isHar
325315
#else // TARGET_UNIX
326316

327317
#define INSTALL_MANAGED_EXCEPTION_DISPATCHER
328-
#define INSTALL_MANAGED_EXCEPTION_DISPATCHER_EX
329318
#define UNINSTALL_MANAGED_EXCEPTION_DISPATCHER
330-
#define UNINSTALL_MANAGED_EXCEPTION_DISPATCHER_EX
331319

332320
#define INSTALL_UNHANDLED_MANAGED_EXCEPTION_TRAP
333321
#define UNINSTALL_UNHANDLED_MANAGED_EXCEPTION_TRAP

src/coreclr/vm/prestub.cpp

+41-73
Original file line numberDiff line numberDiff line change
@@ -2536,20 +2536,6 @@ Stub * MakeInstantiatingStubWorker(MethodDesc *pMD)
25362536
}
25372537
#endif // defined(FEATURE_SHARE_GENERIC_CODE)
25382538

2539-
extern "C" size_t CallDescrWorkerInternalReturnAddressOffset;
2540-
2541-
bool IsCallDescrWorkerInternalReturnAddress(PCODE pCode)
2542-
{
2543-
LIMITED_METHOD_CONTRACT;
2544-
#ifdef FEATURE_EH_FUNCLETS
2545-
size_t CallDescrWorkerInternalReturnAddress = (size_t)CallDescrWorkerInternal + CallDescrWorkerInternalReturnAddressOffset;
2546-
2547-
return pCode == CallDescrWorkerInternalReturnAddress;
2548-
#else // FEATURE_EH_FUNCLETS
2549-
return false;
2550-
#endif // FEATURE_EH_FUNCLETS
2551-
}
2552-
25532539
//=============================================================================
25542540
// This function generates the real code when from Preemptive mode.
25552541
// It is specifically designed to work with the UnmanagedCallersOnlyAttribute.
@@ -2645,76 +2631,60 @@ extern "C" PCODE STDCALL PreStubWorker(TransitionBlock* pTransitionBlock, Method
26452631

26462632
pPFrame->Push(CURRENT_THREAD);
26472633

2648-
EX_TRY
2649-
{
2650-
bool propagateExceptionToNativeCode = IsCallDescrWorkerInternalReturnAddress(pTransitionBlock->m_ReturnAddress);
2634+
INSTALL_MANAGED_EXCEPTION_DISPATCHER;
2635+
INSTALL_UNWIND_AND_CONTINUE_HANDLER;
26512636

2652-
INSTALL_MANAGED_EXCEPTION_DISPATCHER_EX;
2653-
INSTALL_UNWIND_AND_CONTINUE_HANDLER_EX;
2637+
// Make sure the method table is restored, and method instantiation if present
2638+
pMD->CheckRestore();
2639+
CONSISTENCY_CHECK(GetAppDomain()->CheckCanExecuteManagedCode(pMD));
26542640

2655-
// Make sure the method table is restored, and method instantiation if present
2656-
pMD->CheckRestore();
2657-
CONSISTENCY_CHECK(GetAppDomain()->CheckCanExecuteManagedCode(pMD));
2641+
MethodTable* pDispatchingMT = NULL;
2642+
if (pMD->IsVtableMethod())
2643+
{
2644+
OBJECTREF curobj = pPFrame->GetThis();
26582645

2659-
MethodTable* pDispatchingMT = NULL;
2660-
if (pMD->IsVtableMethod())
2646+
if (curobj != NULL) // Check for virtual function called non-virtually on a NULL object
26612647
{
2662-
OBJECTREF curobj = pPFrame->GetThis();
2648+
pDispatchingMT = curobj->GetMethodTable();
26632649

2664-
if (curobj != NULL) // Check for virtual function called non-virtually on a NULL object
2650+
if (pDispatchingMT->IsIDynamicInterfaceCastable())
26652651
{
2666-
pDispatchingMT = curobj->GetMethodTable();
2652+
MethodTable* pMDMT = pMD->GetMethodTable();
2653+
TypeHandle objectType(pDispatchingMT);
2654+
TypeHandle methodType(pMDMT);
26672655

2668-
if (pDispatchingMT->IsIDynamicInterfaceCastable())
2656+
GCStress<cfg_any>::MaybeTrigger();
2657+
INDEBUG(curobj = NULL); // curobj is unprotected and CanCastTo() can trigger GC
2658+
if (!objectType.CanCastTo(methodType))
26692659
{
2670-
MethodTable* pMDMT = pMD->GetMethodTable();
2671-
TypeHandle objectType(pDispatchingMT);
2672-
TypeHandle methodType(pMDMT);
2673-
2674-
GCStress<cfg_any>::MaybeTrigger();
2675-
INDEBUG(curobj = NULL); // curobj is unprotected and CanCastTo() can trigger GC
2676-
if (!objectType.CanCastTo(methodType))
2677-
{
2678-
// Apparently IDynamicInterfaceCastable magic was involved when we chose this method to be called
2679-
// that's why we better stick to the MethodTable it belongs to, otherwise
2680-
// DoPrestub() will fail not being able to find implementation for pMD in pDispatchingMT.
2660+
// Apparently IDynamicInterfaceCastable magic was involved when we chose this method to be called
2661+
// that's why we better stick to the MethodTable it belongs to, otherwise
2662+
// DoPrestub() will fail not being able to find implementation for pMD in pDispatchingMT.
26812663

2682-
pDispatchingMT = pMDMT;
2683-
}
2664+
pDispatchingMT = pMDMT;
26842665
}
2666+
}
26852667

2686-
// For value types, the only virtual methods are interface implementations.
2687-
// Thus pDispatching == pMT because there
2688-
// is no inheritance in value types. Note the BoxedEntryPointStubs are shared
2689-
// between all sharable generic instantiations, so the == test is on
2690-
// canonical method tables.
2668+
// For value types, the only virtual methods are interface implementations.
2669+
// Thus pDispatching == pMT because there
2670+
// is no inheritance in value types. Note the BoxedEntryPointStubs are shared
2671+
// between all sharable generic instantiations, so the == test is on
2672+
// canonical method tables.
26912673
#ifdef _DEBUG
2692-
MethodTable* pMDMT = pMD->GetMethodTable(); // put this here to see what the MT is in debug mode
2693-
_ASSERTE(!pMD->GetMethodTable()->IsValueType() ||
2694-
(pMD->IsUnboxingStub() && (pDispatchingMT->GetCanonicalMethodTable() == pMDMT->GetCanonicalMethodTable())));
2674+
MethodTable* pMDMT = pMD->GetMethodTable(); // put this here to see what the MT is in debug mode
2675+
_ASSERTE(!pMD->GetMethodTable()->IsValueType() ||
2676+
(pMD->IsUnboxingStub() && (pDispatchingMT->GetCanonicalMethodTable() == pMDMT->GetCanonicalMethodTable())));
26952677
#endif // _DEBUG
2696-
}
2697-
}
2698-
2699-
GCX_PREEMP_THREAD_EXISTS(CURRENT_THREAD);
2700-
{
2701-
pbRetVal = pMD->DoPrestub(pDispatchingMT, CallerGCMode::Coop);
27022678
}
2703-
2704-
UNINSTALL_UNWIND_AND_CONTINUE_HANDLER_EX(propagateExceptionToNativeCode);
2705-
UNINSTALL_MANAGED_EXCEPTION_DISPATCHER_EX(propagateExceptionToNativeCode);
27062679
}
2707-
EX_CATCH
2680+
2681+
GCX_PREEMP_THREAD_EXISTS(CURRENT_THREAD);
27082682
{
2709-
if (g_isNewExceptionHandlingEnabled)
2710-
{
2711-
OBJECTHANDLE ohThrowable = CURRENT_THREAD->LastThrownObjectHandle();
2712-
_ASSERTE(ohThrowable);
2713-
StackTraceInfo::AppendElement(ohThrowable, 0, (UINT_PTR)pTransitionBlock, pMD, NULL);
2714-
}
2715-
EX_RETHROW;
2683+
pbRetVal = pMD->DoPrestub(pDispatchingMT, CallerGCMode::Coop);
27162684
}
2717-
EX_END_CATCH(SwallowAllExceptions)
2685+
2686+
UNINSTALL_UNWIND_AND_CONTINUE_HANDLER;
2687+
UNINSTALL_MANAGED_EXCEPTION_DISPATCHER;
27182688

27192689
{
27202690
HardwareExceptionHolder;
@@ -3184,10 +3154,8 @@ EXTERN_C PCODE STDCALL ExternalMethodFixupWorker(TransitionBlock * pTransitionBl
31843154

31853155
pEMFrame->Push(CURRENT_THREAD); // Push the new ExternalMethodFrame onto the frame stack
31863156

3187-
bool propagateExceptionToNativeCode = IsCallDescrWorkerInternalReturnAddress(pTransitionBlock->m_ReturnAddress);
3188-
3189-
INSTALL_MANAGED_EXCEPTION_DISPATCHER_EX;
3190-
INSTALL_UNWIND_AND_CONTINUE_HANDLER_EX;
3157+
INSTALL_MANAGED_EXCEPTION_DISPATCHER;
3158+
INSTALL_UNWIND_AND_CONTINUE_HANDLER;
31913159

31923160
bool fVirtual = false;
31933161
MethodDesc * pMD = NULL;
@@ -3429,8 +3397,8 @@ EXTERN_C PCODE STDCALL ExternalMethodFixupWorker(TransitionBlock * pTransitionBl
34293397
}
34303398
// Ready to return
34313399

3432-
UNINSTALL_UNWIND_AND_CONTINUE_HANDLER_EX(propagateExceptionToNativeCode);
3433-
UNINSTALL_MANAGED_EXCEPTION_DISPATCHER_EX(propagateExceptionToNativeCode);
3400+
UNINSTALL_UNWIND_AND_CONTINUE_HANDLER;
3401+
UNINSTALL_MANAGED_EXCEPTION_DISPATCHER;
34343402

34353403
pEMFrame->Pop(CURRENT_THREAD); // Pop the ExternalMethodFrame from the frame stack
34363404

src/coreclr/vm/virtualcallstub.cpp

+8-13
Original file line numberDiff line numberDiff line change
@@ -1262,8 +1262,6 @@ ResolveCacheElem* __fastcall VirtualCallStubManager::PromoteChainEntry(ResolveCa
12621262
}
12631263
#endif // CHAIN_LOOKUP
12641264

1265-
bool IsCallDescrWorkerInternalReturnAddress(PCODE pCode);
1266-
12671265
/* Resolve to a method and return its address or NULL if there is none.
12681266
Our return value is the target address that control should continue to. Our caller will
12691267
enter the target address as if a direct call with the original stack frame had been made from
@@ -1311,16 +1309,14 @@ PCODE VSD_ResolveWorker(TransitionBlock * pTransitionBlock,
13111309

13121310
PCODE target = (PCODE)NULL;
13131311

1314-
bool propagateExceptionToNativeCode = IsCallDescrWorkerInternalReturnAddress(pTransitionBlock->m_ReturnAddress);
1315-
13161312
if (pObj == NULL) {
13171313
pSDFrame->SetForNullReferenceException();
13181314
pSDFrame->Push(CURRENT_THREAD);
1319-
INSTALL_MANAGED_EXCEPTION_DISPATCHER_EX;
1320-
INSTALL_UNWIND_AND_CONTINUE_HANDLER_EX;
1315+
INSTALL_MANAGED_EXCEPTION_DISPATCHER;
1316+
INSTALL_UNWIND_AND_CONTINUE_HANDLER;
13211317
COMPlusThrow(kNullReferenceException);
1322-
UNINSTALL_UNWIND_AND_CONTINUE_HANDLER_EX(propagateExceptionToNativeCode);
1323-
UNINSTALL_MANAGED_EXCEPTION_DISPATCHER_EX(propagateExceptionToNativeCode);
1318+
UNINSTALL_UNWIND_AND_CONTINUE_HANDLER;
1319+
UNINSTALL_MANAGED_EXCEPTION_DISPATCHER;
13241320
_ASSERTE(!"Throw returned");
13251321
}
13261322

@@ -1355,9 +1351,8 @@ PCODE VSD_ResolveWorker(TransitionBlock * pTransitionBlock,
13551351

13561352
pSDFrame->SetRepresentativeSlot(pRepresentativeMT, representativeToken.GetSlotNumber());
13571353
pSDFrame->Push(CURRENT_THREAD);
1358-
1359-
INSTALL_MANAGED_EXCEPTION_DISPATCHER_EX;
1360-
INSTALL_UNWIND_AND_CONTINUE_HANDLER_EX;
1354+
INSTALL_MANAGED_EXCEPTION_DISPATCHER;
1355+
INSTALL_UNWIND_AND_CONTINUE_HANDLER;
13611356

13621357
// For Virtual Delegates the m_siteAddr is a field of a managed object
13631358
// Thus we have to report it as an interior pointer,
@@ -1393,8 +1388,8 @@ PCODE VSD_ResolveWorker(TransitionBlock * pTransitionBlock,
13931388

13941389
GCPROTECT_END();
13951390

1396-
UNINSTALL_UNWIND_AND_CONTINUE_HANDLER_EX(propagateExceptionToNativeCode);
1397-
UNINSTALL_MANAGED_EXCEPTION_DISPATCHER_EX(propagateExceptionToNativeCode);
1391+
UNINSTALL_UNWIND_AND_CONTINUE_HANDLER;
1392+
UNINSTALL_MANAGED_EXCEPTION_DISPATCHER;
13981393
pSDFrame->Pop(CURRENT_THREAD);
13991394

14001395
return target;

src/tests/Regressions/coreclr/GitHub_76531/dependencytodelete.cs

-14
This file was deleted.

src/tests/Regressions/coreclr/GitHub_76531/dependencytodelete.csproj

-9
This file was deleted.

src/tests/Regressions/coreclr/GitHub_76531/tailcallinvoker.il

-17
This file was deleted.

src/tests/Regressions/coreclr/GitHub_76531/tailcallinvoker.ilproj

-10
This file was deleted.

0 commit comments

Comments
 (0)