}
#endif //_AMD64_
-BOOL PALAPI IsSafeToHandleHardwareException(PCONTEXT contextRecord, PEXCEPTION_RECORD exceptionRecord)
+BOOL IsSafeToCallExecutionManager()
{
Thread *pThread = GetThread();
- PCODE controlPc = GetIP(contextRecord);
+
// It is safe to call the ExecutionManager::IsManagedCode only if the current thread is in
// the cooperative mode. Otherwise ExecutionManager::IsManagedCode could deadlock if
// the exception happened when the thread was holding the ExecutionManager's writer lock.
// When the thread is in preemptive mode, we know for sure that it is not executing managed code.
- BOOL isManagedCode = (pThread != NULL && pThread->PreemptiveGCDisabled() && ExecutionManager::IsManagedCode(controlPc));
+ // Unfortunately, when running GC stress mode that invokes GC after every jitted or NGENed
+ // instruction, we need to relax that to enable instrumentation of PInvoke stubs that switch to
+ // preemptive GC mode at some point.
+ return ((pThread != NULL) && pThread->PreemptiveGCDisabled()) ||
+ GCStress<cfg_instr_jit>::IsEnabled() ||
+ GCStress<cfg_instr_ngen>::IsEnabled();
+}
+
+BOOL PALAPI IsSafeToHandleHardwareException(PCONTEXT contextRecord, PEXCEPTION_RECORD exceptionRecord)
+{
+ PCODE controlPc = GetIP(contextRecord);
return g_fEEStarted && (
exceptionRecord->ExceptionCode == STATUS_BREAKPOINT ||
exceptionRecord->ExceptionCode == STATUS_SINGLE_STEP ||
- isManagedCode ||
+ (IsSafeToCallExecutionManager() && ExecutionManager::IsManagedCode(controlPc)) ||
IsIPInMarkedJitHelper(controlPc));
}
{
// A hardware exception is handled only if it happened in a jitted code or
// in one of the JIT helper functions (JIT_MemSet, ...)
- Thread *pThread = GetThread();
PCODE controlPc = GetIP(&ex->ContextRecord);
- BOOL isManagedCode = (pThread != NULL && pThread->PreemptiveGCDisabled() && ExecutionManager::IsManagedCode(controlPc));
- if (isManagedCode && IsGcMarker(ex->ExceptionRecord.ExceptionCode, &ex->ContextRecord))
+ if (ExecutionManager::IsManagedCode(controlPc) && IsGcMarker(ex->ExceptionRecord.ExceptionCode, &ex->ContextRecord))
{
RtlRestoreContext(&ex->ContextRecord, &ex->ExceptionRecord);
UNREACHABLE();