Skip to content

Commit 3668a6f

Browse files
committed
Fix x86 exception handling edge case
When a NULL reference exception occurs in a JIT helper or a VSD stub, runtime pretends the exception occured in the managed caller. There is a bug on x86 Windows where the COMPlusThrowCallback considers that frame to be the frame where the exception actually occurred (based on the m_crawl.isFirst). In case the call to the helper is the last instruction in a try region, the exception handler lookup would reject that address and the exception may not get handled at the right place or at all. This change fixes it by ensuring that the m_crawl.isFirst is not set when the frame is not the frame of the failure. Close dotnet#113106
1 parent 7bffa54 commit 3668a6f

File tree

2 files changed

+12
-5
lines changed

2 files changed

+12
-5
lines changed

src/coreclr/vm/excep.cpp

+2-4
Original file line numberDiff line numberDiff line change
@@ -6779,15 +6779,15 @@ VEH_ACTION WINAPI CLRVectoredExceptionHandlerPhase3(PEXCEPTION_POINTERS pExcepti
67796779
// the subsequent logic here sees a managed fault.
67806780
//
67816781
// On 64-bit, some additional work is required..
6782-
#ifdef FEATURE_EH_FUNCLETS
67836782
pContext->ContextFlags &= ~CONTEXT_EXCEPTION_ACTIVE;
6783+
#ifdef FEATURE_EH_FUNCLETS
67846784
return VEH_EXECUTE_HANDLE_MANAGED_EXCEPTION;
67856785
#endif // defined(FEATURE_EH_FUNCLETS)
67866786
}
67876787
else if (AdjustContextForVirtualStub(pExceptionRecord, pContext))
67886788
{
6789-
#ifdef FEATURE_EH_FUNCLETS
67906789
pContext->ContextFlags &= ~CONTEXT_EXCEPTION_ACTIVE;
6790+
#ifdef FEATURE_EH_FUNCLETS
67916791
return VEH_EXECUTE_HANDLE_MANAGED_EXCEPTION;
67926792
#endif
67936793
}
@@ -7118,9 +7118,7 @@ LONG WINAPI CLRVectoredExceptionHandlerShim(PEXCEPTION_POINTERS pExceptionInfo)
71187118
// WARNING WARNING WARNING WARNING WARNING WARNING WARNING
71197119
//
71207120

7121-
#ifdef FEATURE_EH_FUNCLETS
71227121
pExceptionInfo->ContextRecord->ContextFlags |= CONTEXT_EXCEPTION_ACTIVE;
7123-
#endif // FEATURE_EH_FUNCLETS
71247122

71257123
// WARNING
71267124
//

src/coreclr/vm/stackwalk.cpp

+10-1
Original file line numberDiff line numberDiff line change
@@ -3207,8 +3207,17 @@ void StackFrameIterator::PostProcessingForNoFrameTransition()
32073207

32083208
// Flags the same as from a FaultingExceptionFrame.
32093209
m_crawl.isInterrupted = true;
3210-
m_crawl.hasFaulted = true;
3210+
m_crawl.hasFaulted = (pContext->ContextFlags & CONTEXT_EXCEPTION_ACTIVE) != 0;
32113211
m_crawl.isIPadjusted = false;
3212+
if (!m_crawl.hasFaulted)
3213+
{
3214+
// If the context is from a hardware exception that happened in a helper where we have unwound
3215+
// the exception location to the caller of the helper, the frame needs to be marked as not
3216+
// being the first one. The COMPlusThrowCallback uses this information to decide whether
3217+
// the current IP should or should not be included in the try region range. The call to
3218+
// the helper that has fired the exception may be the last instruction in the try region.
3219+
m_crawl.isFirst = false;
3220+
}
32123221

32133222
#if defined(STACKWALKER_MAY_POP_FRAMES)
32143223
// If Frames would be unlinked from the Frame chain, also reset the UseExInfoForStackwalk bit

0 commit comments

Comments
 (0)