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); }