Exemple #1
0
        private KeyValuePair <DirectoryArtifact, Node> TryFindSealDirectoryEntryContainingFileArtifact(PipTable pipTable, FileArtifact artifact)
        {
            KeyValuePair <DirectoryArtifact, Node> smallestMatchingSeal = default(KeyValuePair <DirectoryArtifact, Node>);
            int smallestMatchingSealSize = int.MaxValue;
            int next = GetHeadNodeIndex(artifact);

            while (next >= 0)
            {
                var directoryAndSeal = m_seals.BackingSet[next];
                var sealDirectory    =
                    (SealDirectory)
                    pipTable.HydratePip(
                        directoryAndSeal.Value.PipId,
                        PipQueryContext.SealedDirectoryTableTryFindDirectoryArtifactContainingFileArtifact);
                if (sealDirectory.Contents.Contains(artifact))
                {
                    if (!smallestMatchingSeal.Key.IsValid || smallestMatchingSealSize > sealDirectory.Contents.Length)
                    {
                        smallestMatchingSealSize = sealDirectory.Contents.Length;
                        smallestMatchingSeal     = directoryAndSeal;
                    }
                }

                next = directoryAndSeal.Value.Next;
            }

            return(smallestMatchingSeal);
        }
        /// <summary>
        /// Hooks into the log target for pip execution performance data which will be called
        /// when a pip fails. This will then dump relevant information on the failing pip
        /// to a JSON file specified under <see cref="m_logPath"/>.
        /// The maximum number of logs generated can be specified using the
        /// /DumpFailedPipsLogCount parameter.
        /// </summary>
        /// <remarks>
        /// If an error occurs while serializing/dumping the specified pip,
        /// then this analyzer will be disabled for the remainder of this build and
        /// a warning will be logged with more details.
        /// </remarks>
        public override void PipExecutionPerformance(PipExecutionPerformanceEventData data)
        {
            if (data.ExecutionPerformance.ExecutionLevel == PipExecutionLevel.Failed && !m_loggingErrorOccured)
            {
                var currentNumLogFiles = Interlocked.Increment(ref m_numLogFilesGenerated);

                if (currentNumLogFiles <= m_maxLogFiles)
                {
                    var pip = m_pipTable.HydratePip(data.PipId, PipQueryContext.DumpPipLiteAnalyzer);
                    ProcessExecutionMonitoringReportedEventData?dynamicData = null;

                    if (m_shouldDumpDynamicData)
                    {
                        m_dynamicDataDictionary.TryRemove(data.PipId, out dynamicData);
                    }

                    DumpPip(pip, dynamicData, currentNumLogFiles);
                }
            }
            else
            {
                // If m_loggingErrorOccured is set to true, then no data is being added to the dictionary anyway, so there is no need to remove
                if (!m_loggingErrorOccured && m_shouldDumpDynamicData)
                {
                    // The pip is not in a failed state, so it does not need to be dumped.
                    m_dynamicDataDictionary.TryRemove(data.PipId, out _);
                }
            }
        }
        public DumpPipLiteAnalyzer(AnalysisInput input, string outputDirectory, long semiStableHash, bool dumpObservedFileAccesses)
            : base(input)
        {
            if (string.IsNullOrEmpty(outputDirectory))
            {
                // Use the execution log path
                m_logPath = Path.Combine(Path.GetDirectoryName(input.ExecutionLogPath), "FailedPips");
            }
            else
            {
                m_logPath = Path.Combine(outputDirectory, "FailedPips");
            }

            m_pipTable = input.CachedGraph.PipTable;
            m_pipGraph = input.CachedGraph.PipGraph;
            m_dumpObservedFileAccesses = dumpObservedFileAccesses;
            m_dynamicData = null;

            foreach (var pipId in m_pipTable.StableKeys)
            {
                var possibleMatch = m_pipTable.GetPipSemiStableHash(pipId);
                if (possibleMatch == semiStableHash)
                {
                    m_pip = m_pipTable.HydratePip(pipId, PipQueryContext.DumpPipLiteAnalyzer);
                    break;
                }
            }

            if (m_pip == null)
            {
                // If no matches were found, then we likely got some bad input from the user.
                throw new InvalidArgumentException($"Specified Pip 'Pip{semiStableHash:X}' does not exist.");
            }
        }
Exemple #4
0
 private IEnumerable <Pip> HydratePipsByType(PipTable pipTable, IEnumerable <PipType> relevantTypes)
 {
     return(pipTable
            .Keys
            .Where(pipId => relevantTypes.Any(pipType => pipType == pipTable.GetPipType(pipId)))
            .Select(pipId => pipTable.HydratePip(pipId, PipQueryContext.Test))
            .ToList());
 }
Exemple #5
0
 /// <summary>
 /// Gets the process pip by semistable hash
 /// </summary>
 /// <param name="semistableHash"></param>
 /// <returns></returns>
 public Process GetProcessPip(long semistableHash)
 {
     if (m_semiStableHashProcessPips.ContainsKey(semistableHash))
     {
         var pipId = m_semiStableHashProcessPips[semistableHash];
         return((Process)m_pipTable.HydratePip(pipId, PipQueryContext.ViewerAnalyzer));
     }
     return(null);
 }
Exemple #6
0
        public XElement CreateRow(string key, IEnumerable <PipId> values)
        {
            var allPips = values
                          .Select(pipId => m_pipTable.HydratePip(pipId, PipQueryContext.ViewerAnalyzer))
                          .Select(
                pip => new
            {
                PipType  = pip.PipType.ToString(),
                Hash     = Pip.FormatSemiStableHash(pip.Provenance?.SemiStableHash ?? 0),
                FullName = pip.Provenance?.OutputValueSymbol.ToString(m_symbolTable),
                Spec     = pip.Provenance?.Token.Path.ToString(m_pathTable),
                Details  = GetPipDetails(pip),
            })
                          .OrderBy(obj => obj.PipType)
                          .ThenBy(obj => obj.FullName)
                          .Select(obj => string.Format("[{0}] <{1}> {2} - {3} {4}", obj.Hash, obj.PipType, obj.FullName, obj.Spec, obj.Details));

            return(CreateRow(key, allPips));
        }
        /// <summary>
        /// Hooks into the log target for pip execution performance data which will be called
        /// when a pip fails. This will then dump relevant information on the failing pip
        /// to a JSON file specified under <see cref="m_logPath"/>.
        /// The maximum number of logs generated can be specified using the
        /// /DumpFailedPipsLogCount parameter.
        /// </summary>
        /// <remarks>
        /// If an error occurs while serializing/dumping the specified pip,
        /// then this analyzer will be disabled for the remainder of this build and
        /// a warning will be logged with more details.
        /// </remarks>
        public override void PipExecutionPerformance(PipExecutionPerformanceEventData data)
        {
            if (data.ExecutionPerformance.ExecutionLevel == PipExecutionLevel.Failed && !m_loggingErrorOccured)
            {
                var currentNumLogFiles = Interlocked.Increment(ref m_numLogFilesGenerated);

                if (currentNumLogFiles <= m_maxLogFiles)
                {
                    var dumpPipResult = false;

                    if (!m_logPathCreated)
                    {
                        // A log entry should have been generated already if this fails
                        m_logPathCreated = DumpPipLiteAnalysisUtilities.CreateLoggingDirectory(m_logPath.ToString(m_pipExecutionContext.PathTable), m_loggingContext);
                    }

                    if (m_logPathCreated)
                    {
                        var pip = m_pipTable.HydratePip(data.PipId, PipQueryContext.DumpPipLiteAnalyzer);

                        // A log entry should have been generated already if this fails
                        dumpPipResult = DumpPipLiteAnalysisUtilities.DumpPip(pip,
                                                                             m_logPath.ToString(m_pipExecutionContext.PathTable),
                                                                             m_pipExecutionContext.PathTable,
                                                                             m_pipExecutionContext.StringTable,
                                                                             m_pipExecutionContext.SymbolTable,
                                                                             m_pipGraph);
                    }

                    if (!(m_logPathCreated && dumpPipResult))
                    {
                        // This failure was already logged in DumpPipLiteAnalysisUtilies
                        m_loggingErrorOccured = true;
                    }

                    if (currentNumLogFiles >= m_maxLogFiles)
                    {
                        // Log limit reached, log this once
                        Logger.Log.RuntimeDumpPipLiteLogLimitReached(m_loggingContext, m_maxLogFiles);
                    }
                }
            }
        }
Exemple #8
0
        /// <inheritdoc />
        public override int Analyze()
        {
            PipBasicInfoList.Clear();
            m_moduleIdToFriendlyName.Clear();
            foreach (var pipId in m_pipTable.Keys)
            {
                var pipType = m_pipTable.GetPipType(pipId);
                if (pipType == PipType.Process || pipType == PipType.CopyFile)
                {
                    var pipBasicInfo = new PipBasicInfo();
                    pipBasicInfo.pipId          = pipId.Value.ToString("X16", CultureInfo.InvariantCulture).TrimStart(new[] { '0' });
                    pipBasicInfo.semiStableHash = m_pipTable.GetPipSemiStableHash(pipId).ToString("X");
                    pipBasicInfo.pipType        = pipType.ToString();

                    var pip = m_pipTable.HydratePip(pipId, PipQueryContext.ViewerAnalyzer);
                    pipBasicInfo.shortDescription = pip.GetShortDescription(Input.CachedGraph.PipGraph.Context);

                    PipBasicInfoList.Add(pipBasicInfo);
                }
            }
            return(0);
        }
Exemple #9
0
        /// <summary>
        /// Generates the PipMetadata for a given Pip
        /// </summary>
        public PipMetadata GeneratePipMetadata(Pip pip)
        {
            PipMetadata pipMetadata = new PipMetadata
            {
                PipId          = pip.PipId.Value,
                SemiStableHash = pip.FormattedSemiStableHash,
                PipType        = pip.PipType,
                Tags           = pip.Tags.IsValid ? pip.Tags.Select(tag => tag.ToString(StringTable)).ToList() : null
            };

            pipMetadata.Tags = pipMetadata.Tags.Any() ? pipMetadata.Tags : null;

            PipProvenance provenance = pip.Provenance;

            pipMetadata.Qualifier         = PipGraph.Context.QualifierTable.GetCanonicalDisplayString(provenance.QualifierId);
            pipMetadata.Usage             = provenance.Usage.IsValid ? provenance.Usage.ToString(PathTable) : null;
            pipMetadata.SpecFilePath      = provenance.Token.Path.ToString(PathTable);
            pipMetadata.OutputValueSymbol = provenance.OutputValueSymbol.ToString(SymbolTable);
            pipMetadata.ModuleId          = provenance.ModuleId.Value;
            pipMetadata.SpecFilePath      = provenance.Token.Path.ToString(PathTable);

            pipMetadata.PipDependencies = PipGraph.RetrievePipReferenceImmediateDependencies(pip.PipId, null)
                                          .Where(pipRef => pipRef.PipType != PipType.HashSourceFile)
                                          .Select(pipRef => pipRef.PipId)
                                          .Select(pipId => PipTable.HydratePip(pipId, PipQueryContext.ViewerAnalyzer))
                                          .Select(pipHash => pipHash.FormattedSemiStableHash)
                                          .ToList();

            pipMetadata.PipDependents = PipGraph.RetrievePipReferenceImmediateDependents(pip.PipId, null)
                                        .Select(pipRef => pipRef.PipId)
                                        .Select(pipId => PipTable.HydratePip(pipId, PipQueryContext.ViewerAnalyzer))
                                        .Select(pipData => pipData.FormattedSemiStableHash)
                                        .ToList();
            pipMetadata.PipDependencies = pipMetadata.PipDependencies.Any() ? pipMetadata.PipDependencies : null;
            pipMetadata.PipDependents   = pipMetadata.PipDependents.Any() ? pipMetadata.PipDependents : null;

            return(pipMetadata);
        }
Exemple #10
0
        /// <summary>
        /// Dumps all failing pips is the /dumpAllFailedPips flag is set.
        /// </summary>
        /// <param name="data"></param>
        public override void PipExecutionPerformance(PipExecutionPerformanceEventData data)
        {
            if (m_dumpAllFailedPips && data.ExecutionPerformance.ExecutionLevel == PipExecutionLevel.Failed)
            {
                if (!m_isLogDirectoryCreated)
                {
                    m_isLogDirectoryCreated = DumpPipLiteAnalysisUtilities.CreateLoggingDirectory(m_logPath, LoggingContext);
                }

                if (m_isLogDirectoryCreated)
                {
                    var pip = m_pipTable.HydratePip(data.PipId, PipQueryContext.DumpPipLiteAnalyzer);

                    // A log entry should have been generated already if this fails
                    DumpPipLiteAnalysisUtilities.DumpPip(pip,
                                                         m_logPath,
                                                         PathTable,
                                                         StringTable,
                                                         SymbolTable,
                                                         m_pipGraph);
                }
            }
        }
Exemple #11
0
 private IEnumerable <Pip> HydrateAllPips(PipTable pipTable)
 {
     return(pipTable.Keys.Select(pipId => pipTable.HydratePip(pipId, PipQueryContext.Test)).ToList());
 }
 private Process HydratePip(PipId pipId)
 {
     return((Process)PipTable.HydratePip(pipId, PipQueryContext.ViewerAnalyzer));
 }