// Given an address pointing somewhere into a managed module, get the classlib-defined fail-fast // function and invoke it. Any failure to find and invoke the function, or if it returns, results in // Rtm-define fail-fast behavior. internal unsafe static void FailFastViaClasslib(RhFailFastReason reason, Exception unhandledException, IntPtr classlibAddress) { // Find the classlib function that will fail fast. This is a RuntimeExport function from the // classlib module, and is therefore managed-callable. IntPtr pFailFastFunction = (IntPtr)InternalCalls.RhpGetClasslibFunction(classlibAddress, ClassLibFunctionId.FailFast); if (pFailFastFunction == IntPtr.Zero) { // The classlib didn't provide a function, so we fail our way... FailFast(reason, unhandledException); } try { // Invoke the classlib fail fast function. CalliIntrinsics.CallVoid(pFailFastFunction, reason, unhandledException, IntPtr.Zero); } catch { // Unfortunately, this catch turns into "catch (System.Object)", which will not catch // exceptions thrown from the class library because their objects do not derive from our // System.Object. // // @TODO: Use a filtered catch whose filter always returns 'true'. } // The classlib's funciton should never return and should not throw. If it does, then we fail our way... FailFast(reason, unhandledException); }
// Given an address pointing somewhere into a managed module, get the classlib-defined fail-fast // function and invoke it. Any failure to find and invoke the function, or if it returns, results in // MRT-defined fail-fast behavior. internal static void FailFastViaClasslib(RhFailFastReason reason, object unhandledException, IntPtr classlibAddress) { // Find the classlib function that will fail fast. This is a RuntimeExport function from the // classlib module, and is therefore managed-callable. IntPtr pFailFastFunction = (IntPtr)InternalCalls.RhpGetClasslibFunctionFromCodeAddress(classlibAddress, ClassLibFunctionId.FailFast); if (pFailFastFunction == IntPtr.Zero) { // The classlib didn't provide a function, so we fail our way... FallbackFailFast(reason, unhandledException); } try { // Invoke the classlib fail fast function. ((delegate * < RhFailFastReason, object, IntPtr, IntPtr, void >)pFailFastFunction) (reason, unhandledException, IntPtr.Zero, IntPtr.Zero); } catch when(true) { // disallow all exceptions leaking out of callbacks } // The classlib's function should never return and should not throw. If it does, then we fail our way... FallbackFailFast(reason, unhandledException); }
internal static unsafe void UnhandledExceptionFailFastViaClasslib( RhFailFastReason reason, object unhandledException, IntPtr classlibAddress, ref ExInfo exInfo) { IntPtr pFailFastFunction = (IntPtr)InternalCalls.RhpGetClasslibFunctionFromCodeAddress(classlibAddress, ClassLibFunctionId.FailFast); if (pFailFastFunction == IntPtr.Zero) { FailFastViaClasslib( reason, unhandledException, classlibAddress); } // 16-byte align the context. This is overkill on x86 and ARM, but simplifies things slightly. const int contextAlignment = 16; byte * pbBuffer = stackalloc byte[sizeof(OSCONTEXT) + contextAlignment]; void * pContext = PointerAlign(pbBuffer, contextAlignment); InternalCalls.RhpCopyContextFromExInfo(pContext, sizeof(OSCONTEXT), exInfo._pExContext); try { ((delegate * < RhFailFastReason, object, IntPtr, void *, void >)pFailFastFunction) (reason, unhandledException, exInfo._pExContext->IP, pContext); } catch when(true) { // disallow all exceptions leaking out of callbacks } // The classlib's function should never return and should not throw. If it does, then we fail our way... FallbackFailFast(reason, unhandledException); }
private static string GetStringForFailFastReason(RhFailFastReason reason) { switch (reason) { case RhFailFastReason.InternalError: return("Runtime internal error"); case RhFailFastReason.UnhandledException_ExceptionDispatchNotAllowed: return("Unhandled exception: no handler found before escaping a finally clause or other fail-fast scope."); case RhFailFastReason.UnhandledException_CallerDidNotHandle: return("Unhandled exception: no handler found in calling method."); case RhFailFastReason.ClassLibDidNotTranslateExceptionID: return("Unable to translate failure into a classlib-specific exception object."); case RhFailFastReason.IllegalNativeCallableEntry: return("Invalid Program: attempted to call a NativeCallable method from runtime-typesafe code."); case RhFailFastReason.PN_UnhandledException: return("Unhandled exception: a managed exception was not handled before reaching unmanaged code"); case RhFailFastReason.PN_UnhandledExceptionFromPInvoke: return("Unhandled exception: an unmanaged exception was thrown out of a managed-to-native transition."); default: return("Unknown reason."); } }
public static void RuntimeFailFast(RhFailFastReason reason, Exception exception, IntPtr pExContext) { // This method is called by the runtime's EH dispatch code and is not allowed to leak exceptions // back into the dispatcher. try { if ((reason == RhFailFastReason.PN_UnhandledException) && (exception != null) && !(exception is OutOfMemoryException)) { Debug.WriteLine("Unhandled Exception: " + exception.ToString()); } FailFast(String.Format("Runtime-generated FailFast: ({0}): {1}{2}", reason.ToString(), // Explicit call to ToString() to avoid MissingMetadataException inside String.Format(). GetStringForFailFastReason(reason), exception != null ? " [exception object available]" : ""), exception, reason, pExContext); } catch { // Returning from this callback will cause the runtime to FailFast without involving the class // library. } }
// Given an address pointing somewhere into a managed module, get the classlib-defined fail-fast // function and invoke it. Any failure to find and invoke the function, or if it returns, results in // Rtm-define fail-fast behavior. internal unsafe static void FailFastViaClasslib(RhFailFastReason reason, Exception unhandledException, IntPtr classlibAddress) { // Find the classlib function that will fail fast. This is a RuntimeExport function from the // classlib module, and is therefore managed-callable. IntPtr pFailFastFunction = (IntPtr)InternalCalls.RhpGetClasslibFunction(classlibAddress, ClassLibFunctionId.FailFast); if (pFailFastFunction == IntPtr.Zero) { // The classlib didn't provide a function, so we fail our way... FallbackFailFast(reason, unhandledException); } try { // Invoke the classlib fail fast function. CalliIntrinsics.CallVoid(pFailFastFunction, reason, unhandledException, IntPtr.Zero); } catch { // disallow all exceptions leaking out of callbacks } // The classlib's funciton should never return and should not throw. If it does, then we fail our way... FallbackFailFast(reason, unhandledException); }
internal static void FailFast(string message, Exception exception, RhFailFastReason reason, IntPtr pExContext) { // If this a recursive call to FailFast, avoid all unnecessary and complex actitivy the second time around to avoid the recursion // that got us here the first time (Some judgement is required as to what activity is "unnecessary and complex".) bool minimalFailFast = s_inFailFast || (exception is OutOfMemoryException); s_inFailFast = true; if (!minimalFailFast) { String output = (exception != null) ? "Unhandled Exception: " + exception.ToString() : message; DeveloperExperience.Default.WriteLine(output); GenerateExceptionInformationForDump(exception, IntPtr.Zero); } if (Interop.mincore.IsDebuggerPresent()) { Debug.DebugBreak(); } uint errorCode = 0x80004005; // E_FAIL // To help enable testing to bucket the failures we choose one of the following as errorCode: // * RVA of EETypePtr if it is an unhandled managed exception // * HRESULT, if available // * RhFailFastReason, if it is one of the known reasons if (exception != null) { if (reason == RhFailFastReason.PN_UnhandledException) { errorCode = (uint)(exception.EETypePtr.RawValue.ToInt64() - RuntimeImports.RhGetModuleFromEEType(exception.EETypePtr.RawValue).ToInt64()); } else if (exception.HResult != 0) { errorCode = (uint)exception.HResult; } } else if (reason != RhFailFastReason.Unknown) { errorCode = (uint)reason + 0x1000; // Add something to avoid common low level exit codes } Interop.mincore.RaiseFailFastException(errorCode, pExContext); }
public static void RuntimeFailFast(RhFailFastReason reason, Exception?exception, IntPtr pExAddress, IntPtr pExContext) { if (!SafeToPerformRichExceptionSupport) { return; } // This method is called by the runtime's EH dispatch code and is not allowed to leak exceptions // back into the dispatcher. try { //TODO Add PreallocatedOutOfMemoryException // Avoid complex processing and allocations if we are already in failfast or recursive out of memory. // We do not set InFailFast.Value here, because we want rich diagnostics in the FailFast // call below and reentrancy is not possible for this method (all exceptions are ignored). bool minimalFailFast = InFailFast.Value /* || (exception == PreallocatedOutOfMemoryException.Instance)*/; string failFastMessage = ""; if (!minimalFailFast) { if ((reason == RhFailFastReason.PN_UnhandledException) && (exception != null)) { //TODO Add Debug.WriteLine //Debug.WriteLine("Unhandled Exception: " + exception.ToString()); Internal.Console.WriteLine("Unhandled Exception: " + exception.ToString()); } //TODO Add String.Format /*failFastMessage = string.Format("Runtime-generated FailFast: ({0}): {1}{2}", * reason.ToString(), // Explicit call to ToString() to avoid MissingMetadataException inside String.Format() * GetStringForFailFastReason(reason), * exception != null ? " [exception object available]" : "");*/ failFastMessage = "Runtime-generated FailFast: (" + reason.ToString() + "): " + GetStringForFailFastReason(reason) + (exception != null ? " [exception object available]" : ""); } FailFast(failFastMessage, exception, reason, pExAddress, pExContext); } catch { // Returning from this callback will cause the runtime to FailFast without involving the class // library. } }
internal static void FailFast(string message, Exception exception, RhFailFastReason reason, IntPtr pExAddress, IntPtr pExContext) { // If this a recursive call to FailFast, avoid all unnecessary and complex activity the second time around to avoid the recursion // that got us here the first time (Some judgement is required as to what activity is "unnecessary and complex".) bool minimalFailFast = InFailFast.Value || (exception == PreallocatedOutOfMemoryException.Instance); InFailFast.Value = true; if (!minimalFailFast) { string output = (exception != null) ? "Unhandled Exception: " + exception.ToString() : message; DeveloperExperience.Default.WriteLine(output); GenerateExceptionInformationForDump(exception, IntPtr.Zero); } #if PLATFORM_WINDOWS uint errorCode = 0x80004005; // E_FAIL // To help enable testing to bucket the failures we choose one of the following as errorCode: // * hashcode of EETypePtr if it is an unhandled managed exception // * HRESULT, if available // * RhFailFastReason, if it is one of the known reasons if (exception != null) { if (reason == RhFailFastReason.PN_UnhandledException) { errorCode = (uint)(exception.EETypePtr.GetHashCode()); } else if (exception.HResult != 0) { errorCode = (uint)exception.HResult; } } else if (reason != RhFailFastReason.Unknown) { errorCode = (uint)reason + 0x1000; // Add something to avoid common low level exit codes } Interop.mincore.RaiseFailFastException(errorCode, pExAddress, pExContext); #else Interop.Sys.Abort(); #endif }
internal unsafe static void UnhandledExceptionFailFastViaClasslib( RhFailFastReason reason, Exception unhandledException, ref ExInfo exInfo) { IntPtr pFailFastFunction = (IntPtr)InternalCalls.RhpGetClasslibFunction(exInfo._pExContext->IP, ClassLibFunctionId.FailFast); if (pFailFastFunction == IntPtr.Zero) { FailFastViaClasslib( reason, unhandledException, exInfo._pExContext->IP); } // 16-byte align the context. This is overkill on x86 and ARM, but simplifies things slightly. const int contextAlignment = 16; byte * pbBuffer = stackalloc byte[sizeof(OSCONTEXT) + contextAlignment]; void * pContext = PointerAlign(pbBuffer, contextAlignment); // We 'normalized' the faulting IP of hardware faults to behave like return addresses. Undo this // normalization here so that we report the correct thing in the exception context record. if ((exInfo._kind & ExKind.KindMask) == ExKind.HardwareFault) { exInfo._pExContext->IP = (IntPtr)(((byte *)exInfo._pExContext->IP) - c_IPAdjustForHardwareFault); } InternalCalls.RhpCopyContextFromExInfo(pContext, sizeof(OSCONTEXT), exInfo._pExContext); try { CalliIntrinsics.CallVoid(pFailFastFunction, reason, unhandledException, (IntPtr)pContext); } catch { // Unfortunately, this catch turns into "catch (System.Object)", which will not catch // exceptions thrown from the class library because their objects do not derive from our // System.Object. // // @TODO: Use a filtered catch whose filter always returns 'true'. } // The classlib's funciton should never return and should not throw. If it does, then we fail our way... FailFast(reason, unhandledException); }
internal unsafe static void UnhandledExceptionFailFastViaClasslib( RhFailFastReason reason, object unhandledException, IntPtr classlibAddress, ref ExInfo exInfo) { IntPtr pFailFastFunction = (IntPtr)InternalCalls.RhpGetClasslibFunction(classlibAddress, ClassLibFunctionId.FailFast); if (pFailFastFunction == IntPtr.Zero) { FailFastViaClasslib( reason, unhandledException, classlibAddress); } // 16-byte align the context. This is overkill on x86 and ARM, but simplifies things slightly. const int contextAlignment = 16; byte * pbBuffer = stackalloc byte[sizeof(OSCONTEXT) + contextAlignment]; void * pContext = PointerAlign(pbBuffer, contextAlignment); // We 'normalized' the faulting IP of hardware faults to behave like return addresses. Undo this // normalization here so that we report the correct thing in the exception context record. if ((exInfo._kind & ExKind.KindMask) == ExKind.HardwareFault) { exInfo._pExContext->IP = (IntPtr)(((byte *)exInfo._pExContext->IP) - c_IPAdjustForHardwareFault); } InternalCalls.RhpCopyContextFromExInfo(pContext, sizeof(OSCONTEXT), exInfo._pExContext); try { CalliIntrinsics.CallVoid(pFailFastFunction, reason, unhandledException, exInfo._pExContext->IP, (IntPtr)pContext); } catch { // disallow all exceptions leaking out of callbacks } // The classlib's funciton should never return and should not throw. If it does, then we fail our way... FallbackFailFast(reason, unhandledException); }
// This is a fail-fast function used by the runtime as a last resort that will terminate the process with // as little effort as possible. No guarantee is made about the semantics of this fail-fast. internal static void FallbackFailFast(RhFailFastReason reason, object unhandledException) { InternalCalls.RhpFallbackFailFast(); }
private static string GetStringForFailFastReason(RhFailFastReason reason) { switch (reason) { case RhFailFastReason.InternalError: return "Runtime internal error"; case RhFailFastReason.UnhandledException_ExceptionDispatchNotAllowed: return "Unhandled exception: no handler found before escaping a finally clause or other fail-fast scope."; case RhFailFastReason.UnhandledException_CallerDidNotHandle: return "Unhandled exception: no handler found in calling method."; case RhFailFastReason.ClassLibDidNotTranslateExceptionID: return "Unable to translate failure into a classlib-specific exception object."; case RhFailFastReason.IllegalNativeCallableEntry: return "Invalid Program: attempted to call a NativeCallable method from runtime-typesafe code."; case RhFailFastReason.PN_UnhandledException: return "Unhandled exception: a managed exception was not handled before reaching unmanaged code."; case RhFailFastReason.PN_UnhandledExceptionFromPInvoke: return "Unhandled exception: an unmanaged exception was thrown out of a managed-to-native transition."; default: return "Unknown reason."; } }
internal static unsafe void UnhandledExceptionFailFastViaClasslib( RhFailFastReason reason, object unhandledException, IntPtr classlibAddress, ref ExInfo exInfo) { IntPtr pFailFastFunction = (IntPtr)InternalCalls.RhpGetClasslibFunction(classlibAddress, ClassLibFunctionId.FailFast); if (pFailFastFunction == IntPtr.Zero) { FailFastViaClasslib( reason, unhandledException, classlibAddress); } // 16-byte align the context. This is overkill on x86 and ARM, but simplifies things slightly. const int contextAlignment = 16; byte* pbBuffer = stackalloc byte[sizeof(OSCONTEXT) + contextAlignment]; void* pContext = PointerAlign(pbBuffer, contextAlignment); // We 'normalized' the faulting IP of hardware faults to behave like return addresses. Undo this // normalization here so that we report the correct thing in the exception context record. if ((exInfo._kind & ExKind.KindMask) == ExKind.HardwareFault) { exInfo._pExContext->IP = (IntPtr)(((byte*)exInfo._pExContext->IP) - c_IPAdjustForHardwareFault); } InternalCalls.RhpCopyContextFromExInfo(pContext, sizeof(OSCONTEXT), exInfo._pExContext); try { CalliIntrinsics.CallVoid(pFailFastFunction, reason, unhandledException, exInfo._pExContext->IP, (IntPtr)pContext); } catch { // disallow all exceptions leaking out of callbacks } // The classlib's funciton should never return and should not throw. If it does, then we fail our way... FallbackFailFast(reason, unhandledException); }
// Given an address pointing somewhere into a managed module, get the classlib-defined fail-fast // function and invoke it. Any failure to find and invoke the function, or if it returns, results in // MRT-defined fail-fast behavior. internal static void FailFastViaClasslib(RhFailFastReason reason, object unhandledException, IntPtr classlibAddress) { // Find the classlib function that will fail fast. This is a RuntimeExport function from the // classlib module, and is therefore managed-callable. IntPtr pFailFastFunction = (IntPtr)InternalCalls.RhpGetClasslibFunction(classlibAddress, ClassLibFunctionId.FailFast); if (pFailFastFunction == IntPtr.Zero) { // The classlib didn't provide a function, so we fail our way... FallbackFailFast(reason, unhandledException); } try { // Invoke the classlib fail fast function. CalliIntrinsics.CallVoid(pFailFastFunction, reason, unhandledException, IntPtr.Zero, IntPtr.Zero); } catch { // disallow all exceptions leaking out of callbacks } // The classlib's function should never return and should not throw. If it does, then we fail our way... FallbackFailFast(reason, unhandledException); }
public static void RuntimeFailFast(RhFailFastReason reason, Exception exception, IntPtr pExAddress, IntPtr pExContext) { RuntimeImports.RhpFallbackFailFast(); }
internal unsafe static void UnhandledExceptionFailFastViaClasslib( RhFailFastReason reason, Exception unhandledException, ref ExInfo exInfo) { IntPtr pFailFastFunction = (IntPtr)InternalCalls.RhpGetClasslibFunction(exInfo._pExContext->IP, ClassLibFunctionId.FailFast); if (pFailFastFunction == IntPtr.Zero) { FailFastViaClasslib( reason, unhandledException, exInfo._pExContext->IP); } // 16-byte align the context. This is overkill on x86 and ARM, but simplifies things slightly. const int contextAlignment = 16; byte* pbBuffer = stackalloc byte[sizeof(OSCONTEXT) + contextAlignment]; void* pContext = PointerAlign(pbBuffer, contextAlignment); // We 'normalized' the faulting IP of hardware faults to behave like return addresses. Undo this // normalization here so that we report the correct thing in the exception context record. if ((exInfo._kind & ExKind.KindMask) == ExKind.HardwareFault) { exInfo._pExContext->IP = (IntPtr)(((byte*)exInfo._pExContext->IP) - c_IPAdjustForHardwareFault); } InternalCalls.RhpCopyContextFromExInfo(pContext, sizeof(OSCONTEXT), exInfo._pExContext); try { CalliIntrinsics.CallVoid(pFailFastFunction, reason, unhandledException, (IntPtr)pContext); } catch { // Unfortunately, this catch turns into "catch (System.Object)", which will not catch // exceptions thrown from the class library because their objects do not derive from our // System.Object. // // @TODO: Use a filtered catch whose filter always returns 'true'. } // The classlib's funciton should never return and should not throw. If it does, then we fail our way... FailFast(reason, unhandledException); }
public static void RuntimeFailFast(RhFailFastReason reason, Exception exception, IntPtr pExAddress, IntPtr pExContext) { // This method is called by the runtime's EH dispatch code and is not allowed to leak exceptions // back into the dispatcher. try { if (!SafeToPerformRichExceptionSupport) return; // Avoid complex processing and allocations if we are already in failfast or out of memory. // We do not set InFailFast.Value here, because we want rich diagnostics in the FailFast // call below and reentrancy is not possible for this method (all exceptions are ignored). bool minimalFailFast = InFailFast.Value || (exception is OutOfMemoryException); string failFastMessage = ""; if (!minimalFailFast) { if ((reason == RhFailFastReason.PN_UnhandledException) && (exception != null)) { Debug.WriteLine("Unhandled Exception: " + exception.ToString()); } failFastMessage = String.Format("Runtime-generated FailFast: ({0}): {1}{2}", reason.ToString(), // Explicit call to ToString() to avoid MissingMetadataException inside String.Format() GetStringForFailFastReason(reason), exception != null ? " [exception object available]" : ""); } FailFast(failFastMessage, exception, reason, pExAddress, pExContext); } catch { // Returning from this callback will cause the runtime to FailFast without involving the class // library. } }
internal static void FailFast(RhFailFastReason reason, Exception unhandledException) { BinderIntrinsics.DebugBreak(); }
internal static T Call <T>(IntPtr pfn, RhFailFastReason arg0, object arg1, IntPtr arg2) { throw new NotImplementedException(); }
internal static void FailFast(string message, Exception?exception, RhFailFastReason reason, IntPtr pExAddress, IntPtr pExContext) { // If this a recursive call to FailFast, avoid all unnecessary and complex activity the second time around to avoid the recursion // that got us here the first time (Some judgement is required as to what activity is "unnecessary and complex".) bool minimalFailFast = InFailFast.Value || (exception == PreallocatedOutOfMemoryException.Instance); InFailFast.Value = true; if (!minimalFailFast) { string prefix; string outputMessage; if (exception != null) { prefix = "Unhandled Exception: "; outputMessage = exception.ToString(); } else { prefix = "Process terminated. "; outputMessage = message; } Internal.Console.Error.Write(prefix); if (outputMessage != null) { Internal.Console.Error.Write(outputMessage); } Internal.Console.Error.Write(Environment.NewLine); #if FEATURE_DUMP_DEBUGGING GenerateExceptionInformationForDump(exception, IntPtr.Zero); #endif } #if TARGET_WINDOWS uint errorCode = 0x80004005; // E_FAIL // To help enable testing to bucket the failures we choose one of the following as errorCode: // * hashcode of EETypePtr if it is an unhandled managed exception // * HRESULT, if available // * RhFailFastReason, if it is one of the known reasons if (exception != null) { if (reason == RhFailFastReason.PN_UnhandledException) { errorCode = (uint)(exception.EETypePtr.GetHashCode()); } else if (exception.HResult != 0) { errorCode = (uint)exception.HResult; } } else if (reason != RhFailFastReason.Unknown) { errorCode = (uint)reason + 0x1000; // Add something to avoid common low level exit codes } Interop.Kernel32.RaiseFailFastException(errorCode, pExAddress, pExContext); #else Interop.Sys.Abort(); #endif }
internal static void CallVoid(IntPtr pfn, RhFailFastReason arg0, object arg1, IntPtr arg2) { Call <int>(pfn, arg0, arg1, arg2); }
internal static void FailFast(string message, Exception exception, RhFailFastReason reason, IntPtr pExAddress, IntPtr pExContext) { // If this a recursive call to FailFast, avoid all unnecessary and complex actitivy the second time around to avoid the recursion // that got us here the first time (Some judgement is required as to what activity is "unnecessary and complex".) bool minimalFailFast = InFailFast.Value || (exception is OutOfMemoryException); InFailFast.Value = true; if (!minimalFailFast) { String output = (exception != null) ? "Unhandled Exception: " + exception.ToString() : message; DeveloperExperience.Default.WriteLine(output); GenerateExceptionInformationForDump(exception, IntPtr.Zero); } uint errorCode = 0x80004005; // E_FAIL // To help enable testing to bucket the failures we choose one of the following as errorCode: // * RVA of EETypePtr if it is an unhandled managed exception // * HRESULT, if available // * RhFailFastReason, if it is one of the known reasons if (exception != null) { if (reason == RhFailFastReason.PN_UnhandledException) errorCode = (uint)(exception.EETypePtr.RawValue.ToInt64() - RuntimeImports.RhGetModuleFromEEType(exception.EETypePtr.RawValue).ToInt64()); else if (exception.HResult != 0) errorCode = (uint)exception.HResult; } else if (reason != RhFailFastReason.Unknown) { errorCode = (uint)reason + 0x1000; // Add something to avoid common low level exit codes } Interop.mincore.RaiseFailFastException(errorCode, pExAddress, pExContext); }