Skip to content

Commit 83d1100

Browse files
authored
Fix x86 exception handling edge case (#113760)
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 #113106
1 parent 8b1111d commit 83d1100

File tree

2 files changed

+12
-5
lines changed

2 files changed

+12
-5
lines changed

src/coreclr/vm/excep.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6780,15 +6780,15 @@ VEH_ACTION WINAPI CLRVectoredExceptionHandlerPhase3(PEXCEPTION_POINTERS pExcepti
67806780
// the subsequent logic here sees a managed fault.
67816781
//
67826782
// On 64-bit, some additional work is required..
6783-
#ifdef FEATURE_EH_FUNCLETS
67846783
pContext->ContextFlags &= ~CONTEXT_EXCEPTION_ACTIVE;
6784+
#ifdef FEATURE_EH_FUNCLETS
67856785
return VEH_EXECUTE_HANDLE_MANAGED_EXCEPTION;
67866786
#endif // defined(FEATURE_EH_FUNCLETS)
67876787
}
67886788
else if (AdjustContextForVirtualStub(pExceptionRecord, pContext))
67896789
{
6790-
#ifdef FEATURE_EH_FUNCLETS
67916790
pContext->ContextFlags &= ~CONTEXT_EXCEPTION_ACTIVE;
6791+
#ifdef FEATURE_EH_FUNCLETS
67926792
return VEH_EXECUTE_HANDLE_MANAGED_EXCEPTION;
67936793
#endif
67946794
}
@@ -7119,9 +7119,7 @@ LONG WINAPI CLRVectoredExceptionHandlerShim(PEXCEPTION_POINTERS pExceptionInfo)
71197119
// WARNING WARNING WARNING WARNING WARNING WARNING WARNING
71207120
//
71217121

7122-
#ifdef FEATURE_EH_FUNCLETS
71237122
pExceptionInfo->ContextRecord->ContextFlags |= CONTEXT_EXCEPTION_ACTIVE;
7124-
#endif // FEATURE_EH_FUNCLETS
71257123

71267124
// WARNING
71277125
//

src/coreclr/vm/stackwalk.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3212,8 +3212,17 @@ void StackFrameIterator::PostProcessingForNoFrameTransition()
32123212

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

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

0 commit comments

Comments
 (0)