/// <nodoc /> public XlgDebuggerState(DebugLogsAnalyzer analyzer) : base(XlgThreadId) { Analyzer = analyzer; var logFile = Path.Combine(Path.GetDirectoryName(Analyzer.Input.ExecutionLogPath), "BuildXL.status.csv"); StackTrace = new[] { new DisplayStackTraceEntry(file: logFile, line: 1, position: 1, functionName: "<main>", entry: null) }; PipsByType = new ObjectInfo(Enum .GetValues(typeof(PipType)) .Cast <PipType>() .Except(new[] { PipType.Max }) .Select(pipType => new Property(pipType.ToString(), () => PipGraph.RetrievePipReferencesOfType(pipType).ToArray()))); PipsByStatus = new ObjectInfo(Enum .GetValues(typeof(PipExecutionLevel)) .Cast <PipExecutionLevel>() .Select(level => level.ToString()) .Concat(new[] { ExeLevelNotCompleted }) .Select(levelStr => new Property(levelStr, () => GetPipsForExecutionLevel(levelStr)))); RootObject = new ObjectInfo(preview: "Root", properties: new[] { new Property("Pips", () => PipGraph.RetrieveAllPips()), new Property("Files", () => PipGraph.AllFiles), new Property("Directories", () => PipGraph.AllSealDirectories), new Property("DirMembership", () => Analyzer.GetDirMembershipData()), //new Property("CriticalPath", new AnalyzeCricialPath()), new Property("GroupedBy", new ObjectInfo(new[] { new Property("Pips", new PipsScope()), new Property("Files", () => GroupFiles(PipGraph.AllFiles)), new Property("Directories", () => GroupDirs(PipGraph.AllSealDirectories)) })) }); RootEnv = new Env( parent: null, resolver: (obj) => { var result = Renderer.GetObjectInfo(context: this, obj); return(new ObjectInfo( result.Preview, properties: result.Properties .Select(p => new Property(p.Name, value: Renderer.IsInvalid(p.Value) ? new object[0] : p.Value)) .ToArray())); }, vars: LibraryFunctions.All.ToDictionary(f => '$' + f.Name, f => Result.Scalar(f)), current: RootObject); Evaluator = new Evaluator( new Env(parent: RootEnv, resolver: RootEnv.Resolver, current: RootEnv.Current), Analyzer.EnableEvalCaching); }
public override int Analyze() { Console.WriteLine($"Analyzing"); m_block.Complete(); m_block.CompletionAsync().GetAwaiter().GetResult(); Console.WriteLine($"Writing Graph"); foreach (var pip in PipGraph.RetrieveAllPips()) { var serializedPip = pip; var nodeId = pip.PipId.ToNodeId(); bool addEdges = true; if (pip.PipType == PipType.Process) { var entry = GetEntry(pip.PipId); serializedPip = entry.Process; addEdges = !entry.AddedEdges; } if (addEdges && AddEdgesForPips) { using (var scope = m_mutableGraph.AcquireExclusiveIncomingEdgeScope(nodeId)) { foreach (var edge in DataflowGraph.GetIncomingEdges(nodeId)) { scope.AddEdge(edge.OtherNode, edge.IsLight); } } } serializedPip.ResetPipIdForTesting(); m_pipTable.Add(nodeId.Value, serializedPip); } m_mutableGraph.Seal(); CachedGraph.Serializer.SerializeToFileAsync( GraphCacheFile.DirectedGraph, m_mutableGraph.Serialize, Path.Combine(OutputFilePath, nameof(GraphCacheFile.DirectedGraph))) .GetAwaiter().GetResult(); CachedGraph.Serializer.SerializeToFileAsync( GraphCacheFile.PipTable, w => m_pipTable.Serialize(w, Environment.ProcessorCount), Path.Combine(OutputFilePath, nameof(GraphCacheFile.PipTable))) .GetAwaiter().GetResult(); CachedGraph.Serializer.SerializeToFileAsync( GraphCacheFile.PipGraphId, PipGraph.SerializeGraphId, Path.Combine(OutputFilePath, nameof(GraphCacheFile.PipGraphId))) .GetAwaiter().GetResult(); Console.WriteLine($"Simulating [Reading]"); var simulator = new BuildSimulatorAnalyzer(Input); simulator.Increment = SimulatorIncrement ?? simulator.Increment; simulator.ExecutionData.DataflowGraph = m_mutableGraph; simulator.OutputDirectory = OutputFilePath; simulator.ReadExecutionLog(); Console.WriteLine($"Simulating [Analyzing]"); simulator.Analyze(); Console.WriteLine($"Blocking Dependency Analysis"); DisplayTable <DepColumn> depTable = new DisplayTable <DepColumn>(" , "); foreach (var pipId in PipTable.Keys) { var pipType = PipTable.GetPipType(pipId); if (pipType == PipType.Process) { var entry = GetEntry(pipId); (PipId node, ulong cost)maxConsumedDependency = default; (PipId node, ulong cost)maxDependency = default; foreach (var dep in entry.PipDependencies) { var cost = simulator.ExecutionData.BottomUpAggregateCosts[dep.Key.ToNodeId()]; if (!maxDependency.node.IsValid || cost > maxDependency.cost) { maxDependency = (dep.Key, cost); } if (dep.Value != null && dep.Value.HasFlag(ContentFlag.Consumed)) { if (!maxConsumedDependency.node.IsValid || cost > maxConsumedDependency.cost) { maxConsumedDependency = (dep.Key, cost); } } } depTable.NextRow(); depTable.Set(DepColumn.Id, $"{entry.SpecFileName}-{entry.Identifier}"); depTable.Set(DepColumn.MaxConsumedDependency, ToString(maxConsumedDependency.node)); depTable.Set(DepColumn.MaxConsumedDependencyChainCost, maxConsumedDependency.cost.ToMinutes()); depTable.Set(DepColumn.MaxDependency, ToString(maxDependency.node)); depTable.Set(DepColumn.MaxDependencyChainCost, maxDependency.cost.ToMinutes()); } else if (pipType == PipType.SealDirectory && !PipTable.GetSealDirectoryKind(pipId).IsSourceSeal() && !IsSourceOnlySeal(pipId)) { var seal = (SealDirectory)GetPip(pipId); var entry = GetEntry(seal.Directory); (PipId node, ulong cost)maxDependency = default; foreach (var dep in DataflowGraph.GetIncomingEdges(pipId.ToNodeId())) { var cost = simulator.ExecutionData.BottomUpAggregateCosts[dep.OtherNode]; if (!maxDependency.node.IsValid || cost > maxDependency.cost) { maxDependency = (dep.OtherNode.ToPipId(), cost); } } depTable.NextRow(); depTable.Set(DepColumn.Id, $"{entry.SpecFileName}-{entry.Identifier} ({entry.FileCount} files)"); depTable.Set(DepColumn.MaxDependency, ToString(maxDependency.node)); depTable.Set(DepColumn.MaxDependencyChainCost, maxDependency.cost.ToMinutes()); depTable.Set(DepColumn.Directory, seal.DirectoryRoot.ToString(PathTable)); } } using (var blockAnalysisWriter = new StreamWriter(Path.Combine(OutputFilePath, "blockAnalysis.txt"))) { depTable.Write(blockAnalysisWriter); } m_writer.Dispose(); Console.WriteLine($"Analyzing complete"); return(0); }