Example #1
0
        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();
        }
Example #2
0
        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)));
        }
Example #3
0
        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;
                    }
                }
            }
        }
Example #4
0
        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);
        }
Example #5
0
        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)));
        }
Example #6
0
        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());
        }
Example #7
0
        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);
        }