Ejemplo n.º 1
0
        private static void AppendExceptionStackFrameViaClasslib(object exception, IntPtr IP,
                                                                 ref bool isFirstRethrowFrame, ref bool isFirstFrame)
        {
            IntPtr pAppendStackFrame = (IntPtr)InternalCalls.RhpGetClasslibFunction(IP,
                                                                                    ClassLibFunctionId.AppendExceptionStackFrame);

            if (pAppendStackFrame != IntPtr.Zero)
            {
                int flags = (isFirstFrame ? (int)RhEHFrameType.RH_EH_FIRST_FRAME : 0) |
                            (isFirstRethrowFrame ? (int)RhEHFrameType.RH_EH_FIRST_RETHROW_FRAME : 0);

                try
                {
                    CalliIntrinsics.CallVoid(pAppendStackFrame, exception, IP, flags);
                }
                catch
                {
                    // disallow all exceptions leaking out of callbacks
                }

                // Clear flags only if we called the function
                isFirstRethrowFrame = false;
                isFirstFrame        = false;
            }
        }
Ejemplo n.º 2
0
        // 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);
        }
Ejemplo n.º 3
0
        // 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);
        }
Ejemplo n.º 4
0
        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
            {
                CalliIntrinsics.CallVoid(pFailFastFunction, reason, unhandledException, exInfo._pExContext->IP, (IntPtr)pContext);
            }
            catch when(true)
            {
                // 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);
        }
Ejemplo n.º 5
0
        // Each class library can sign up for a callback to run code on the finalizer thread before any
        // objects derived from that class library's System.Object are finalized.  This is where we make those
        // callbacks.  When a class library is loaded, we set the s_fHasNewClasslibs flag and then the next
        // time the finalizer runs, we call this function to make any outstanding callbacks.
        private unsafe static void MakeFinalizerInitCallbacks()
        {
            while (true)
            {
                IntPtr pfnFinalizerInitCallback = InternalCalls.RhpGetNextFinalizerInitCallback();
                if (pfnFinalizerInitCallback == IntPtr.Zero)
                {
                    break;
                }

                CalliIntrinsics.CallVoid(pfnFinalizerInitCallback);
            }
        }
Ejemplo n.º 6
0
        private unsafe static void DrainQueue()
        {
            // Drain the queue of finalizable objects.
            while (true)
            {
                Object target = InternalCalls.RhpGetNextFinalizableObject();
                if (target == null)
                {
                    return;
                }

                // Call the finalizer on the current target object. If the finalizer throws we'll fail
                // fast via normal Redhawk exception semantics (since we don't attempt to catch
                // anything).
                CalliIntrinsics.CallVoid(target.EEType->FinalizerCode, target);
            }
        }
Ejemplo n.º 7
0
        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);
        }
Ejemplo n.º 8
0
        private static void OnFirstChanceExceptionViaClassLib(object exception)
        {
            IntPtr pOnFirstChanceFunction =
                (IntPtr)InternalCalls.RhpGetClasslibFunctionFromEEType((IntPtr)exception.m_pEEType, ClassLibFunctionId.OnFirstChance);

            if (pOnFirstChanceFunction == IntPtr.Zero)
            {
                return;
            }

            try
            {
                CalliIntrinsics.CallVoid(pOnFirstChanceFunction, exception);
            }
            catch when(true)
            {
                // disallow all exceptions leaking out of callbacks
            }
        }
Ejemplo n.º 9
0
        internal unsafe static void AppendExceptionStackFrameViaClasslib(
            Exception exception, IntPtr IP, bool isFirstRethrowFrame, IntPtr classlibAddress, bool isFirstFrame)
        {
            IntPtr pAppendStackFrame = (IntPtr)InternalCalls.RhpGetClasslibFunction(classlibAddress,
                                                                                    ClassLibFunctionId.AppendExceptionStackFrame);
            int flags = (isFirstFrame ? (int)RhEHFrameType.RH_EH_FIRST_FRAME : 0) |
                        (isFirstRethrowFrame ? (int)RhEHFrameType.RH_EH_FIRST_RETHROW_FRAME : 0);

            if (pAppendStackFrame != IntPtr.Zero)
            {
                try
                {
                    CalliIntrinsics.CallVoid(pAppendStackFrame, exception, IP, flags);
                }
                catch
                {
                    // disallow all exceptions leaking out of callbacks
                }
            }
        }
Ejemplo n.º 10
0
        public static void ProcessFinalizers()
        {
            while (true)
            {
                // Wait until there's some work to be done. If true is returned we should finalize objects,
                // otherwise memory is low and we should initiate a collection.
                if (InternalCalls.RhpWaitForFinalizerRequest() != 0)
                {
                    if (s_fHaveNewClasslibs)
                    {
                        s_fHaveNewClasslibs = false;
                        MakeFinalizerInitCallbacks();
                    }

                    // Drain the queue of finalizable objects.
                    Object target = InternalCalls.RhpGetNextFinalizableObject();
                    while (target != null)
                    {
                        // Call the finalizer on the current target object. If the finalizer throws we'll fail
                        // fast via normal Redhawk exception semantics (since we don't attempt to catch
                        // anything).
                        unsafe
                        {
                            CalliIntrinsics.CallVoid(target.EEType->FinalizerCode, target);
                        }

                        target = InternalCalls.RhpGetNextFinalizableObject();
                    }

                    // Tell anybody that's interested that the finalization pass is complete (there is a race condition here
                    // where we might immediately signal a new request as complete, but this is acceptable).
                    InternalCalls.RhpSignalFinalizationComplete();
                }
                else
                {
                    // RhpWaitForFinalizerRequest() returned false and indicated that memory is low. We help
                    // out by initiating a garbage collection and then go back to waiting for another request.
                    InternalCalls.RhCollect(-1, InternalGCCollectionMode.Blocking);
                }
            }
        }
Ejemplo n.º 11
0
        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);
        }
Ejemplo n.º 12
0
        internal unsafe static void AppendExceptionStackFrameViaClasslib(
            Exception exception, IntPtr IP, bool isFirstRethrowFrame, IntPtr classlibAddress, bool isFirstFrame)
        {
            IntPtr pAppendStackFrame = (IntPtr)InternalCalls.RhpGetClasslibFunction(classlibAddress,
                                                                                    ClassLibFunctionId.AppendExceptionStackFrame);
            int flags = (isFirstFrame ? (int)RhEHFrameType.RH_EH_FIRST_FRAME : 0) |
                        (isFirstRethrowFrame ? (int)RhEHFrameType.RH_EH_FIRST_RETHROW_FRAME : 0);

            if (pAppendStackFrame != IntPtr.Zero)
            {
                try
                {
                    CalliIntrinsics.CallVoid(pAppendStackFrame, exception, IP, flags);
                }
                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'.
                }
            }
        }