Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 36 additions & 107 deletions src/coreclr/vm/exceptionhandling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ ClrUnwindEx(EXCEPTION_RECORD* pExceptionRecord,
UINT_PTR TargetFrameSp);
#endif // !TARGET_UNIX

EXCEPTION_HANDLER_DECL(CallDescrWorkerUnwindFrameChainHandler);
EXCEPTION_HANDLER_DECL(ReverseComUnwindFrameChainHandler);
EXCEPTION_HANDLER_DECL(HijackHandler);
EXCEPTION_HANDLER_DECL(FixRedirectContextHandler);
EXCEPTION_HANDLER_DECL(UMEntryPrestubUnwindFrameChainHandler);

#if defined(TARGET_UNIX) && !defined(DACCESS_COMPILE)
VOID UnwindManagedExceptionPass2(PAL_SEHException& ex, CONTEXT* unwindStartContext);
#endif // TARGET_UNIX && !DACCESS_COMPILE
Expand Down Expand Up @@ -915,12 +921,7 @@ static void PopExplicitFrames(Thread *pThread, void *targetSp, void *targetCalle
}
}

EXTERN_C EXCEPTION_DISPOSITION
ProcessCLRExceptionNew(IN PEXCEPTION_RECORD pExceptionRecord,
IN PVOID pEstablisherFrame,
IN OUT PCONTEXT pContextRecord,
IN OUT PDISPATCHER_CONTEXT pDispatcherContext
)
EXCEPTION_HANDLER_IMPL(ProcessCLRExceptionNew)
{
//
// This method doesn't always return, so it will leave its
Expand Down Expand Up @@ -977,20 +978,15 @@ ProcessCLRExceptionNew(IN PEXCEPTION_RECORD pExceptionRecord,
else
{
OBJECTREF oref = ExceptionTracker::CreateThrowable(pExceptionRecord, FALSE);
DispatchManagedException(oref, pContextRecord, pExceptionRecord);
DispatchManagedException(oref, pContext, pExceptionRecord);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A nit - can we please keep the name pContextRecord at places where you have renamed it? It would make this change much smaller and it would match the Windows naming (e.g. in RtlVirtualUnwind and other similar functions). It is also usually used in locations where the exception record so that the two names match.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I renamed it to follow the existing macro. If I were to change the macro then an equal number of places elsewhere would have the be modified.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer taking the non-x86 stuff as the standard. The x86 has always been a bit different at various places for historical reasons.

}
}
#endif // !HOST_UNIX
EEPOLICY_HANDLE_FATAL_ERROR_WITH_MESSAGE(COR_E_EXECUTIONENGINE, _T("SEH exception leaked into managed code"));
UNREACHABLE();
}

EXTERN_C EXCEPTION_DISPOSITION
ProcessCLRException(IN PEXCEPTION_RECORD pExceptionRecord,
IN PVOID pEstablisherFrame,
IN OUT PCONTEXT pContextRecord,
IN OUT PDISPATCHER_CONTEXT pDispatcherContext
)
EXCEPTION_HANDLER_IMPL(ProcessCLRException)
{
//
// This method doesn't always return, so it will leave its
Expand All @@ -1002,7 +998,7 @@ ProcessCLRException(IN PEXCEPTION_RECORD pExceptionRecord,

if (g_isNewExceptionHandlingEnabled)
{
return ProcessCLRExceptionNew(pExceptionRecord, pEstablisherFrame, pContextRecord, pDispatcherContext);
return ProcessCLRExceptionNew(pExceptionRecord, pEstablisherFrame, pContext, pDispatcherContext);
}

// We must preserve this so that GCStress=4 eh processing doesnt kill last error.
Expand All @@ -1013,8 +1009,8 @@ ProcessCLRException(IN PEXCEPTION_RECORD pExceptionRecord,
STRESS_LOG5(LF_EH, LL_INFO10, "Processing exception at establisher=%p, ip=%p disp->cxr: %p, sp: %p, cxr @ exception: %p\n",
pEstablisherFrame, pDispatcherContext->ControlPc,
pDispatcherContext->ContextRecord,
GetSP(pDispatcherContext->ContextRecord), pContextRecord);
AMD64_ONLY(STRESS_LOG3(LF_EH, LL_INFO10, " rbx=%p, rsi=%p, rdi=%p\n", pContextRecord->Rbx, pContextRecord->Rsi, pContextRecord->Rdi));
GetSP(pDispatcherContext->ContextRecord), pContext);
AMD64_ONLY(STRESS_LOG3(LF_EH, LL_INFO10, " rbx=%p, rsi=%p, rdi=%p\n", pContext->Rbx, pContext->Rsi, pContext->Rdi));

// sample flags early on because we may change pExceptionRecord below
// if we are seeing a STATUS_UNWIND_CONSOLIDATE
Expand Down Expand Up @@ -1130,7 +1126,7 @@ ProcessCLRException(IN PEXCEPTION_RECORD pExceptionRecord,
(pExceptionRecord->ExceptionCode == STATUS_SINGLE_STEP))
{
// It is a breakpoint; is it from the runtime or managed code?
PCODE ip = GetIP(pContextRecord); // IP of the fault.
PCODE ip = GetIP(pContext); // IP of the fault.

BOOL fExternalException;

Expand Down Expand Up @@ -1160,7 +1156,7 @@ ProcessCLRException(IN PEXCEPTION_RECORD pExceptionRecord,
pDispatcherContext->ControlPc,
sf,
pExceptionRecord,
pContextRecord,
pContext,
bAsynchronousThreadStop,
!(dwExceptionFlags & EXCEPTION_UNWINDING),
&STState);
Expand Down Expand Up @@ -1214,7 +1210,7 @@ ProcessCLRException(IN PEXCEPTION_RECORD pExceptionRecord,

status = pTracker->ProcessOSExceptionNotification(
pExceptionRecord,
pContextRecord,
pContext,
pDispatcherContext,
dwExceptionFlags,
sf,
Expand Down Expand Up @@ -1268,11 +1264,11 @@ ProcessCLRException(IN PEXCEPTION_RECORD pExceptionRecord,
{
bool fAborting = false;
UINT_PTR uResumePC = (UINT_PTR)-1;
UINT_PTR uOriginalSP = GetSP(pContextRecord);
UINT_PTR uOriginalSP = GetSP(pContext);

Frame* pLimitFrame = pTracker->GetLimitFrame();

pDispatcherContext->ContextRecord = pContextRecord;
pDispatcherContext->ContextRecord = pContext;

// We may be in COOP mode at this point - the indefinite switch was done
// in ExceptionTracker::ProcessManagedCallFrame.
Expand All @@ -1291,7 +1287,7 @@ ProcessCLRException(IN PEXCEPTION_RECORD pExceptionRecord,
//
// Since CallCatchHandler expects to be in COOP mode, perform the switch here.
GCX_COOP_NO_DTOR();
uResumePC = pTracker->CallCatchHandler(pContextRecord, &fAborting);
uResumePC = pTracker->CallCatchHandler(pContext, &fAborting);

{
//
Expand All @@ -1318,11 +1314,11 @@ ProcessCLRException(IN PEXCEPTION_RECORD pExceptionRecord,
INDEBUG(pTracker = (ExceptionTracker*)POISONC);

// Note that we should only fail to fix up for SO.
bool fFixedUp = FixNonvolatileRegisters(uOriginalSP, pThread, pContextRecord, fAborting);
bool fFixedUp = FixNonvolatileRegisters(uOriginalSP, pThread, pContext, fAborting);
_ASSERTE(fFixedUp || (pExceptionRecord->ExceptionCode == STATUS_STACK_OVERFLOW));


CONSISTENCY_CHECK(pLimitFrame > dac_cast<PTR_VOID>(GetSP(pContextRecord)));
CONSISTENCY_CHECK(pLimitFrame > dac_cast<PTR_VOID>(GetSP(pContext)));
if (pICFSetAsLimitFrame != NULL)
{
_ASSERTE(pICFSetAsLimitFrame == pLimitFrame);
Expand All @@ -1337,9 +1333,9 @@ ProcessCLRException(IN PEXCEPTION_RECORD pExceptionRecord,

pThread->SetFrame(pLimitFrame);

FixContext(pContextRecord);
FixContext(pContext);

SetIP(pContextRecord, (PCODE)uResumePC);
SetIP(pContext, (PCODE)uResumePC);
}

#ifdef STACK_GUARDS_DEBUG
Expand All @@ -1351,10 +1347,10 @@ ProcessCLRException(IN PEXCEPTION_RECORD pExceptionRecord,
#ifdef TARGET_AMD64
// OSes older than Win8 have a bug where RtlUnwindEx passes meaningless ContextFlags to the personality routine in
// some cases.
pContextRecord->ContextFlags |= CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT;
pContext->ContextFlags |= CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT;
#endif

ExceptionTracker::ResumeExecution(pContextRecord);
ExceptionTracker::ResumeExecution(pContext);
UNREACHABLE();
}
}
Expand Down Expand Up @@ -4656,7 +4652,7 @@ VOID UnwindManagedExceptionPass2(PAL_SEHException& ex, CONTEXT* unwindStartConte

// Perform unwinding of the current frame
disposition = ProcessCLRException(exceptionRecord,
(void*)establisherFrame,
(struct _EXCEPTION_REGISTRATION_RECORD *)establisherFrame,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks strange, the establisherFrame isn't a struct like this. Is is purely a stack pointer.

currentFrameContext,
&dispatcherContext);

Expand Down Expand Up @@ -4849,7 +4845,7 @@ VOID DECLSPEC_NORETURN UnwindManagedExceptionPass1(PAL_SEHException& ex, CONTEXT

// Find exception handler in the current frame
disposition = ProcessCLRException(ex.GetExceptionRecord(),
(void*)establisherFrame,
(struct _EXCEPTION_REGISTRATION_RECORD *)establisherFrame,
ex.GetContextRecord(),
&dispatcherContext);

Expand Down Expand Up @@ -6050,12 +6046,7 @@ BOOL FirstCallToHandler (
}


EXTERN_C EXCEPTION_DISPOSITION
HijackHandler(IN PEXCEPTION_RECORD pExceptionRecord,
IN PVOID pEstablisherFrame,
IN OUT PCONTEXT pContextRecord,
IN OUT PDISPATCHER_CONTEXT pDispatcherContext
)
EXCEPTION_HANDLER_IMPL(HijackHandler)
{
CONTRACTL
{
Expand All @@ -6069,7 +6060,7 @@ HijackHandler(IN PEXCEPTION_RECORD pExceptionRecord,
pDispatcherContext->EstablisherFrame,
pDispatcherContext->ContextRecord,
GetSP(pDispatcherContext->ContextRecord),
pContextRecord);
pContext);

Thread* pThread = GetThread();
CONTEXT *pNewContext = NULL;
Expand Down Expand Up @@ -6240,12 +6231,7 @@ UnhandledExceptionHandlerUnix(

#else // TARGET_UNIX

EXTERN_C EXCEPTION_DISPOSITION
UMThunkUnwindFrameChainHandler(IN PEXCEPTION_RECORD pExceptionRecord,
IN PVOID pEstablisherFrame,
IN OUT PCONTEXT pContextRecord,
IN OUT PDISPATCHER_CONTEXT pDispatcherContext
)
EXCEPTION_HANDLER_IMPL(UMThunkUnwindFrameChainHandler)
{
Thread* pThread = GetThreadNULLOk();
if (pThread == NULL) {
Expand Down Expand Up @@ -6284,68 +6270,22 @@ UMThunkUnwindFrameChainHandler(IN PEXCEPTION_RECORD pExceptionRecord,
return ExceptionContinueSearch;
}

EXTERN_C EXCEPTION_DISPOSITION
UMEntryPrestubUnwindFrameChainHandler(
IN PEXCEPTION_RECORD pExceptionRecord,
IN PVOID pEstablisherFrame,
IN OUT PCONTEXT pContextRecord,
IN OUT PDISPATCHER_CONTEXT pDispatcherContext
)
{
EXCEPTION_DISPOSITION disposition = UMThunkUnwindFrameChainHandler(
pExceptionRecord,
pEstablisherFrame,
pContextRecord,
pDispatcherContext
);

return disposition;
}

EXTERN_C EXCEPTION_DISPOSITION
UMThunkStubUnwindFrameChainHandler(
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This handler is no longer used.

IN PEXCEPTION_RECORD pExceptionRecord,
IN PVOID pEstablisherFrame,
IN OUT PCONTEXT pContextRecord,
IN OUT PDISPATCHER_CONTEXT pDispatcherContext
)
EXCEPTION_HANDLER_IMPL(UMEntryPrestubUnwindFrameChainHandler)
{

#ifdef _DEBUG
// If the exception is escaping the last CLR personality routine on the stack,
// then state a flag on the thread to indicate so.
//
// We check for thread object since this function is the personality routine of the UMThunk
// and we can landup here even when thread creation (within the thunk) fails.
if (GetThreadNULLOk() != NULL)
{
SetReversePInvokeEscapingUnhandledExceptionStatus(IS_UNWINDING(pExceptionRecord->ExceptionFlags),
pEstablisherFrame
);
}
#endif // _DEBUG

EXCEPTION_DISPOSITION disposition = UMThunkUnwindFrameChainHandler(
pExceptionRecord,
pEstablisherFrame,
pContextRecord,
pContext,
pDispatcherContext
);

return disposition;
}


// This is the personality routine setup for the assembly helper (CallDescrWorker) that calls into
// managed code.
EXTERN_C EXCEPTION_DISPOSITION
CallDescrWorkerUnwindFrameChainHandler(IN PEXCEPTION_RECORD pExceptionRecord,
IN PVOID pEstablisherFrame,
IN OUT PCONTEXT pContextRecord,
IN OUT PDISPATCHER_CONTEXT pDispatcherContext
)
EXCEPTION_HANDLER_IMPL(CallDescrWorkerUnwindFrameChainHandler)
{

Thread* pThread = GetThread();
if (pExceptionRecord->ExceptionCode == STATUS_STACK_OVERFLOW)
{
Expand All @@ -6366,7 +6306,7 @@ CallDescrWorkerUnwindFrameChainHandler(IN PEXCEPTION_RECORD pExceptionReco
{
retVal = ProcessCLRException(pExceptionRecord,
pEstablisherFrame,
pContextRecord,
pContext,
pDispatcherContext);
}
else
Expand All @@ -6393,12 +6333,7 @@ CallDescrWorkerUnwindFrameChainHandler(IN PEXCEPTION_RECORD pExceptionReco
#endif // TARGET_UNIX

#ifdef FEATURE_COMINTEROP
EXTERN_C EXCEPTION_DISPOSITION
ReverseComUnwindFrameChainHandler(IN PEXCEPTION_RECORD pExceptionRecord,
IN PVOID pEstablisherFrame,
IN OUT PCONTEXT pContextRecord,
IN OUT PDISPATCHER_CONTEXT pDispatcherContext
)
EXCEPTION_HANDLER_IMPL(ReverseComUnwindFrameChainHandler)
{
if (IS_UNWINDING(pExceptionRecord->ExceptionFlags))
{
Expand All @@ -6409,13 +6344,7 @@ ReverseComUnwindFrameChainHandler(IN PEXCEPTION_RECORD pExceptionRecord,
#endif // FEATURE_COMINTEROP

#ifndef TARGET_UNIX
EXTERN_C EXCEPTION_DISPOSITION
FixRedirectContextHandler(
IN PEXCEPTION_RECORD pExceptionRecord,
IN PVOID pEstablisherFrame,
IN OUT PCONTEXT pContextRecord,
IN OUT PDISPATCHER_CONTEXT pDispatcherContext
)
EXCEPTION_HANDLER_IMPL(FixRedirectContextHandler)
{
CONTRACTL
{
Expand All @@ -6428,7 +6357,7 @@ FixRedirectContextHandler(
STRESS_LOG4(LF_EH, LL_INFO10, "FixRedirectContextHandler: sp %p, establisher %p, cxr: %p, disp cxr: %p\n",
GetSP(pDispatcherContext->ContextRecord),
pDispatcherContext->EstablisherFrame,
pContextRecord,
pContext,
pDispatcherContext->ContextRecord);

CONTEXT *pRedirectedContext = GetCONTEXTFromRedirectedStubStackFrame(pDispatcherContext);
Expand Down
8 changes: 3 additions & 5 deletions src/coreclr/vm/exceptionhandling.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,9 @@
// Accessing it will result in AV.
#define INVALID_RESUME_ADDRESS 0x000000000000bad0

EXTERN_C EXCEPTION_DISPOSITION
ProcessCLRException(IN PEXCEPTION_RECORD pExceptionRecord,
IN PVOID pEstablisherFrame,
IN OUT PT_CONTEXT pContextRecord,
IN OUT PT_DISPATCHER_CONTEXT pDispatcherContext);
#ifndef DACCESS_COMPILE
EXCEPTION_HANDLER_DECL(ProcessCLRException);
#endif

VOID DECLSPEC_NORETURN DispatchManagedException(OBJECTREF throwable, CONTEXT *pExceptionContext, EXCEPTION_RECORD *pExceptionRecord = NULL);
VOID DECLSPEC_NORETURN DispatchManagedException(OBJECTREF throwable);
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/vm/exstate.h
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ class ThreadExceptionState
ThrowCallbackType& tct,
Frame *pStartFrame);

friend EXCEPTION_HANDLER_IMPL(COMPlusFrameHandler);
friend _EXCEPTION_HANDLER_DECL(COMPlusFrameHandler);

friend EXCEPTION_DISPOSITION __cdecl
CPFH_RealFirstPassHandler(EXCEPTION_RECORD *pExceptionRecord,
Expand Down
Loading