示例#1
0
        internal static RubyExceptionData /*!*/ AssociateInstance(Exception /*!*/ e)
        {
            RubyExceptionData result;

            Exception visibleException = RubyUtils.GetVisibleException(e);

            if (e == visibleException || visibleException == null)
            {
                result = new RubyExceptionData(e);
            }
            else
            {
                // Async exception

                Debug.Assert(e is ThreadAbortException);
                result = GetInstance(visibleException);

                if (result._exception == visibleException)
                {
                    // A different instance of ThreadAbortException is thrown at the end of every catch block (as long as
                    // Thread.ResetAbort is not called). However, we only want to remember the first one
                    // as it will have the most complete stack trace.
                    result._exception = e;
                }
            }

            e.Data[_DataKey] = result;
            return(result);
        }
示例#2
0
        public static void ActiveExceptionHandled(Exception visibleException)
        {
            Debug.Assert(RubyUtils.GetVisibleException(visibleException) == visibleException);

            RubyExceptionData data = RubyExceptionData.GetInstance(visibleException);

            if (data._exception != visibleException)
            {
                // The exception was raised asynchronously with Thread.Abort. We can not just catch and ignore
                // the ThreadAbortException as the CLR keeps trying to re-raise it unless ResetAbort is called.
                //
                // Note that ResetAbort can cause ThreadAbortException.ExceptionState to be cleared (though it may
                // not be cleared under some circustances), and we use that to squirrel away the Ruby exception
                // that the user is expecting. Hence, ResetAbort should only be called when
                // ThreadAbortException.ExceptionState no longer needs to be accessed.
                if ((Thread.CurrentThread.ThreadState & System.Threading.ThreadState.AbortRequested) != 0)
                {
                    Thread.ResetAbort();
                }
            }
        }