private void GetProcessDirectoryDependenciesContents() { Process process = null; foreach (var pipId in PipTable.StableKeys) { var possibleMatch = PipTable.GetPipSemiStableHash(pipId); if (possibleMatch == PipSemistableHash) { process = (Process)GetPip(pipId); } } foreach (var directory in process.DirectoryDependencies) { m_writer.WriteLine(directory.Path.ToString(PathTable)); foreach (var file in PipGraph.ListSealedDirectoryContents(directory)) { m_writer.WriteLine(file.Path.ToString(PathTable)); } m_writer.WriteLine(); } m_writer.Flush(); }
private ObjectInfo DirectoryArtifactInfo(DirectoryArtifact d) { if (!d.IsValid) { return(new ObjectInfo("Invalid")); } var name = d.Path.GetName(PathTable).ToString(StringTable); var kind = d.IsSharedOpaque ? "shared opaque" : d.IsOutputDirectory() ? "exclusive opaque" : "source"; var members = d.IsOutputDirectory() ? Analyzer.GetDirMembers(d, PipGraph.GetProducer(d)) : d.PartialSealId > 0 ? PipGraph.ListSealedDirectoryContents(d).Select(f => f.Path) : CollectionUtilities.EmptyArray <AbsolutePath>(); return(new ObjectInfo( preview: $"{name} [{kind}]", properties: new[] { new Property("Path", d.Path.ToString(PathTable)), new Property("PartialSealId", d.PartialSealId), new Property("Kind", kind), d.IsOutputDirectory() ? new Property("Producer", () => Analyzer.GetPip(PipGraph.GetProducer(d))) : null, new Property("Consumers", PipGraph.GetConsumingPips(d)), new Property("Members", members) } .Where(p => p != null))); }
public override void Prepare() { Directory.CreateDirectory(OutputFilePath); m_writer = new StreamWriter(Path.Combine(OutputFilePath, "results.txt")); Console.WriteLine("Creating nodes"); foreach (var node in DataflowGraph.Nodes) { m_mutableGraph.CreateNode(); } Console.WriteLine("Created nodes"); foreach (var entry in PipGraph.AllOutputDirectoriesAndProducers) { var sealId = PipGraph.GetSealedDirectoryNode(entry.Key).ToPipId(); m_dynamicDirectoryProducers[sealId] = entry.Value; } foreach (CopyFile copyFile in PipGraph.RetrievePipsOfType(PipType.CopyFile)) { m_copiedFilesByTarget[copyFile.Destination] = copyFile.Source; } foreach (var directory in PipGraph.AllSealDirectories) { var sealId = PipGraph.GetSealedDirectoryNode(directory).ToPipId(); var sealKind = PipTable.GetSealDirectoryKind(sealId); // Populate map of whether this is a source only seal IsSourceOnlySeal(sealId); if (sealKind == SealDirectoryKind.Full || sealKind == SealDirectoryKind.Partial) { PipId?singleProducer = null; foreach (var file in PipGraph.ListSealedDirectoryContents(directory)) { if (file.IsOutputFile) { var producer = PipGraph.TryGetProducer(file); if (singleProducer == null) { singleProducer = producer; } else if (singleProducer != producer) { singleProducer = PipId.Invalid; } } } if (singleProducer.HasValue && singleProducer.Value.IsValid) { m_dynamicDirectoryProducers[sealId] = singleProducer.Value; } } } }
private ReadOnlyArray <FileArtifact> GetContents(DirectoryArtifact directoryArtifact) { var sealId = PipGraph.GetSealedDirectoryNode(directoryArtifact).ToPipId(); var sealKind = PipTable.GetSealDirectoryKind(sealId); if (sealKind == SealDirectoryKind.Full || sealKind == SealDirectoryKind.Partial) { return(PipGraph.ListSealedDirectoryContents(directoryArtifact)); } else if (sealKind.IsOpaqueOutput()) { return(m_dynamicContents[directoryArtifact]); } return(ReadOnlyArray <FileArtifact> .Empty); }
private ObjectInfo DirectoryArtifactInfo(DirectoryArtifact d) { if (!d.IsValid) { return(new ObjectInfo("Invalid")); } var name = d.Path.GetName(PathTable).ToString(StringTable); var kind = d.IsSharedOpaque ? "shared opaque" : d.IsOutputDirectory() ? "exclusive opaque" : "source"; return(new ObjectInfo( preview: $"{name} [{kind}]", properties: new[] { new Property("Path", d.Path.ToString(PathTable)), new Property("PartialSealId", d.PartialSealId), new Property("Kind", kind), d.IsOutputDirectory() ? new Property("Producer", () => PipGraph.GetProducer(d)) : null, new Property("Consumers", PipGraph.GetConsumingPips(d.Path).ToArray()), d.PartialSealId > 0 ? new Property("Members", () => PipGraph.ListSealedDirectoryContents(d)) : null } .Where(p => p != null))); }
private ObjectInfo DirectoryArtifactInfo(DirectoryArtifact d) { if (!d.IsValid) { return(new ObjectInfo("Invalid")); } var name = d.Path.GetName(PathTable).ToString(StringTable); var kind = d.IsSharedOpaque ? "shared opaque" : d.IsOutputDirectory() ? "exclusive opaque" : "source"; return(new ObjectInfoBuilder() .Preview($"{name} [{kind}]") .Prop("Path", d.Path.ToString(PathTable)) .Prop("PartialSealId", d.PartialSealId) .Prop("Kind", kind) .Prop("Producer", () => d.IsOutputDirectory() ? Analyzer.GetPip(PipGraph.TryGetProducer(d)) : null) .Prop("Consumers", PipGraph.GetConsumingPips(d)) .Prop("Members", () => d.IsOutputDirectory() ? (object)Analyzer.GetDirMembers(d) : d.PartialSealId > 0 ? PipGraph.ListSealedDirectoryContents(d).Select(f => f.Path) : CollectionUtilities.EmptyArray <AbsolutePath>()) .Build()); }
public override int Analyze() { var rootExpander = new RootExpander(PathTable); HashSet <ContentHash> hashes = new HashSet <ContentHash>(); hashes.Add(ContentHashingUtilities.ZeroHash); HashSet <FileArtifact> files = new HashSet <FileArtifact>(); foreach (var root in Roots) { rootExpander.Add(AbsolutePath.Create(PathTable, root.Key), root.Value); } Func <AbsolutePath, string> expandRoot = absPath => absPath.ToString(PathTable, rootExpander); var orderedPips = CachedGraph.PipGraph.RetrievePipReferencesOfType(PipType.Process) .Where(lazyPip => TargetSemiStableHash == null || TargetSemiStableHash == lazyPip.SemiStableHash) .Select(lazyPip => (Process)lazyPip.HydratePip()) .ToLookup(process => process.Provenance.Token.Path) .OrderBy(grouping => grouping.Key.ToString(PathTable, rootExpander)) .ToList(); using (var fingerprintStream = File.Create(DumpFilePath, bufferSize: 64 << 10 /* 64 KB */)) using (var hashWriter = new StreamWriter(DumpFilePath + ".hashes.txt")) { using ( var fingerprintArchive = CompressFile ? new ZipArchive(fingerprintStream, ZipArchiveMode.Create) : null) { using ( var writer = XmlWriter.Create( CompressFile ? fingerprintArchive.CreateEntry("dump.xml", CompressionLevel.Fastest).Open() : fingerprintStream, new XmlWriterSettings() { Indent = true })) { int doneProcesses = 0; var t = new Timer( o => { var done = doneProcesses; Console.WriteLine("Processes Done: {0} of {1}", done, orderedPips.Count); }, null, 5000, 5000); try { writer.WriteStartElement("ProcessDump"); writer.WriteAttributeString("Count", orderedPips.Count.ToString(CultureInfo.InvariantCulture)); foreach (var specPipGroup in orderedPips) { writer.WriteStartElement("SpecFile"); writer.WriteAttributeString("Path", specPipGroup.Key.ToString(PathTable, rootExpander)); foreach (var pip in specPipGroup) { doneProcesses++; writer.WriteStartElement("Process"); writer.WriteAttributeString("Name", pip.Executable.Path.ToString(PathTable, rootExpander)); writer.WriteAttributeString("CMD", RenderProcessArguments(pip)); writer.WriteElementString("Description", pip.GetDescription(PipGraph.Context)); writer.WriteStartElement("EnvironmentVariables"); foreach (var environmentVariable in pip.EnvironmentVariables) { writer.WriteStartElement("Environment"); writer.WriteAttributeString("Name", environmentVariable.Name.ToString(PathTable.StringTable)); if (environmentVariable.Value.IsValid) { writer.WriteAttributeString("Value", environmentVariable.Value.ToString(expandRoot, PathTable.StringTable, PipData.MaxMonikerRenderer)); } else { writer.WriteAttributeString("Value", "Unset"); } writer.WriteEndElement(); } writer.WriteEndElement(); writer.WriteStartElement("Dependencies"); foreach (var input in pip.Dependencies) { writer.WriteStartElement("Item"); writer.WriteAttributeString("Path", input.Path.ToString(PathTable, rootExpander)); writer.WriteAttributeString("Hash", m_fileHashes.GetOrAdd(input, ContentHashingUtilities.ZeroHash).Item.Value.ToString()); writer.WriteAttributeString("RewriteCount", input.RewriteCount.ToString()); writer.WriteEndElement(); } writer.WriteEndElement(); writer.WriteStartElement("DirectoryDependencies"); foreach (var input in pip.DirectoryDependencies) { writer.WriteStartElement("Item"); writer.WriteAttributeString("Path", input.Path.ToString(PathTable, rootExpander)); var kind = PipTable.GetSealDirectoryKind(PipGraph.GetSealedDirectoryNode(input).ToPipId()); writer.WriteAttributeString("Kind", kind.ToString()); // Print directory dependency file details when dumping a specific process if (TargetSemiStableHash != null && (kind == SealDirectoryKind.Full || kind == SealDirectoryKind.Partial)) { foreach (var file in PipGraph.ListSealedDirectoryContents(input)) { writer.WriteStartElement("Item"); writer.WriteAttributeString("Path", file.Path.ToString(PathTable, rootExpander)); writer.WriteAttributeString("Hash", m_fileHashes.GetOrAdd(file, ContentHashingUtilities.ZeroHash).Item.Value.ToString()); writer.WriteAttributeString("RewriteCount", file.RewriteCount.ToString()); writer.WriteEndElement(); } } else if (m_contents.TryGetValue(input, out var contents)) { m_observedInputs.TryGetValue(pip.PipId.Value, out var observedInputs); foreach (var file in contents) { // skip the files that were not accessed if (observedInputs != null && !observedInputs.Contains(file.Path)) { continue; } writer.WriteStartElement("Item"); writer.WriteAttributeString("Path", file.Path.ToString(PathTable, rootExpander)); writer.WriteAttributeString("Hash", m_fileHashes.GetOrAdd(file, ContentHashingUtilities.ZeroHash).Item.Value.ToString()); writer.WriteAttributeString("RewriteCount", file.RewriteCount.ToString()); writer.WriteEndElement(); } } writer.WriteEndElement(); } writer.WriteEndElement(); writer.WriteStartElement("Outputs"); foreach (var input in pip.FileOutputs) { writer.WriteStartElement("Item"); if (input.RewriteCount > 1) { writer.WriteAttributeString("RewriteCount", input.RewriteCount.ToString()); } writer.WriteString(input.Path.ToString(PathTable, rootExpander)); writer.WriteEndElement(); } writer.WriteEndElement(); writer.WriteStartElement("DirectoryOutputs"); foreach (var output in pip.DirectoryOutputs) { writer.WriteStartElement("Directory"); { writer.WriteAttributeString("Path", output.Path.ToString(PathTable, rootExpander)); if (m_contents.TryGetValue(output, out var contents)) { writer.WriteStartElement("Contents"); { foreach (var file in contents) { writer.WriteStartElement("Item"); if (file.RewriteCount > 1) { writer.WriteAttributeString("RewriteCount", file.RewriteCount.ToString()); } writer.WriteString(file.Path.ToString(PathTable, rootExpander)); writer.WriteEndElement(); } } writer.WriteEndElement(); } } writer.WriteEndElement(); } writer.WriteEndElement(); if (pip.TempDirectory.IsValid) { writer.WriteElementString("TempDirectory", pip.TempDirectory.ToString(PathTable, rootExpander)); } writer.WriteStartElement("AdditionalTempDirectories"); foreach (var item in pip.AdditionalTempDirectories) { writer.WriteElementString("Item", item.ToString(PathTable, rootExpander)); } writer.WriteEndElement(); writer.WriteEndElement(); // Process } writer.WriteEndElement(); // SpecFile } writer.WriteEndElement(); // ProcessDump } finally { // kill and wait for the status timer to die... using (var e = new AutoResetEvent(false)) { t.Dispose(e); e.WaitOne(); } } } } } return(0); }