Example #1
0
        public Args(string[] args)
            : base(args)
        {
            List <Option> analyzerOptions      = new List <Option>();
            string        cachedGraphDirectory = null;

            // TODO: Embed HashType in XLG file and update analyzer to use that instead of setting HashType globally.
            ContentHashingUtilities.SetDefaultHashType();

            foreach (Option opt in Options)
            {
                if (opt.Name.Equals("executionLog", StringComparison.OrdinalIgnoreCase) ||
                    opt.Name.Equals("xl", StringComparison.OrdinalIgnoreCase))
                {
                    if (string.IsNullOrEmpty(m_analysisInput.ExecutionLogPath))
                    {
                        m_analysisInput.ExecutionLogPath = ParsePathOption(opt);
                    }
                    else
                    {
                        m_analysisInputOther.ExecutionLogPath = ParseSingletonPathOption(opt, m_analysisInputOther.ExecutionLogPath);
                    }
                }
                else if (opt.Name.Equals("graphDirectory", StringComparison.OrdinalIgnoreCase) ||
                         opt.Name.Equals("gd", StringComparison.OrdinalIgnoreCase))
                {
                    cachedGraphDirectory = ParseSingletonPathOption(opt, cachedGraphDirectory);
                }
                else if (opt.Name.Equals("mode", StringComparison.OrdinalIgnoreCase) ||
                         opt.Name.Equals("m", StringComparison.OrdinalIgnoreCase))
                {
                    m_mode = ParseEnumOption <AnalysisMode>(opt);
                }
                else if (opt.Name.Equals("disableTelemetry"))
                {
                    m_telemetryDisabled = true;
                }
                else if (opt.Name.Equals("disableWorkerEvents", StringComparison.OrdinalIgnoreCase))
                {
                    m_canHandleWorkerEvents = false;
                }
                else if (s_helpStrings.Any(s => opt.Name.Equals(s, StringComparison.OrdinalIgnoreCase)))
                {
                    // If the analyzer was called with '/help' argument - print help and exit
                    Help = true;
                    WriteHelp();
                    return;
                }
                else
                {
                    analyzerOptions.Add(opt);
                }
            }

            AnalyzerOptions = analyzerOptions;
            if (!m_mode.HasValue)
            {
                throw Error("Mode parameter is required");
            }

            // Add required parameter errors here
            switch (m_mode.Value)
            {
            case AnalysisMode.ObservedAccess:
            {
                if (!analyzerOptions.Any(opt => opt.Name.Equals("o")))
                {
                    throw Error("When executing `ObservedAccess` mode, an `/o:PATH_TO_OUTPUT_FILE` parameter is required to store the generated output");
                }
                break;
            }
            }

            // Only send telemetry if all arguments were valid
            TelemetryStartup();

            switch (m_mode.Value)
            {
            case AnalysisMode.SpecClosure:
                var analyzer = InitializeSpecClosureAnalyzer();
                analyzer.Analyze();
                break;
            }

            if (string.IsNullOrEmpty(m_analysisInput.ExecutionLogPath) && string.IsNullOrEmpty(cachedGraphDirectory))
            {
                // Try to find the last build log from the user if none was specied.
                var invocation = new global::BuildXL.Engine.Invocations().GetLastInvocation(LoggingContext);
                if (invocation == null || !Directory.Exists(invocation.Value.LogsFolder))
                {
                    throw Error("executionLog or graphDirectory parameter is required");
                }

                Console.WriteLine("Using last build from: '{0}', you can use /executionLog or /graphDirectory arguments to explicitly choose a build", invocation.Value.LogsFolder);
                m_analysisInput.ExecutionLogPath = invocation.Value.LogsFolder;
            }

            if (m_mode.Value == AnalysisMode.LogCompare && string.IsNullOrEmpty(m_analysisInput.ExecutionLogPath))
            {
                throw Error("Additional executionLog to compare parameter is required");
            }

            // The fingerprint store based cache miss analyzer and the bxl invocation analyzer
            // only use graph information from the newer build, so skip loading the graph for the earlier build
            // TODO: To avoid large "||" statements, convert this to a list or enum or struct and check if the mode is "in" that data structure
            if (m_mode.Value != AnalysisMode.CacheMiss || m_mode.Value != AnalysisMode.BXLInvocationXLG)
            {
                if (!m_analysisInput.LoadCacheGraph(cachedGraphDirectory))
                {
                    throw Error($"Could not load cached graph from directory {cachedGraphDirectory}");
                }
            }

            switch (m_mode.Value)
            {
            case AnalysisMode.FingerprintText:
                m_analyzer = InitializeFingerprintTextAnalyzer();
                break;

            case AnalysisMode.ExportGraph:
                m_analyzer = InitializePipGraphExporter();
                break;

            case AnalysisMode.DirMembership:
                m_analyzer = InitializeDirMembershipAnalyzer();
                break;

            case AnalysisMode.Dev:
                m_analyzer = InitializeDevAnalyzer();
                break;

            case AnalysisMode.DumpProcess:
                m_analyzer = InitializeDumpProcessAnalyzer();
                break;

            case AnalysisMode.EventStats:
                m_analyzer = InitializeEventStatsAnalyzer();
                break;

            case AnalysisMode.Simulate:
                m_analyzer = InitializeBuildSimulatorAnalyzer(m_analysisInput);
                break;

            case AnalysisMode.ExportDgml:
                m_analyzer = InitializeExportDgmlAnalyzer();
                break;

            case AnalysisMode.CriticalPath:
                m_analyzer = InitializeCriticalPathAnalyzer();
                break;

            case AnalysisMode.FileImpact:
                m_analyzer = InitializeFileImpactAnalyzer();
                break;

            case AnalysisMode.FileConsumption:
                m_analyzer = InitializeFileConsumptionAnalyzer();
                break;

            case AnalysisMode.Codex:
                m_analyzer = InitializeCodexAnalyzer();
                break;

            case AnalysisMode.DumpPip:
                m_analyzer = InitializeDumpPipAnalyzer();
                break;

            case AnalysisMode.CosineDumpPip:
                m_analyzer = InitializeCosineDumpPip();
                break;

            case AnalysisMode.CosineJson:
                m_analyzer = InitializeCosineJsonExport();
                break;

            case AnalysisMode.ProcessRunScript:
                m_analyzer = InitializeProcessRunScriptAnalyzer();
                break;

            case AnalysisMode.ObservedInput:
                m_analyzer = InitializeObservedInputResult();
                break;

            case AnalysisMode.ObservedInputSummary:
                m_analyzer = InitializeObservedInputSummaryResult();
                break;

            case AnalysisMode.ToolEnumeration:
                m_analyzer = InitializeToolEnumerationAnalyzer();
                break;

            case AnalysisMode.FailedPipInput:
                m_analyzer = InitializeFailedPipInputAnalyzer();
                break;

            case AnalysisMode.FailedPipsDump:
                m_analyzer = InitializeFailedPipsDumpAnalyzer();
                if (!string.IsNullOrEmpty(m_analysisInputOther.ExecutionLogPath))
                {
                    if (!m_analysisInputOther.LoadCacheGraph(null))
                    {
                        throw Error("Could not load second cached graph");
                    }
                    m_analyzerOther = ((FailedPipsDumpAnalyzer)m_analyzer).GetDiffAnalyzer(m_analysisInputOther);
                }
                break;

            case AnalysisMode.Whitelist:
                m_analyzer = InitializeWhitelistAnalyzer();
                break;

            case AnalysisMode.IdeGenerator:
                m_analyzer = InitializeIdeGenerator();
                break;

            case AnalysisMode.PipExecutionPerformance:
                m_analyzer = InitializePipExecutionPerformanceAnalyzer();
                break;

            case AnalysisMode.ProcessDetouringStatus:
                m_analyzer = InitializeProcessDetouringStatusAnalyzer();
                break;

            case AnalysisMode.ObservedAccess:
                m_analyzer = InitializeObservedAccessAnalyzer();
                break;

            case AnalysisMode.CacheDump:
                m_analyzer = InitializeCacheDumpAnalyzer(m_analysisInput);
                break;

            case AnalysisMode.BuildStatus:
                m_analyzer = InitializeBuildStatus(m_analysisInput);
                break;

            case AnalysisMode.WinIdeDependency:
                m_analyzer = InitializeWinIdeDependencyAnalyzer();
                break;

            case AnalysisMode.PerfSummary:
                m_analyzer = InitializePerfSummaryAnalyzer();
                break;

            case AnalysisMode.LogCompare:
                m_analyzer = InitializeSummaryAnalyzer(m_analysisInput);
                if (!m_analysisInputOther.LoadCacheGraph(null))
                {
                    throw Error("Could not load second cached graph");
                }

                m_analyzerOther = InitializeSummaryAnalyzer(m_analysisInputOther, true);
                break;

            case AnalysisMode.CacheMissLegacy:
                m_analyzer = InitializeCacheMissAnalyzer(m_analysisInput);
                if (!m_analysisInputOther.LoadCacheGraph(null))
                {
                    throw Error("Could not load second cached graph");
                }

                m_analyzerOther = ((CacheMissAnalyzer)m_analyzer).GetDiffAnalyzer(m_analysisInputOther);
                break;

            case AnalysisMode.IncrementalSchedulingState:
                m_analyzer = InitializeIncrementalSchedulingStateAnalyzer();
                break;

            case AnalysisMode.FileChangeTracker:
                m_analyzer = InitializeFileChangeTrackerAnalyzer();
                break;

            case AnalysisMode.InputTracker:
                m_analyzer = InitializeInputTrackerAnalyzer();
                break;

            case AnalysisMode.FilterLog:
                m_analyzer = InitializeFilterLogAnalyzer();
                break;

            case AnalysisMode.PipFilter:
                m_analyzer = InitializePipFilterAnalyzer();
                break;

            case AnalysisMode.CacheMiss:
                // This analyzer does not rely on the execution log
                if (!m_analysisInputOther.LoadCacheGraph(null))
                {
                    throw Error("Could not load second cached graph");
                }
                m_analyzer = InitializeFingerprintStoreAnalyzer(m_analysisInput, m_analysisInputOther);
                break;

            case AnalysisMode.PipFingerprint:
                m_analyzer = InitializePipFingerprintAnalyzer(m_analysisInput);
                break;

            case AnalysisMode.RequiredDependencies:
                m_analyzer = InitializeRequiredDependencyAnalyzer();
                break;

            case AnalysisMode.ScheduledInputsOutputs:
                m_analyzer = InitializeScheduledInputsOutputsAnalyzer();
                break;

#if FEATURE_VSTS_ARTIFACTSERVICES
            case AnalysisMode.CacheHitPredictor:
                m_analyzer = InitializeCacheHitPredictor();
                break;
#endif
            case AnalysisMode.DependencyAnalyzer:
                m_analyzer = InitializeDependencyAnalyzer();
                break;

            case AnalysisMode.GraphDiffAnalyzer:
                if (!m_analysisInputOther.LoadCacheGraph(null))
                {
                    throw Error("Could not load second cached graph");
                }
                m_analyzer = InitializeGraphDiffAnalyzer();
                break;

            case AnalysisMode.DumpMounts:
                m_analyzer = InitializeDumpMountsAnalyzer();
                break;

            case AnalysisMode.CopyFile:
                m_analyzer = InitializeCopyFilesAnalyzer();
                break;

            case AnalysisMode.XlgToDb:
                m_analyzer = InitializeXLGToDBAnalyzer();
                break;

            case AnalysisMode.BXLInvocationXLG:
                m_analyzer = InitializeBXLInvocationAnalyzer();
                break;

            case AnalysisMode.EventStatsXldb:
                m_analyzer = InitializeEventStatsXldbAnalyzer();
                break;

            case AnalysisMode.DumpPipXldb:
                m_analyzer = InitializeDumpPipXldbAnalyzer();
                break;

            case AnalysisMode.DebugLogs:
                ConsoleListener.RegisterEventSource(ETWLogger.Log);
                ConsoleListener.RegisterEventSource(FrontEnd.Script.Debugger.ETWLogger.Log);
                m_analyzer = InitializeDebugLogsAnalyzer();
                break;

            default:
                Contract.Assert(false, "Unhandled analysis mode");
                break;
            }

            Contract.Assert(m_analyzer != null, "Analyzer must be set.");

            m_analyzer.LoggingContext        = LoggingContext;
            m_analyzer.CanHandleWorkerEvents = m_canHandleWorkerEvents;
            if (m_analyzerOther != null)
            {
                m_analyzerOther.CanHandleWorkerEvents = m_canHandleWorkerEvents;
            }
        }