Skip to content

Commit 737e35e

Browse files
authored
Fix Win64 exception propagation in NativeCallable methods (#33653)
A recent change has removed the UMThunkStub usage for native callable methods. That has broken handling of exceptions propagated from the managed native callable method into the native caller in case there were explicit frames below the native frame, like during the GC stress 3. This change fixes it by unwinding the explicit frames upto the native frame during the 2nd pass of exception handling when exception unwinding passes through the frame of a native callable method and isn't handled there.
1 parent bedc8d5 commit 737e35e

File tree

1 file changed

+19
-1
lines changed

1 file changed

+19
-1
lines changed

src/coreclr/src/vm/exceptionhandling.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -818,6 +818,8 @@ UINT_PTR ExceptionTracker::FinishSecondPass(
818818
return uResumePC;
819819
}
820820

821+
void CleanUpForSecondPass(Thread* pThread, bool fIsSO, LPVOID MemoryStackFpForFrameChain, LPVOID MemoryStackFp);
822+
821823
// On CoreARM, the MemoryStackFp is ULONG when passed by RtlDispatchException,
822824
// unlike its 64bit counterparts.
823825
EXTERN_C EXCEPTION_DISPOSITION
@@ -1262,6 +1264,22 @@ lExit: ;
12621264

12631265
if ((ExceptionContinueSearch == returnDisposition))
12641266
{
1267+
if (dwExceptionFlags & EXCEPTION_UNWINDING)
1268+
{
1269+
EECodeInfo codeInfo(pDispatcherContext->ControlPc);
1270+
if (codeInfo.IsValid())
1271+
{
1272+
GcInfoDecoder gcInfoDecoder(codeInfo.GetGCInfoToken(), DECODE_REVERSE_PINVOKE_VAR);
1273+
if (gcInfoDecoder.GetReversePInvokeFrameStackSlot() != NO_REVERSE_PINVOKE_FRAME)
1274+
{
1275+
// Exception is being propagated from a native callable method into its native caller.
1276+
// The explicit frame chain needs to be unwound at this boundary.
1277+
bool fIsSO = pExceptionRecord->ExceptionCode == STATUS_STACK_OVERFLOW;
1278+
CleanUpForSecondPass(pThread, fIsSO, (void*)MemoryStackFp, (void*)MemoryStackFp);
1279+
}
1280+
}
1281+
}
1282+
12651283
GCX_PREEMP_NO_DTOR();
12661284
}
12671285

@@ -5824,7 +5842,7 @@ BOOL IsSafeToUnwindFrameChain(Thread* pThread, LPVOID MemoryStackFpForFrameChain
58245842
// We're safe only if the managed method will be unwound also
58255843
LPVOID managedSP = dac_cast<PTR_VOID>(GetRegdisplaySP(&rd));
58265844

5827-
if (managedSP < MemoryStackFpForFrameChain)
5845+
if (managedSP <= MemoryStackFpForFrameChain)
58285846
{
58295847
return TRUE;
58305848
}

0 commit comments

Comments
 (0)