Skip to content
Merged
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
18 changes: 6 additions & 12 deletions src/coreclr/debug/ee/debugger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13191,19 +13191,14 @@ void STDCALL ExceptionHijackWorker(
// See code:ExceptionHijackPersonalityRoutine for more information.
//
// Arguments:
// * pExceptionRecord - not used
// * MemoryStackFp - not used
// * BackingStoreFp - not used
// * pContextRecord - not used
// * pDispatcherContext - not used
// * GlobalPointer - not used
// Standard personality routine signature.
//
// Return Value:
// Always return ExceptionContinueSearch.
//

EXCEPTION_DISPOSITION EmptyPersonalityRoutine(IN PEXCEPTION_RECORD pExceptionRecord,
IN ULONG64 MemoryStackFp,
IN PVOID pEstablisherFrame,
IN OUT PCONTEXT pContextRecord,
IN OUT PDISPATCHER_CONTEXT pDispatcherContext)
{
Expand All @@ -13216,7 +13211,7 @@ EXCEPTION_DISPOSITION EmptyPersonalityRoutine(IN PEXCEPTION_RECORD pExcept
// Personality routine for unwinder the assembly hijack stub on 64-bit.
//
// Arguments:
// standard Personality routine signature.
// Standard personality routine signature.
//
// Assumptions:
// This is caleld by the OS exception logic during exception handling.
Expand All @@ -13243,9 +13238,8 @@ EXCEPTION_DISPOSITION EmptyPersonalityRoutine(IN PEXCEPTION_RECORD pExcept
// On AMD64, we work around this by using an empty personality routine.

EXTERN_C EXCEPTION_DISPOSITION
ExceptionHijackPersonalityRoutine(IN PEXCEPTION_RECORD pExceptionRecord
BIT64_ARG(IN ULONG64 MemoryStackFp)
NOT_BIT64_ARG(IN ULONG32 MemoryStackFp),
ExceptionHijackPersonalityRoutine(IN PEXCEPTION_RECORD pExceptionRecord,
IN PVOID pEstablisherFrame,
IN OUT PCONTEXT pContextRecord,
IN OUT PDISPATCHER_CONTEXT pDispatcherContext
)
Expand All @@ -13268,7 +13262,7 @@ ExceptionHijackPersonalityRoutine(IN PEXCEPTION_RECORD pExceptionRecord

// This copies pHijackContext into pDispatcherContext, which the OS can then
// use to walk the stack.
FixupDispatcherContext(pDispatcherContext, pHijackContext, pContextRecord, (PEXCEPTION_ROUTINE)EmptyPersonalityRoutine);
FixupDispatcherContext(pDispatcherContext, pHijackContext, (PEXCEPTION_ROUTINE)EmptyPersonalityRoutine);
#else
_ASSERTE(!"NYI - ExceptionHijackPersonalityRoutine()");
#endif
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/debug/ee/debugger.h
Original file line number Diff line number Diff line change
Expand Up @@ -3872,7 +3872,7 @@ HANDLE OpenWin32EventOrThrow(
bool DbgIsSpecialILOffset(DWORD offset);

#if !defined(TARGET_X86)
void FixupDispatcherContext(T_DISPATCHER_CONTEXT* pDispatcherContext, T_CONTEXT* pContext, T_CONTEXT* pOriginalContext, PEXCEPTION_ROUTINE pUnwindPersonalityRoutine = NULL);
void FixupDispatcherContext(T_DISPATCHER_CONTEXT* pDispatcherContext, T_CONTEXT* pContext, PEXCEPTION_ROUTINE pUnwindPersonalityRoutine = NULL);
#endif

#endif /* DEBUGGER_H_ */
32 changes: 17 additions & 15 deletions src/coreclr/debug/ee/funceval.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3579,7 +3579,7 @@ static void GCProtectArgsAndDoNormalFuncEval(DebuggerEval *pDE,
GCX_FORBID();
RecordFuncEvalException( pDE, ppException);
}
// Note: we need to catch all exceptioins here because they all get reported as the result of
// Note: we need to catch all exceptions here because they all get reported as the result of
// the funceval. If a ThreadAbort occurred other than for a funcEval abort, we'll re-throw it manually.
EX_END_CATCH(SwallowAllExceptions);

Expand Down Expand Up @@ -3994,32 +3994,34 @@ void * STDCALL FuncEvalHijackWorker(DebuggerEval *pDE)
#if defined(FEATURE_EH_FUNCLETS) && !defined(TARGET_UNIX)

EXTERN_C EXCEPTION_DISPOSITION
FuncEvalHijackPersonalityRoutine(IN PEXCEPTION_RECORD pExceptionRecord
BIT64_ARG(IN ULONG64 MemoryStackFp)
NOT_BIT64_ARG(IN ULONG32 MemoryStackFp),
FuncEvalHijackPersonalityRoutine(IN PEXCEPTION_RECORD pExceptionRecord,
IN PVOID pEstablisherFrame,
IN OUT PCONTEXT pContextRecord,
IN OUT PDISPATCHER_CONTEXT pDispatcherContext
)
{
DebuggerEval* pDE = NULL;
// The offset of the DebuggerEval pointer relative to the establisher frame.
SIZE_T debuggerEvalPtrOffset = 0;
#if defined(TARGET_AMD64)
pDE = *(DebuggerEval**)(pDispatcherContext->EstablisherFrame);
// On AMD64 the establisher frame is the SP of FuncEvalHijack itself.
// In FuncEvalHijack we store RCX at the current SP.
debuggerEvalPtrOffset = 0;
#elif defined(TARGET_ARM)
// on ARM the establisher frame is the SP of the caller of FuncEvalHijack, on other platforms it's FuncEvalHijack's SP.
// in FuncEvalHijack we allocate 8 bytes of stack space and then store R0 at the current SP, so if we subtract 8 from
// On ARM the establisher frame is the SP of the FuncEvalHijack's caller.
// In FuncEvalHijack we allocate 8 bytes of stack space and then store R0 at the current SP, so if we subtract 8 from
// the establisher frame we can get the stack location where R0 was stored.
pDE = *(DebuggerEval**)(pDispatcherContext->EstablisherFrame - 8);

debuggerEvalPtrOffset = 8;
#elif defined(TARGET_ARM64)
// on ARM64 the establisher frame is the SP of the caller of FuncEvalHijack.
// in FuncEvalHijack we allocate 32 bytes of stack space and then store R0 at the current SP + 16, so if we subtract 16 from
// the establisher frame we can get the stack location where R0 was stored.
pDE = *(DebuggerEval**)(pDispatcherContext->EstablisherFrame - 16);
// On ARM64 the establisher frame is the SP of the FuncEvalHijack's caller.
// In FuncEvalHijack we allocate 32 bytes of stack space and then store X0 at the current SP + 16, so if we subtract 16 from
// the establisher frame we can get the stack location where X0 was stored.
debuggerEvalPtrOffset = 16;
#else
_ASSERTE(!"NYI - FuncEvalHijackPersonalityRoutine()");
#endif

FixupDispatcherContext(pDispatcherContext, &(pDE->m_context), pContextRecord);
DebuggerEval* pDE = *(DebuggerEval**)(pDispatcherContext->EstablisherFrame - debuggerEvalPtrOffset);
FixupDispatcherContext(pDispatcherContext, &(pDE->m_context));

// Returning ExceptionCollidedUnwind will cause the OS to take our new context record and
// dispatcher context and restart the exception dispatching on this call frame, which is
Expand Down
113 changes: 45 additions & 68 deletions src/coreclr/vm/excep.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5637,7 +5637,7 @@ LONG CallOutFilter(PEXCEPTION_POINTERS pExceptionInfo, PVOID pv)
{
CallOutFilterParam *pParam = static_cast<CallOutFilterParam *>(pv);

_ASSERTE(pParam->OneShot && (pParam->OneShot == TRUE || pParam->OneShot == FALSE));
_ASSERTE(pParam && (pParam->OneShot == TRUE || pParam->OneShot == FALSE));

if (pParam->OneShot == TRUE)
{
Expand Down Expand Up @@ -6576,10 +6576,7 @@ static LONG HandleManagedFaultFilter(EXCEPTION_POINTERS* ep, LPVOID pv)
return EXCEPTION_CONTINUE_SEARCH;
}

void HandleManagedFault(EXCEPTION_RECORD* pExceptionRecord,
CONTEXT* pContext,
EXCEPTION_REGISTRATION_RECORD* pEstablisherFrame,
Thread* pThread)
void HandleManagedFault(EXCEPTION_RECORD* pExceptionRecord, CONTEXT* pContext)
{
WRAPPER_NO_CONTRACT;

Expand Down Expand Up @@ -6726,27 +6723,16 @@ bool ShouldHandleManagedFault(

#ifndef TARGET_UNIX

LONG WINAPI CLRVectoredExceptionHandlerPhase2(PEXCEPTION_POINTERS pExceptionInfo);

enum VEH_ACTION
{
VEH_NO_ACTION = 0,
VEH_EXECUTE_HANDLE_MANAGED_EXCEPTION,
VEH_CONTINUE_EXECUTION,
VEH_CONTINUE_SEARCH,
VEH_EXECUTE_HANDLER
};


VEH_ACTION WINAPI CLRVectoredExceptionHandlerPhase2(PEXCEPTION_POINTERS pExceptionInfo);
VEH_ACTION WINAPI CLRVectoredExceptionHandlerPhase3(PEXCEPTION_POINTERS pExceptionInfo);

LONG WINAPI CLRVectoredExceptionHandler(PEXCEPTION_POINTERS pExceptionInfo)
VEH_ACTION WINAPI CLRVectoredExceptionHandler(PEXCEPTION_POINTERS pExceptionInfo)
{
// It is not safe to execute code inside VM after we shutdown EE. One example is DisablePreemptiveGC
// will block forever.
if (g_fForbidEnterEE)
{
return EXCEPTION_CONTINUE_SEARCH;
return VEH_CONTINUE_SEARCH;
}


Expand Down Expand Up @@ -6836,7 +6822,7 @@ LONG WINAPI CLRVectoredExceptionHandler(PEXCEPTION_POINTERS pExceptionInfo)
pExceptionInfo->ContextRecord->Rip = hijackArgs.ReturnAddress;
}

return EXCEPTION_CONTINUE_EXECUTION;
return VEH_CONTINUE_EXECUTION;
}
#endif

Expand All @@ -6860,11 +6846,9 @@ LONG WINAPI CLRVectoredExceptionHandler(PEXCEPTION_POINTERS pExceptionInfo)
//
// Not an Out-of-memory situation, so no need for a forbid fault region here
//
return EXCEPTION_CONTINUE_SEARCH;
return VEH_CONTINUE_SEARCH;
}

LONG retVal = 0;

// We can't probe here, because we won't return from the CLRVectoredExceptionHandlerPhase2
// on WIN64
//
Expand All @@ -6875,15 +6859,10 @@ LONG WINAPI CLRVectoredExceptionHandler(PEXCEPTION_POINTERS pExceptionInfo)
CantAllocHolder caHolder;
}

retVal = CLRVectoredExceptionHandlerPhase2(pExceptionInfo);

//
//END_ENTRYPOINT_VOIDRET;
//
return retVal;
return CLRVectoredExceptionHandlerPhase2(pExceptionInfo);
}

LONG WINAPI CLRVectoredExceptionHandlerPhase2(PEXCEPTION_POINTERS pExceptionInfo)
VEH_ACTION WINAPI CLRVectoredExceptionHandlerPhase2(PEXCEPTION_POINTERS pExceptionInfo)
{
//
// DO NOT USE CONTRACTS HERE AS THIS ROUTINE MAY NEVER RETURN. You can use
Expand Down Expand Up @@ -6917,31 +6896,16 @@ LONG WINAPI CLRVectoredExceptionHandlerPhase2(PEXCEPTION_POINTERS pExceptionInfo
action = CLRVectoredExceptionHandlerPhase3(pExceptionInfo);
}

if (action == VEH_CONTINUE_EXECUTION)
{
return EXCEPTION_CONTINUE_EXECUTION;
}

if (action == VEH_CONTINUE_SEARCH)
if ((action == VEH_CONTINUE_EXECUTION) || (action == VEH_CONTINUE_SEARCH) || (action == VEH_EXECUTE_HANDLER))
{
return EXCEPTION_CONTINUE_SEARCH;
}

if (action == VEH_EXECUTE_HANDLER)
{
return EXCEPTION_EXECUTE_HANDLER;
return action;
}

#if defined(FEATURE_EH_FUNCLETS)

if (action == VEH_EXECUTE_HANDLE_MANAGED_EXCEPTION)
{
HandleManagedFault(pExceptionInfo->ExceptionRecord,
pExceptionInfo->ContextRecord,
NULL, // establisher frame (x86 only)
NULL // pThread (x86 only)
);
return EXCEPTION_CONTINUE_EXECUTION;
return action;
}

#endif // defined(FEATURE_EH_FUNCLETS)
Expand All @@ -6961,7 +6925,7 @@ LONG WINAPI CLRVectoredExceptionHandlerPhase2(PEXCEPTION_POINTERS pExceptionInfo
// the choice to break the no-trigger region after taking all necessary precautions.
if (IsDebuggerFault(pExceptionRecord, pExceptionInfo->ContextRecord, pExceptionRecord->ExceptionCode, GetThreadNULLOk()))
{
return EXCEPTION_CONTINUE_EXECUTION;
return VEH_CONTINUE_EXECUTION;
}
}

Expand Down Expand Up @@ -6993,11 +6957,11 @@ LONG WINAPI CLRVectoredExceptionHandlerPhase2(PEXCEPTION_POINTERS pExceptionInfo
{
// The breakpoint was not ours. Someone else can handle it. (Or if not, we'll get it again as
// an unhandled exception.)
return EXCEPTION_CONTINUE_SEARCH;
return VEH_CONTINUE_SEARCH;
}

// The breakpoint was from managed or the runtime. Handle it.
return UserBreakpointFilter(pExceptionInfo);
return (VEH_ACTION)UserBreakpointFilter(pExceptionInfo);
}

#if defined(FEATURE_EH_FUNCLETS)
Expand All @@ -7015,19 +6979,11 @@ LONG WINAPI CLRVectoredExceptionHandlerPhase2(PEXCEPTION_POINTERS pExceptionInfo

if (fShouldHandleManagedFault)
{
//
// HandleManagedFault may never return, so we cannot use a forbid fault region around it.
//
HandleManagedFault(pExceptionInfo->ExceptionRecord,
pExceptionInfo->ContextRecord,
NULL, // establisher frame (x86 only)
NULL // pThread (x86 only)
);
return EXCEPTION_CONTINUE_EXECUTION;
}
return VEH_EXECUTE_HANDLE_MANAGED_EXCEPTION;
}
#endif // defined(FEATURE_EH_FUNCLETS)

return EXCEPTION_EXECUTE_HANDLER;
return VEH_EXECUTE_HANDLER;
}

/*
Expand Down Expand Up @@ -7594,13 +7550,34 @@ LONG WINAPI CLRVectoredExceptionHandlerShim(PEXCEPTION_POINTERS pExceptionInfo)
if (pThread || fExceptionInEE)
{
if (!bIsGCMarker)
result = CLRVectoredExceptionHandler(pExceptionInfo);
else
result = EXCEPTION_CONTINUE_EXECUTION;
{
VEH_ACTION action = CLRVectoredExceptionHandler(pExceptionInfo);

#ifdef FEATURE_EH_FUNCLETS
if (VEH_EXECUTE_HANDLE_MANAGED_EXCEPTION == action)
{
//
// HandleManagedFault may never return, so we cannot use a forbid fault region around it.
//
HandleManagedFault(pExceptionInfo->ExceptionRecord, pExceptionInfo->ContextRecord);
return EXCEPTION_CONTINUE_EXECUTION;
}
#endif // FEATURE_EH_FUNCLETS

if (VEH_EXECUTE_HANDLER == action)
{
result = EXCEPTION_CONTINUE_SEARCH;
}
else
{
_ASSERTE((action == VEH_CONTINUE_EXECUTION) || (action == VEH_CONTINUE_SEARCH));
result = (LONG)action;
}

if (EXCEPTION_EXECUTE_HANDLER == result)
}
else
{
result = EXCEPTION_CONTINUE_SEARCH;
result = EXCEPTION_CONTINUE_EXECUTION;
}

#ifdef _DEBUG
Expand Down Expand Up @@ -8321,7 +8298,7 @@ void SetReversePInvokeEscapingUnhandledExceptionStatus(BOOL fIsUnwinding,
#if defined(TARGET_X86)
EXCEPTION_REGISTRATION_RECORD * pEstablisherFrame
#elif defined(FEATURE_EH_FUNCLETS)
ULONG64 pEstablisherFrame
PVOID pEstablisherFrame
#else
#error Unsupported platform
#endif
Expand Down
9 changes: 3 additions & 6 deletions src/coreclr/vm/excep.h
Original file line number Diff line number Diff line change
Expand Up @@ -744,14 +744,11 @@ bool IsGcMarker(T_CONTEXT *pContext, EXCEPTION_RECORD *pExceptionRecord);

bool ShouldHandleManagedFault(
EXCEPTION_RECORD* pExceptionRecord,
T_CONTEXT* pContext,
T_CONTEXT* pContext,
EXCEPTION_REGISTRATION_RECORD* pEstablisherFrame,
Thread* pThread);

void HandleManagedFault(EXCEPTION_RECORD* pExceptionRecord,
T_CONTEXT* pContext,
EXCEPTION_REGISTRATION_RECORD* pEstablisherFrame,
Thread* pThread);
void HandleManagedFault(EXCEPTION_RECORD* pExceptionRecord, T_CONTEXT* pContext);

LONG WatsonLastChance(
Thread *pThread,
Expand All @@ -778,7 +775,7 @@ void SetReversePInvokeEscapingUnhandledExceptionStatus(BOOL fIsUnwinding,
#ifdef TARGET_X86
EXCEPTION_REGISTRATION_RECORD * pEstablisherFrame
#elif defined(FEATURE_EH_FUNCLETS)
ULONG64 pEstablisherFrame
PVOID pEstablisherFrame
#else
#error Unsupported platform
#endif
Expand Down
Loading