예제 #1
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();
                }
            }
        }
예제 #2
0
 internal static RubyExceptionData/*!*/ AssociateInstance(Exception/*!*/ e) {
     var result = new RubyExceptionData(e);
     e.Data[_DataKey] = result;
     return result;
 }
예제 #3
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;
        }