@@ -929,8 +929,18 @@ ProcessCLRExceptionNew(IN PEXCEPTION_RECORD pExceptionRecord,
929
929
else
930
930
{
931
931
GCX_COOP ();
932
- OBJECTREF oref = ExceptionTracker::CreateThrowable (pExceptionRecord, FALSE );
933
- DispatchManagedException (oref, pContextRecord);
932
+ ThreadExceptionState* pExState = pThread->GetExceptionState ();
933
+ ExInfo *pPrevExInfo = (ExInfo*)pExState->GetCurrentExceptionTracker ();
934
+ if (pPrevExInfo != NULL && pPrevExInfo->m_DebuggerExState .GetDebuggerInterceptContext () != NULL )
935
+ {
936
+ ContinueExceptionInterceptionUnwind ();
937
+ UNREACHABLE ();
938
+ }
939
+ else
940
+ {
941
+ OBJECTREF oref = ExceptionTracker::CreateThrowable (pExceptionRecord, FALSE );
942
+ DispatchManagedException (oref, pContextRecord);
943
+ }
934
944
}
935
945
#endif // !HOST_UNIX
936
946
EEPOLICY_HANDLE_FATAL_ERROR_WITH_MESSAGE (COR_E_EXECUTIONENGINE, _T (" SEH exception leaked into managed code" ));
@@ -4299,9 +4309,12 @@ EXCEPTION_DISPOSITION ClrDebuggerDoUnwindAndIntercept(X86_FIRST_ARG(EXCEPTION_RE
4299
4309
{
4300
4310
GCX_COOP ();
4301
4311
4312
+ ExInfo* pExInfo = (ExInfo*)pExState->GetCurrentExceptionTracker ();
4313
+ _ASSERTE (pExInfo != NULL );
4314
+
4302
4315
PREPARE_NONVIRTUAL_CALLSITE (METHOD__EH__UNWIND_AND_INTERCEPT);
4303
4316
DECLARE_ARGHOLDER_ARRAY (args, 2 );
4304
- args[ARGNUM_0] = PTR_TO_ARGHOLDER (pExState-> GetCurrentExceptionTracker () );
4317
+ args[ARGNUM_0] = PTR_TO_ARGHOLDER (pExInfo );
4305
4318
args[ARGNUM_1] = PTR_TO_ARGHOLDER (uInterceptStackFrame);
4306
4319
pThread->IncPreventAbort ();
4307
4320
@@ -7532,29 +7545,55 @@ void MarkInlinedCallFrameAsEHHelperCall(Frame* pFrame)
7532
7545
pInlinedCallFrame->m_Datum = (PTR_NDirectMethodDesc)((TADDR)pInlinedCallFrame->m_Datum | (TADDR)InlinedCallFrameMarker::ExceptionHandlingHelper);
7533
7546
}
7534
7547
7548
+ static TADDR GetSpForDiagnosticReporting (REGDISPLAY *pRD)
7549
+ {
7550
+ #ifdef ESTABLISHER_FRAME_ADDRESS_IS_CALLER_SP
7551
+ return CallerStackFrame::FromRegDisplay (pRD).SP ;
7552
+ #else
7553
+ return GetSP (pRD->pCurrentContext );
7554
+ #endif
7555
+ }
7556
+
7535
7557
extern " C" void QCALLTYPE AppendExceptionStackFrame (QCall::ObjectHandleOnStack exceptionObj, SIZE_T ip, SIZE_T sp, int flags, ExInfo *pExInfo)
7536
7558
{
7537
7559
QCALL_CONTRACT;
7538
7560
7539
7561
BEGIN_QCALL;
7540
- GCX_COOP ();
7541
7562
7542
7563
Thread* pThread = GET_THREAD ();
7543
- Frame* pFrame = pThread->GetFrame ();
7544
- MarkInlinedCallFrameAsFuncletCall (pFrame);
7545
7564
7546
- bool canAllocateMemory = !(exceptionObj.Get () == CLRException::GetPreallocatedOutOfMemoryException ()) &&
7547
- !(exceptionObj.Get () == CLRException::GetPreallocatedStackOverflowException ());
7565
+ {
7566
+ GCX_COOP ();
7567
+
7568
+ Frame* pFrame = pThread->GetFrame ();
7569
+ MarkInlinedCallFrameAsEHHelperCall (pFrame);
7548
7570
7549
- MethodDesc *pMD = pExInfo->m_frameIter .m_crawl .GetFunction ();
7571
+ bool canAllocateMemory = !(exceptionObj.Get () == CLRException::GetPreallocatedOutOfMemoryException ()) &&
7572
+ !(exceptionObj.Get () == CLRException::GetPreallocatedStackOverflowException ());
7573
+
7574
+ MethodDesc *pMD = pExInfo->m_frameIter .m_crawl .GetFunction ();
7550
7575
#if _DEBUG
7551
- EECodeInfo codeInfo (ip);
7552
- _ASSERTE (codeInfo.IsValid ());
7553
- _ASSERTE (pMD == codeInfo.GetMethodDesc ());
7576
+ EECodeInfo codeInfo (ip);
7577
+ _ASSERTE (codeInfo.IsValid ());
7578
+ _ASSERTE (pMD == codeInfo.GetMethodDesc ());
7554
7579
#endif // _DEBUG
7555
7580
7556
- pExInfo->m_StackTraceInfo .AppendElement (canAllocateMemory, ip, sp, pMD, &pExInfo->m_frameIter .m_crawl );
7557
- pExInfo->m_StackTraceInfo .SaveStackTrace (canAllocateMemory, pExInfo->m_hThrowable , /* bReplaceStack*/ FALSE , /* bSkipLastElement*/ FALSE );
7581
+ // Compensate for a bug in the old EH that doesn't mark faulting instructions as faulting. The VS expects that behavior.
7582
+ bool hasFaulted = pExInfo->m_frameIter .m_crawl .HasFaulted ();
7583
+ if (hasFaulted)
7584
+ {
7585
+ pExInfo->m_frameIter .m_crawl .hasFaulted = false ;
7586
+ }
7587
+ pExInfo->m_StackTraceInfo .AppendElement (canAllocateMemory, ip, sp, pMD, &pExInfo->m_frameIter .m_crawl );
7588
+ pExInfo->m_StackTraceInfo .SaveStackTrace (canAllocateMemory, pExInfo->m_hThrowable , /* bReplaceStack*/ FALSE , /* bSkipLastElement*/ FALSE );
7589
+ pExInfo->m_frameIter .m_crawl .hasFaulted = hasFaulted;
7590
+ }
7591
+
7592
+ // Notify the debugger that we are on the first pass for a managed exception.
7593
+ // Note that this callback is made for every managed frame.
7594
+ TADDR spForDebugger = GetSpForDiagnosticReporting (pExInfo->m_frameIter .m_crawl .GetRegisterSet ());
7595
+ EEToDebuggerExceptionInterfaceWrapper::FirstChanceManagedException (pThread, ip, spForDebugger);
7596
+
7558
7597
if (!pExInfo->DeliveredFirstChanceNotification ())
7559
7598
{
7560
7599
ExceptionNotifications::DeliverFirstChanceNotification ();
@@ -7589,15 +7628,6 @@ UINT_PTR GetEstablisherFrame(REGDISPLAY* pvRegDisplay, ExInfo* exInfo)
7589
7628
#endif
7590
7629
}
7591
7630
7592
- static TADDR GetSpForDiagnosticReporting (REGDISPLAY *pRD)
7593
- {
7594
- #ifdef ESTABLISHER_FRAME_ADDRESS_IS_CALLER_SP
7595
- return CallerStackFrame::FromRegDisplay (pRD).SP ;
7596
- #else
7597
- return GetSP (pRD->pCurrentContext );
7598
- #endif
7599
- }
7600
-
7601
7631
extern " C" void * QCALLTYPE CallCatchFunclet (QCall::ObjectHandleOnStack exceptionObj, BYTE* pHandlerIP, REGDISPLAY* pvRegDisplay, ExInfo* exInfo)
7602
7632
{
7603
7633
QCALL_CONTRACT;
@@ -7663,25 +7693,32 @@ extern "C" void * QCALLTYPE CallCatchFunclet(QCall::ObjectHandleOnStack exceptio
7663
7693
BOOL fIntercepted = pThread->GetExceptionState ()->GetFlags ()->DebuggerInterceptInfo ();
7664
7694
if (fIntercepted )
7665
7695
{
7696
+ _ASSERTE (pHandlerIP == NULL );
7666
7697
// retrieve the interception information
7667
7698
MethodDesc *pInterceptMD = NULL ;
7668
7699
StackFrame sfInterceptStackFrame;
7669
7700
UINT_PTR uResumePC = 0 ;
7670
7701
ULONG_PTR ulRelOffset;
7671
7702
7672
7703
pThread->GetExceptionState ()->GetDebuggerState ()->GetDebuggerInterceptInfo (&pInterceptMD, NULL , (PBYTE*)&(sfInterceptStackFrame.SP ), &ulRelOffset, NULL );
7704
+ if (sfInterceptStackFrame.SP == GetSP (pvRegDisplay->pCurrentContext ))
7705
+ {
7706
+ PCODE pStartAddress = pInterceptMD->GetNativeCode ();
7673
7707
7674
- PCODE pStartAddress = pInterceptMD->GetNativeCode ();
7675
-
7676
- EECodeInfo codeInfo (pStartAddress);
7677
- _ASSERTE (codeInfo.IsValid ());
7708
+ EECodeInfo codeInfo (pStartAddress);
7709
+ _ASSERTE (codeInfo.IsValid ());
7678
7710
7679
- // Note that the value returned for ulRelOffset is actually the offset,
7680
- // so we need to adjust it to get the actual IP.
7681
- _ASSERTE (FitsIn<DWORD>(ulRelOffset));
7682
- uResumePC = codeInfo.GetJitManager ()->GetCodeAddressForRelOffset (codeInfo.GetMethodToken (), static_cast <DWORD>(ulRelOffset));
7711
+ // Note that the value returned for ulRelOffset is actually the offset,
7712
+ // so we need to adjust it to get the actual IP.
7713
+ _ASSERTE (FitsIn<DWORD>(ulRelOffset));
7714
+ uResumePC = codeInfo.GetJitManager ()->GetCodeAddressForRelOffset (codeInfo.GetMethodToken (), static_cast <DWORD>(ulRelOffset));
7683
7715
7684
- SetIP (pvRegDisplay->pCurrentContext , uResumePC);
7716
+ SetIP (pvRegDisplay->pCurrentContext , uResumePC);
7717
+ }
7718
+ else
7719
+ {
7720
+ fIntercepted = FALSE ;
7721
+ }
7685
7722
}
7686
7723
#endif // DEBUGGING_SUPPORTED
7687
7724
@@ -7797,6 +7834,10 @@ extern "C" void QCALLTYPE ResumeAtInterceptionLocation(REGDISPLAY* pvRegDisplay)
7797
7834
MarkInlinedCallFrameAsFuncletCall (pFrame);
7798
7835
7799
7836
UINT_PTR targetSp = GetSP (pvRegDisplay->pCurrentContext );
7837
+ ExInfo *pExInfo = (PTR_ExInfo)pThread->GetExceptionState ()->GetCurrentExceptionTracker ();
7838
+
7839
+ pExInfo->m_ScannedStackRange .ExtendUpperBound (targetSp);
7840
+
7800
7841
PopExplicitFrames (pThread, (void *)targetSp);
7801
7842
7802
7843
// This must be done before we pop the ExInfos.
@@ -8135,10 +8176,6 @@ static void NotifyFunctionEnter(StackFrameIterator *pThis, Thread *pThread, ExIn
8135
8176
EEToProfilerExceptionInterfaceWrapper::ExceptionSearchFunctionLeave (pExInfo->m_pMDToReportFunctionLeave );
8136
8177
}
8137
8178
EEToProfilerExceptionInterfaceWrapper::ExceptionSearchFunctionEnter (pMD);
8138
- // Notify the debugger that we are on the first pass for a managed exception.
8139
- // Note that this callback is made for every managed frame.
8140
- TADDR spForDebugger = GetSpForDiagnosticReporting (pThis->m_crawl .GetRegisterSet ());
8141
- EEToDebuggerExceptionInterfaceWrapper::FirstChanceManagedException (pThread, GetControlPC (pThis->m_crawl .GetRegisterSet ()), spForDebugger);
8142
8179
}
8143
8180
else
8144
8181
{
@@ -8169,8 +8206,7 @@ extern "C" bool QCALLTYPE SfiInit(StackFrameIterator* pThis, CONTEXT* pStackwalk
8169
8206
// just clear the thread state.
8170
8207
pThread->ResetThrowControlForThread ();
8171
8208
8172
- // Skip the SfiInit pinvoke frame
8173
- pFrame = pThread->GetFrame ()->PtrNextFrame ();
8209
+ pFrame = pExInfo->m_pInitialFrame ;
8174
8210
8175
8211
NotifyExceptionPassStarted (pThis, pThread, pExInfo);
8176
8212
@@ -8215,6 +8251,7 @@ extern "C" bool QCALLTYPE SfiInit(StackFrameIterator* pThis, CONTEXT* pStackwalk
8215
8251
!(pExInfo->m_exception == CLRException::GetPreallocatedStackOverflowException ());
8216
8252
8217
8253
pExInfo->m_StackTraceInfo .AppendElement (canAllocateMemory, NULL , GetRegdisplaySP (pExInfo->m_frameIter .m_crawl .GetRegisterSet ()), pMD, &pExInfo->m_frameIter .m_crawl );
8254
+ pExInfo->m_StackTraceInfo .SaveStackTrace (canAllocateMemory, pExInfo->m_hThrowable , /* bReplaceStack*/ FALSE , /* bSkipLastElement*/ FALSE );
8218
8255
8219
8256
#if defined(DEBUGGING_SUPPORTED)
8220
8257
if (NotifyDebuggerOfStub (pThread, pFrame))
@@ -8461,6 +8498,8 @@ extern "C" bool QCALLTYPE SfiNext(StackFrameIterator* pThis, uint* uExCollideCla
8461
8498
!(pTopExInfo->m_exception == CLRException::GetPreallocatedStackOverflowException ());
8462
8499
8463
8500
pTopExInfo->m_StackTraceInfo .AppendElement (canAllocateMemory, NULL , GetRegdisplaySP (pTopExInfo->m_frameIter .m_crawl .GetRegisterSet ()), pMD, &pTopExInfo->m_frameIter .m_crawl );
8501
+ pTopExInfo->m_StackTraceInfo .SaveStackTrace (canAllocateMemory, pTopExInfo->m_hThrowable , /* bReplaceStack*/ FALSE , /* bSkipLastElement*/ FALSE );
8502
+
8464
8503
#if defined(DEBUGGING_SUPPORTED)
8465
8504
if (NotifyDebuggerOfStub (pThread, pFrame))
8466
8505
{
0 commit comments