Beispiel #1
0
 public static T SimpleRefWrap <T>(ref T tgt, SimpleRefDel <T> originalCode, String instrMethod)
 {
     using (_ProtectingThreadContext.Acquire())
     {
         if (WrapperSentry.Wrap())
         {
             ClrSyncManager manager = ClrSyncManager.SyncManager;
             manager.SetMethodInfo(instrMethod);
             if (manager.TrackGC)
             {
                 return(ref_wrap_gcaddr(manager, ref tgt, originalCode));
             }
             else if (manager.TrackVolatile)
             {
                 return(ref_wrap_uintptr(manager, ref tgt, originalCode));
             }
             else
             {
                 return(originalCode(ref tgt));
             }
         }
         else
         {
             return(originalCode(ref tgt));
         }
     }
 }
Beispiel #2
0
        public static Timer CreateTimer(ClrSyncManager manager, Original::TimerCallback timerCallback, object state, TimeSpan dueTime, TimeSpan period)
        {
            TimerRoutineArg argument = new TimerRoutineArg();

            argument.callback        = timerCallback;
            argument.state           = state;
            argument.dueTime         = dueTime;
            argument.Period          = period;
            argument.selfSemaphore   = new Semaphore(0, 1);
            argument.parentSemaphore = new Semaphore(0, 1);
            argument.disposed        = false;
            argument.changed         = true;

            Timer ret = new Timer(TimerCreateWrapper, argument, 0, Timeout.Infinite);

            argument.timer = ret;
            timer2tra.Add(ret, argument);
            int child = manager.TaskFork();

            argument.parentSemaphore.WaitOne();
            manager.RegisterTaskSemaphore(child, argument.selfSemaphore, false);
            manager.TaskResume(child);

            return(ret);
        }
Beispiel #3
0
 public static Action <Object> TaskCreateWrapper(ClrSyncManager manager)
 {
     return
         (delegate(Object o)
     {
         try
         {
             TaskArg p = (TaskArg)o;
             p.e.Set();
             manager.ThreadBegin(p.s);
             MChessChess.LeaveChess();
             Exception exception = null;
             try
             {
                 var tryExecuteTask = p.taskScheduler.GetType().GetMethod("TryExecuteTask",
                                                                          global::System.Reflection.BindingFlags.NonPublic |
                                                                          global::System.Reflection.BindingFlags.Instance);
                 tryExecuteTask.Invoke(p.taskScheduler, new object[] { p.task });
             }
             catch (Exception e)     // catch recoverable exception in user code
             {
                 exception = e;
             }
             MChessChess.EnterChess();
             manager.SetMethodInfo("Task.End");
             manager.AggregateSyncVarAccess(
                 new object[] { p.task, ((IAsyncResult)p.task).AsyncWaitHandle },
                 MSyncVarOp.RWEVENT);
             manager.CommitSyncVarAccess();
             if (manager.BreakDeadlockMode)
             {
                 MChessChess.WakeNextDeadlockedThread(false, true);
             }
             else if (exception == null)
             {
                 manager.ThreadEnd(Original::Thread.CurrentThread);
             }
             else
             {
                 manager.Shutdown(exception);
             }
         }
         catch (Exception e)     // catch fatal exception in our code
         {
             manager.Shutdown(e);
         }
     });
 }
Beispiel #4
0
 public static void SimpleWrap <T>(ref T r, SimpleDelManagerRef <T> instrumentedCode, SimpleDelRef <T> originalCode)
 {
     using (_ProtectingThreadContext.Acquire())
     {
         if (WrapperSentry.Wrap())
         {
             using (new WrapperSentry())
             {
                 ClrSyncManager manager = ClrSyncManager.SyncManager;
                 instrumentedCode(manager, ref r);
             }
         }
         else
         {
             originalCode(ref r);
         }
     }
 }
Beispiel #5
0
 public static T SimpleWrap <T>(SimpleDelManager <T> instrumentedCode, SimpleDel <T> originalCode)
 {
     using (_ProtectingThreadContext.Acquire())
     {
         if (WrapperSentry.Wrap())
         {
             using (new WrapperSentry())
             {
                 ClrSyncManager manager = ClrSyncManager.SyncManager;
                 return(instrumentedCode(manager));
             }
         }
         else
         {
             return(originalCode());
         }
     }
 }
Beispiel #6
0
        private static T ref_wrap_uintptr <T>(ClrSyncManager manager, ref T tgt, SimpleRefDel <T> originalCode)
        {
            T   ret;
            var ptr = ObjectTracking.GetCurrentRawAddress(ref tgt);

            manager.SyncVarAccess(ptr, MSyncVarOp.RWVAR_READWRITE);
            try
            {
                ret = originalCode(ref tgt);
            }
            catch (Exception e)
            {
                manager.CommitSyncVarAccess();
                throw e;
            }
            manager.CommitSyncVarAccess();
            return(ret);
        }
Beispiel #7
0
 public static WaitCallback ThreadCreateWrapper(ClrSyncManager manager)
 {
     return
         (delegate(object o)
     {
         try
         {
             ThreadRoutineArg p = (ThreadRoutineArg)o;
             manager.ThreadBegin(p.s);
             MChessChess.LeaveChess();
             Exception exception = null;
             try
             {
                 p.wcb(p.o);
             }
             catch (Exception e)     // catch recoverable exception in user code
             {
                 exception = e;
             }
             MChessChess.EnterChess();
             if (manager.BreakDeadlockMode)
             {
                 MChessChess.WakeNextDeadlockedThread(false, true);
             }
             else if (exception == null)
             {
                 manager.ThreadEnd(Original::Thread.CurrentThread);
             }
             else
             {
                 manager.Shutdown(exception);
             }
         }
         catch (Exception e)     // catch fatal exception in our code
         {
             manager.Shutdown(e);
         }
     });
 }
Beispiel #8
0
        public static T SimpleContextExposingWrap <T>(SimpleDelManagerContext <T> instrumentedCode, SimpleDel <T> originalCode)
        {
            IDisposable protectingcontext = _ProtectingThreadContext.Acquire();

            try
            {
                if (WrapperSentry.Wrap())
                {
                    using (new WrapperSentry())
                    {
                        ClrSyncManager manager = ClrSyncManager.SyncManager;
                        return(instrumentedCode(manager, ref protectingcontext));
                    }
                }
                else
                {
                    return(originalCode());
                }
            }
            finally
            {
                protectingcontext.Dispose();
            }
        }
Beispiel #9
0
        private static T ref_wrap_gcaddr <T>(ClrSyncManager manager, ref T tgt, SimpleRefDel <T> originalCode)
        {
            GCAddress gca;

            if (GCAddress.FromByRef(ref tgt, out gca))
            {
                try
                {
                    manager.SyncVarAccess(gca, MSyncVarOp.RWVAR_READWRITE);
                    T ret;
                    try
                    {
                        ret = originalCode(ref tgt);
                    }
                    catch (Exception e)
                    {
                        manager.CommitSyncVarAccess();
                        throw e;
                    }
                    manager.CommitSyncVarAccess();
                    return(ret);
                }
                finally
                {
                    gca.Release();
                }
            }
            else
            {
                // GC tracking returns false when addr is
                // -	On the stack, or
                // -	Allocated by native code, or
                // -	When it points to certain static fields, and you have only volatile-tracking enabled, but not all read/write accesses.
                return(ref_wrap_uintptr <T>(manager, ref tgt, originalCode));
            }
        }
Beispiel #10
0
        public static WaitOrTimerCallback RegisterWaitForSingleObjectWrapper(ClrSyncManager manager)
        {
            return
                (delegate(object argument, bool timedOut)
            {
                try
                {
                    global::System.Diagnostics.Debug.Assert(!timedOut);
                    Helper.WaitOrTimerCallbackRoutineArg p = (Helper.WaitOrTimerCallbackRoutineArg)argument;
                    p.a.Set();

                    manager.ThreadBegin(p.s);
                    WaitHandle cancelObject = null;

                    while (true)
                    {
                        manager.SetMethodInfo("RegisteredWaitForSingleObject.CheckCancellation");
                        manager.SyncVarAccess(p, MSyncVarOp.RWVAR_READWRITE);
                        bool cancelled = p.canceled;
                        cancelObject = p.onCancellation;
                        if (cancelled)
                        {
                            p.finished = true;
                        }
                        manager.CommitSyncVarAccess();
                        if (cancelled)
                        {
                            break;
                        }

                        MChessChess.LeaveChess();
                        bool flag = __Substitutions.System.Threading.WaitHandle.WaitOne(p.waitObject, (int)p.millisecondsTimeOutInterval, false);
                        p.callback(p.state, !flag);
                        MChessChess.EnterChess();

                        if (p.executeOnlyOnce)
                        {
                            manager.SetMethodInfo("RegisteredWaitForSingleObject.ReadOnCancellation");
                            manager.SyncVarAccess(p, MSyncVarOp.RWVAR_READWRITE);
                            cancelObject = p.onCancellation;
                            p.finished = true;
                            manager.CommitSyncVarAccess();
                            break;
                        }
                    }

                    MChessChess.LeaveChess();
                    Exception exception = null;
                    try
                    {
                        if (cancelObject != null)
                        {
                            __Substitutions.System.Threading.EventWaitHandle.Set((EventWaitHandle)cancelObject);
                        }
                    }
                    catch (Exception e)     // catch recoverable exception in monitored code
                    {
                        exception = e;
                    }
                    MChessChess.EnterChess();
                    if (manager.BreakDeadlockMode)
                    {
                        MChessChess.WakeNextDeadlockedThread(false, true);
                    }
                    else if (exception == null)
                    {
                        manager.ThreadEnd(Original::Thread.CurrentThread);
                    }
                    else
                    {
                        manager.Shutdown(exception);
                    }
                }
                catch (Exception e)     // catch fatal exception in our code
                {
                    manager.Shutdown(e);
                }
            });
        }
Beispiel #11
0
 public static Original::ParameterizedThreadStart WrapParamThreadStart(Original::ParameterizedThreadStart del, ClrSyncManager manager)
 {
     return(delegate(object o)
     {
         try
         {
             manager.ThreadBegin(Original::Thread.CurrentThread);
             MChessChess.LeaveChess();
             Exception exception = null;
             try
             {
                 CheckThreadReadyForMonitoring();
                 del(o);
             }
             catch (Exception e) // catch recoverable exception in user code
             {
                 exception = e;
             }
             MChessChess.EnterChess();
             if (manager.BreakDeadlockMode)
             {
                 MChessChess.WakeNextDeadlockedThread(false, true);
             }
             else if (exception == null)
             {
                 manager.ThreadEnd(Original::Thread.CurrentThread);
             }
             else
             {
                 manager.Shutdown(exception);
             }
         }
         catch (Exception e) // catch fatal exception in our code
         {
             manager.Shutdown(e);
         }
     });
 }
Beispiel #12
0
        public ChessMain(MChessOptions m, Assembly a, string testClassName, string unitTestName)
        {
            this.mco                = m;
            this.testAssembly       = a;
            this.testclass          = testClassName;
            this.unitTestMethodName = unitTestName;
            this.runUnitTest        = !String.IsNullOrEmpty(unitTestMethodName);

            this.manager = new ClrSyncManager(m);
            MChessChess.Init(manager, mco);

            TryLoadReferencedAssemblies(new[] { testAssembly });
            get_entries(testAssembly);
            popups(m);

            this.manager.SetExitCallBack((c, ex) => {
                string msg = "";
                if (ex != null)
                {
                    msg = @"Child thread raised exception
" + ex.Message + @"
Stack trace:
" + ex.StackTrace + @"
";
                    ReportErrorAndExit(msg, c, true, ex);
                }
                ReportErrorAndExitRaw("", c, true, true, null);
            });

            try
            {
                do_startup();

                // print warning if races are disabled
                if (MChessChess.GetExitCode() == 0 && !(mco.preemptAccesses || mco.sober ||
                                                        mco.maxExecutions == 1 || !String.IsNullOrEmpty(mco.enumerateObservations)))
                {
                    MChessChess.ReportWarning("Race Detection Disabled. Races May Hide Bugs.", "", false);
                }

                // RunTest loop
                bool moreToTest = true;
                while (moreToTest)
                {
                    if (!MChessChess.StartTest())
                    {
                        ReportErrorAndExit("Internal failure: CHESS.StartTest failed", ChessExitCode.ChessFailure, false, null);
                    }

                    if (MyEngine.EnvironmentVars.FlipPreemptSense)
                    {
                        MChessChess.PreemptionDisable();
                    }
                    do_run();
                    if (MyEngine.EnvironmentVars.FlipPreemptSense)
                    {
                        MChessChess.PreemptionEnable();
                    }

                    if (manager.BreakDeadlockMode)
                    {
                        MChessChess.EnterChess();
                        MChessChess.WakeNextDeadlockedThread(true, false);
                        // we are now done with the deadlock-breaking mode!
                        Debug.Assert(!MChessChess.IsBreakingDeadlock());
                        manager.BreakDeadlockMode = false;
                        MChessChess.LeaveChess();
                    }
                    moreToTest = MChessChess.EndTest();
                }

                do_shutdown();
            }
            catch (Exception ex)
            {
                string message = @"CHESS internal failure.
" + ex.Message + @"
" + ex.StackTrace + @"
";
                ReportErrorAndExit(message, ChessExitCode.ChessFailure, false, ex);
            }
            ReportErrorAndExit("", (ChessExitCode)MChessChess.GetExitCode(), false, null);
        }
Beispiel #13
0
        // dueTime:  the amount of time to delay before callback is invoked, in milliseconds.
        // Specify Timeout.Infinite to prevent the timer from starting.
        //  Specify zero (0) to start the timer immediately.
        // period: The time interval between invocations of callback, in milliseconds.
        // Specify Timeout.Infinite to disable periodic signaling.

        // The method specified for callback should be reentrant, because it is called on ThreadPool threads.
        // The method can be executed simultaneously on two thread pool threads if the timer interval is less
        // than the time required to execute the method, or if all thread pool threads are in use and the method
        // is queued multiple times.

        public static void TimerCreateWrapper(object start)
        {
            try
            {
                TimerRoutineArg argument = (TimerRoutineArg)start;
                argument.inLoop  = true;
                argument.changed = false;
                argument.parentSemaphore.Release();
                ClrSyncManager manager = ClrSyncManager.SyncManager;
                manager.ThreadBegin(argument.selfSemaphore);
                Exception exception = null;
                while (true)
                {
                    manager.SetMethodInfo("Timer.read");
                    manager.SyncVarAccess(argument.timer, MSyncVarOp.RWVAR_READWRITE);
                    manager.CommitSyncVarAccess();

                    if (timer2tra[argument.timer].disposed)
                    {
                        // the timer only goes away when it is disposed of
                        // it may be disabled, but a Change can reenable it
                        break;
                    }

                    manager.TaskYield();    // until fairness deals with unbounded thread creation
                    manager.TaskYield();    // we yield twice

                    if (!argument.dueTime.Equals(TimeSpan.FromTicks(Timeout.Infinite)))
                    {
                        MChessChess.LeaveChess();
                        try
                        {
                            argument.callback(argument.state);
                        }
                        catch (Exception e) // catch recoverable exception in monitored code
                        {
                            exception = e;
                        }
                        MChessChess.EnterChess();
                        // If period is zero (0) or Infinite and dueTime is not Infinite, callback is invoked once;
                        // the periodic behavior of the timer is disabled, but can be re-enabled using the Change method.
                    }

                    if (exception != null)
                    {
                        break;
                    }

                    if (argument.changed)
                    {
                        argument.changed = false;
                        continue;
                    }

                    if (argument.Period.Equals(TimeSpan.FromTicks(Timeout.Infinite)) || argument.Period.Equals(TimeSpan.FromTicks(0)))
                    {
                        break;
                    }
                }
                argument.inLoop = false;
                if (timer2tra[argument.timer].disposed)
                {
                    timer2tra.Remove(argument.timer);
                }

                if (manager.BreakDeadlockMode)
                {
                    MChessChess.WakeNextDeadlockedThread(false, true);
                }
                else if (exception == null)
                {
                    manager.ThreadEnd(System.Threading.Thread.CurrentThread);
                }
                else
                {
                    manager.Shutdown(exception);
                }
            }
            catch (Exception e) // catch fatal error in our code
            {
                ClrSyncManager manager = ClrSyncManager.SyncManager;
                manager.Shutdown(e);
            }
        }
Beispiel #14
0
        static public bool Wrap()
        {
            ClrSyncManager manager = ClrSyncManager.SyncManager;

            return(manager != null && manager.IsInitialized && not_tracked > 0);
        }