}
};
+// This is a native exception holder that doesn't catch any exceptions.
+class NativeExceptionHolderNoCatch : public NativeExceptionHolderBase
+{
+
+public:
+ NativeExceptionHolderNoCatch()
+ : NativeExceptionHolderBase()
+ {
+ }
+
+ virtual EXCEPTION_DISPOSITION InvokeFilter(PAL_SEHException& ex)
+ {
+ return EXCEPTION_CONTINUE_SEARCH;
+ }
+};
+
//
// This factory class for the native exception holder is necessary because
// templated functions don't need the explicit type parameter and can infer
/* Macros used to indicate a call to managed code is starting/ending */
/***********************************************************************/
+#ifdef FEATURE_PAL
+// Install a native exception holder that doesn't catch any exceptions but its presence
+// in a stack range of native frames indicates that there was a call from native to
+// managed code. It is used by the DispatchManagedException to detect the case when
+// the INSTALL_MANAGED_EXCEPTION_DISPATCHER was not at the managed to native boundary.
+// For example in the PreStubWorker, which can be called from both native and managed
+// code.
+#define INSTALL_CALL_TO_MANAGED_EXCEPTION_HOLDER() \
+ NativeExceptionHolderNoCatch __exceptionHolder; \
+ __exceptionHolder.Push();
+#else // FEATURE_PAL
+#define INSTALL_CALL_TO_MANAGED_EXCEPTION_HOLDER()
+#endif // FEATURE_PAL
+
enum EEToManagedCallFlags
{
EEToManagedDefault = 0x0000,
} \
} \
BEGIN_SO_TOLERANT_CODE(CURRENT_THREAD); \
+ INSTALL_CALL_TO_MANAGED_EXCEPTION_HOLDER(); \
INSTALL_COMPLUS_EXCEPTION_HANDLER_NO_DECLARE();
#define END_CALL_TO_MANAGED() \
// Get the managed frame to continue unwinding from.
CONTEXT frameContext;
RtlCaptureContext(&frameContext);
+ UINT_PTR currentSP = GetSP(&frameContext);
Thread::VirtualUnwindToFirstManagedCallFrame(&frameContext);
-
+ UINT_PTR firstManagedFrameSP = GetSP(&frameContext);
+
+ // Check if there is any exception holder in the skipped frames. If there is one, we need to unwind them
+ // using the C++ handling. This is a special case when the UNINSTALL_MANAGED_EXCEPTION_DISPATCHER was
+ // not at the managed to native boundary.
+ if (NativeExceptionHolderBase::FindNextHolder(nullptr, (void*)currentSP, (void*)firstManagedFrameSP) != nullptr)
+ {
+ break;
+ }
+
UnwindManagedExceptionPass2(ex, &frameContext);
}
UNREACHABLE();
{
ex = ex2;
}
+
}
while (true);
+
+ throw ex;
}
#ifdef _AMD64_