private void DumpPip(Pip pip, AnalysisInput analysisInput, string dumpPath)
 {
     var dumpPipAnalyzer = new DumpPipAnalyzer(analysisInput, dumpPath, pip.SemiStableHash, directory: default, true, false);
Beispiel #2
0
        private string GetRunningPipsMessage(string standardStatus, string perfInfo)
        {
            lock (m_runningPipsLock)
            {
                if (m_buildViewModel == null)
                {
                    return(null);
                }

                var context = m_buildViewModel.Context;
                Contract.Assert(context != null);

                if (m_runningPips == null)
                {
                    m_runningPips = new Dictionary <PipId, PipInfo>();
                }

                DateTime thisCollection = DateTime.UtcNow;

                // Use the viewer's interface to fetch the info about which pips are currently running.
                foreach (var pip in m_buildViewModel.RetrieveExecutingProcessPips())
                {
                    PipInfo runningInfo;
                    if (!m_runningPips.TryGetValue(pip.PipId, out runningInfo))
                    {
                        // This is a new pip that wasn't running the last time the currently running pips were queried
                        Pip p = pip.HydratePip();

                        runningInfo = new PipInfo()
                        {
                            PipDescription = p.GetShortDescription(context),
                            FirstSeen      = DateTime.UtcNow,
                        };
                        m_runningPips.Add(pip.PipId, runningInfo);
                    }

                    runningInfo.LastSeen = DateTime.UtcNow;
                }

                // Build up a string based on the snapshot of what pips are being running
                using (var pooledWrapper = Pools.StringBuilderPool.GetInstance())
                {
                    StringBuilder sb = pooledWrapper.Instance;
                    sb.Append(TimeSpanToString(TimeDisplay.Seconds, DateTime.UtcNow - BaseTime));
                    sb.Append(' ');
                    sb.Append(standardStatus);
                    if (!string.IsNullOrWhiteSpace(perfInfo))
                    {
                        sb.Append(". " + perfInfo);
                    }

                    // Display the log file location if there have been errors logged. This allows the user to open the
                    // log files while the build is running to see errors that have scrolled off the console
                    var errors = Interlocked.Read(ref m_errorsLogged);
                    if (errors > 0 && m_logsDirectory != null)
                    {
                        sb.AppendLine();
                        sb.AppendFormat(Strings.App_Errors_LogsDirectory, errors, m_logsDirectory);
                    }

                    int pipCount = 0;

                    foreach (var item in m_runningPips.ToArray().OrderBy(kvp => kvp.Value.FirstSeen))
                    {
                        if (item.Value.LastSeen < thisCollection)
                        {
                            // If the pip was last seen before this collection it is no longer running and should be removed
                            m_runningPips.Remove(item.Key);
                        }
                        else
                        {
                            pipCount++;
                            if (pipCount <= m_maxStatusPips)
                            {
                                // Otherwise include it in the string
                                string info = string.Format(CultureInfo.InvariantCulture, "   {0} {1}",
                                                            TimeSpanToString(TimeDisplay.Seconds, item.Value.LastSeen - item.Value.FirstSeen),
                                                            item.Value.PipDescription);

                                // Don't have a trailing newline for the last message;
                                if (sb.Length > 0)
                                {
                                    sb.AppendLine();
                                }

                                sb.Append(info);
                            }
                        }
                    }

                    if (pipCount > m_maxStatusPips)
                    {
                        sb.AppendLine();
                        sb.AppendFormat(Strings.ConsoleListener_AdditionalPips, pipCount - m_maxStatusPips);
                    }

                    return(sb.ToString());
                }
            }
        }
Beispiel #3
0
 /// <summary>
 /// Checks if a pip is a service related pip.
 /// </summary>
 /// <param name="pip"></param>
 /// <returns></returns>
 public static bool IsServiceRelatedPip(Pip pip) => ServiceKind(pip) != ServicePipKind.None;
Beispiel #4
0
        private string GetSealDescription(Pip pip)
        {
            SealDirectory seal = (SealDirectory)pip;

            return($"[{seal.Kind}] {GetDescription(pip)}");
        }
Beispiel #5
0
 private bool ArePipsConcurrent(Pip a, Pip b)
 {
     return((a.PipId.Value >= m_concurrentStart && a.PipId.Value <= m_concurrentStop) &&
            (b.PipId.Value >= m_concurrentStart && b.PipId.Value <= m_concurrentStop));
 }
Beispiel #6
0
 private static async Task <PipResult> Execute(BuildXLContext context, FileContentTable fileContentTable, IConfiguration config, Pip pip, (string substSource, string substTarget)?subst)
Beispiel #7
0
 private string Describe(Pip pip)
 {
     return(pip.GetShortDescription(m_analyzer.CachedGraph.Context));
 }
 private bool CreateLogPathAndRun(Pip pip, PipGraph graph)
 {
     DumpPipLiteAnalysisUtilities.CreateLoggingDirectory(m_logPath, LoggingContext);
     return(DumpPipLiteAnalysisUtilities.DumpPip(pip, m_logPath, Context.PathTable, Context.StringTable, Context.SymbolTable, graph, LoggingContext));
 }
 private string GetDumpFilePath(Pip pip)
 {
     return(Path.Combine(m_logPath, $"{pip.FormattedSemiStableHash}.json"));
 }
Beispiel #10
0
 /// <summary>
 /// Adds the output files of the pip to the set
 /// </summary>
 protected static void AddOutputs(Pip pip, HashSet <FileOrDirectoryArtifact> outputs)
 {
     ForEachOutput(outputs, pip, (outputs2, output) => outputs2.Add(output));
 }
Beispiel #11
0
        private void LogAzureDevOpsIssue(EventWrittenEventArgs eventData, string eventType)
        {
            var builder = new StringBuilder();

            builder.Append("##vso[task.logIssue type=");
            builder.Append(eventType);

            var message = eventData.Message;
            var args    = eventData.Payload == null?CollectionUtilities.EmptyArray <object>() : eventData.Payload.ToArray();

            string body;

            // see if this event provides provenance info
            if (message.StartsWith(EventConstants.ProvenancePrefix, StringComparison.Ordinal))
            {
                Contract.Assume(args.Length >= 3, "Provenance prefix contains 3 formatting tokens.");

                // file
                builder.Append(";sourcepath=");
                builder.Append(args[0]);

                //line
                builder.Append(";linenumber=");
                builder.Append(args[1]);

                //column
                builder.Append(";columnnumber=");
                builder.Append(args[2]);

                //code
                builder.Append(";code=DX");
                builder.Append(eventData.EventId.ToString("D4"));
            }

            var newArgs = args;

            // construct a short message for ADO console
            if ((eventData.EventId == (int)LogEventId.PipProcessError) ||
                (eventData.EventId == (int)SharedLogEventId.DistributionWorkerForwardedError && (int)args[1] == (int)LogEventId.PipProcessError))
            {
                var pipProcessError = new PipProcessErrorEventFields(eventData.Payload, eventData.EventId != (int)LogEventId.PipProcessError);
                args[0] = Pip.FormatSemiStableHash(pipProcessError.PipSemiStableHash);
                args[1] = pipProcessError.ShortPipDescription;
                args[2] = pipProcessError.PipSpecPath;
                args[3] = pipProcessError.ExitCode;
                args[4] = pipProcessError.OptionalMessage;
                args[5] = pipProcessError.OutputToLog;
                args[6] = pipProcessError.MessageAboutPathsToLog;
                args[7] = pipProcessError.PathsToLog;
                message = "[{0}, {1}, {2}] - failed with exit code {3}, {4}\r\n{5}\r\n{6}\r\n{7}";
            }
            else if (eventData.EventId == (int)SharedLogEventId.DistributionWorkerForwardedError || eventData.EventId == (int)SharedLogEventId.DistributionWorkerForwardedWarning)
            {
                message = "{0}";
            }

            body = string.Format(CultureInfo.CurrentCulture, message, args);
            builder.Append(";]");

            // substitute newlines in the message
            var encodedBody = body.Replace("\r\n", $"%0D%0A##[{eventType}]")
                              .Replace("\r", $"%0D##[{eventType}]")
                              .Replace("\n", $"%0A##[{eventType}]");

            builder.Append(encodedBody);

            m_console.WriteOutputLine(MessageLevel.Info, builder.ToString());
        }
Beispiel #12
0
        private void WriteStaticPipDetails(Pip pip, PipExecutionContext context)
        {
            Contract.Requires(pip != null);
            Contract.Requires(pip.PipType != PipType.HashSourceFile);

            m_writer.WritePropertyName("pipId");
            m_writer.WriteValue(pip.PipId.Value);

            if (pip.SemiStableHash != 0)
            {
                m_writer.WritePropertyName("stableId");

                // The X16 format agrees with e.g. PipDC41BEE27D4187E2 which is the most user-visible presently.
                // See Pip.GetDescription
                m_writer.WriteValue(pip.SemiStableHash.ToString("X16", CultureInfo.InvariantCulture));
            }

            if (pip.Provenance != null)
            {
                m_writer.WritePropertyName("provenance");
                m_writer.WriteStartObject();
                {
                    m_writer.WritePropertyName("value");
                    m_writer.WriteValue(pip.Provenance.OutputValueSymbol.ToString(context.SymbolTable));

                    m_writer.WritePropertyName("spec");
                    m_writer.WriteValue(pip.Provenance.Token.Path.ToString(context.PathTable));
                }

                m_writer.WriteEndObject();
            }

            m_writer.WritePropertyName("type");
            m_writer.WriteValue(pip.PipType.ToString());

            m_writer.WritePropertyName("description");
            m_writer.WriteValue(pip.GetDescription(context));

            var process = pip as Process;

            if (process != null)
            {
                m_writer.WritePropertyName("exe");
                m_writer.WriteValue(process.GetToolName(context.PathTable).ToString(context.StringTable));

                if (process.Semaphores != null && process.Semaphores.Length > 0)
                {
                    m_writer.WritePropertyName("semaphores");
                    m_writer.WriteStartArray();

                    foreach (ProcessSemaphoreInfo semaphore in process.Semaphores)
                    {
                        m_writer.WriteStartObject();
                        m_writer.WritePropertyName("name");
                        m_writer.WriteValue(semaphore.Name.ToString(context.StringTable));
                        m_writer.WritePropertyName("value");
                        m_writer.WriteValue(semaphore.Value);
                        m_writer.WritePropertyName("limit");
                        m_writer.WriteValue(semaphore.Limit);
                        m_writer.WriteEndObject();
                    }

                    m_writer.WriteEndArray();
                }
            }
        }
Beispiel #13
0
        private void WriteGraphNodeEntry(
            Pip pip,
            IPipScheduleTraversal graph,
            PipExecutionContext context,
            Dictionary <DirectoryArtifact, int> directoryIds,
            Dictionary <PipId, ProcessExecutionMonitoringReportedEventData> directoryInputContent,
            Dictionary <PipId, PipExecutionDirectoryOutputs> directoryOutputContent)
        {
            Contract.Requires(pip != null);

            m_writer.WriteWhitespace(Environment.NewLine);
            m_writer.WriteStartObject();
            {
                WriteStaticPipDetails(pip, context);
                {
                    // We get nice space savings by omitting dependsOn when it is empty (think HashSourceFile and WriteFile pips).
                    bool writtenHeader = false;

                    foreach (var dependency in graph.RetrievePipImmediateDependencies(pip))
                    {
                        if (!writtenHeader)
                        {
                            m_writer.WritePropertyName("dependsOn");
                            m_writer.WriteStartArray();

                            writtenHeader = true;
                        }

                        if (IncludePip(dependency.PipType))
                        {
                            m_writer.WriteValue(dependency.PipId.Value);
                        }
                    }

                    if (writtenHeader)
                    {
                        m_writer.WriteEndArray();
                    }

                    writtenHeader = false;

                    PipArtifacts.ForEachInput(pip, dependency =>
                    {
                        int dependencyId;
                        if (dependency.IsFile)
                        {
                            if (!m_fileIds.TryGetValue(dependency.FileArtifact.Path, out dependencyId))
                            {
                                Contract.Assume(false, "Expected file artifact already written (dependency of pip) " + dependency.Path.ToString(context.PathTable));
                                throw new InvalidOperationException("Unreachable");
                            }
                        }
                        else
                        {
                            if (!directoryIds.TryGetValue(dependency.DirectoryArtifact, out dependencyId))
                            {
                                Contract.Assume(false, "Expected directory artifact already written (input of pip) " + dependency.Path.ToString(context.PathTable));
                                throw new InvalidOperationException("Unreachable");
                            }
                        }

                        if (!writtenHeader)
                        {
                            m_writer.WritePropertyName("consumes");
                            m_writer.WriteStartArray();

                            writtenHeader = true;
                        }

                        m_writer.WriteValue(dependencyId);
                        return(true);
                    }, includeLazyInputs: true);

                    // Write reads from shared opaque directories
                    if (directoryInputContent.TryGetValue(pip.PipId, out var pipInput))
                    {
                        foreach (var input in pipInput.ReportedFileAccesses)
                        {
                            int dependencyId;
                            if (!m_fileIds.TryGetValue(input.ManifestPath, out dependencyId))
                            {
                                // Ignore unrecognized reads (these are usually directories / files that aren't produced, so we don't have their ID)
                                continue;
                            }
                            m_writer.WriteValue(dependencyId);
                        }
                    }

                    if (writtenHeader)
                    {
                        m_writer.WriteEndArray();
                    }
                }

                {
                    m_writer.WritePropertyName("produces");
                    m_writer.WriteStartArray();

                    SortedSet <int> reads = new SortedSet <int>();

                    PipArtifacts.ForEachOutput(pip, dependency =>
                    {
                        int dependencyId;
                        if (dependency.IsFile)
                        {
                            if (!m_fileIds.TryGetValue(dependency.FileArtifact.Path, out dependencyId))
                            {
                                Contract.Assume(false, "Expected file artifact already written (output of pip) " + dependency.Path.ToString(context.PathTable));
                                throw new InvalidOperationException("Unreachable");
                            }
                        }
                        else
                        {
                            if (!directoryIds.TryGetValue(dependency.DirectoryArtifact, out dependencyId))
                            {
                                Contract.Assume(false, "Expected directory artifact already written (output of pip) " + dependency.Path.ToString(context.PathTable));
                                throw new InvalidOperationException("Unreachable");
                            }
                        }

                        reads.Add(dependencyId);
                        return(true);
                    }, includeUncacheable: true);

                    // Write outputs into shared opaque directories
                    if (directoryOutputContent.TryGetValue(pip.PipId, out var pipOutput))
                    {
                        foreach (var output in pipOutput.DirectoryOutputs)
                        {
                            DirectoryArtifact dir = output.directoryArtifact;
                            var content           = output.fileArtifactArray;

                            foreach (var file in content)
                            {
                                int dependencyId;
                                if (!m_fileIds.TryGetValue(file.Path, out dependencyId))
                                {
                                    Contract.Assume(false, "Expected file artifact not found in fileId table " + file.Path.ToString(context.PathTable));
                                    throw new InvalidOperationException("Unreachable");
                                }
                                reads.Add(dependencyId);
                            }
                        }
                    }

                    foreach (int dependencyId in reads)
                    {
                        m_writer.WriteValue(dependencyId);
                    }

                    m_writer.WriteEndArray();
                }
            }

            m_writer.WriteEndObject();
        }
        private void WriteGraphNodeEntry(
            Pip pip,
            IPipScheduleTraversal graph,
            PipExecutionContext context,
            Dictionary <DirectoryArtifact, int> directoryIds)
        {
            Contract.Requires(pip != null);

            m_writer.WriteWhitespace(Environment.NewLine);
            m_writer.WriteStartObject();
            {
                WriteStaticPipDetails(pip, context);
                {
                    // We get nice space savings by omitting dependsOn when it is empty (think HashSourceFile and WriteFile pips).
                    bool writtenHeader = false;

                    foreach (var dependency in graph.RetrievePipImmediateDependencies(pip))
                    {
                        if (!writtenHeader)
                        {
                            m_writer.WritePropertyName("dependsOn");
                            m_writer.WriteStartArray();

                            writtenHeader = true;
                        }

                        if (IncludePip(dependency.PipType))
                        {
                            m_writer.WriteValue(dependency.PipId.Value);
                        }
                    }

                    if (writtenHeader)
                    {
                        m_writer.WriteEndArray();
                    }

                    writtenHeader = false;

                    PipArtifacts.ForEachInput(pip, dependency =>
                    {
                        int dependencyId;
                        if (dependency.IsFile)
                        {
                            if (!m_fileIds.TryGetValue(dependency.FileArtifact, out dependencyId))
                            {
                                Contract.Assume(false, "Expected file artifact already written (dependency of pip) " + dependency.Path.ToString(context.PathTable));
                                throw new InvalidOperationException("Unreachable");
                            }
                        }
                        else
                        {
                            if (!directoryIds.TryGetValue(dependency.DirectoryArtifact, out dependencyId))
                            {
                                Contract.Assume(false, "Expected directory artifact already written (input of pip) " + dependency.Path.ToString(context.PathTable));
                                throw new InvalidOperationException("Unreachable");
                            }
                        }

                        if (!writtenHeader)
                        {
                            m_writer.WritePropertyName("consumes");
                            m_writer.WriteStartArray();

                            writtenHeader = true;
                        }

                        m_writer.WriteValue(dependencyId);
                        return(true);
                    }, includeLazyInputs: true);

                    if (writtenHeader)
                    {
                        m_writer.WriteEndArray();
                    }
                }

                {
                    m_writer.WritePropertyName("produces");
                    m_writer.WriteStartArray();

                    PipArtifacts.ForEachOutput(pip, dependency =>
                    {
                        int dependencyId;
                        if (dependency.IsFile)
                        {
                            if (!m_fileIds.TryGetValue(dependency.FileArtifact, out dependencyId))
                            {
                                Contract.Assume(false, "Expected file artifact already written (output of pip) " + dependency.Path.ToString(context.PathTable));
                                throw new InvalidOperationException("Unreachable");
                            }
                        }
                        else
                        {
                            if (!directoryIds.TryGetValue(dependency.DirectoryArtifact, out dependencyId))
                            {
                                Contract.Assume(false, "Expected directory artifact already written (output of pip) " + dependency.Path.ToString(context.PathTable));
                                throw new InvalidOperationException("Unreachable");
                            }
                        }

                        m_writer.WriteValue(dependencyId);
                        return(true);
                    }, includeUncacheable: true);

                    m_writer.WriteEndArray();
                }
            }

            m_writer.WriteEndObject();
        }
Beispiel #15
0
        public ObjectInfo GetObjectInfo(object context, object obj)
        {
            obj = obj is EvaluationResult evalResult
                ? evalResult.Value
                : obj;

            if (obj == null || IsInvalid(obj))
            {
                return(s_nullObj);
            }

            if (obj.GetType().IsArray)
            {
                return(ArrayObjInfo(((IEnumerable)obj).Cast <object>().ToArray()));
            }

            var customResult = m_customRenderer?.Invoke(this, context, obj);

            if (customResult != null)
            {
                return(customResult);
            }

            return(obj switch
            {
                ScopeLocals scope => new ObjectInfo(LocalsScopeName, null, Lazy.Create(() => GetLocalsForStackEntry(scope.EvalState, scope.FrameIndex))),
                ScopePipGraph scope => PipGraphInfo(scope.Graph).WithPreview(PipGraphScopeName),
                ScopeAllModules scope => ArrayObjInfo(scope.EvaluatedModules.ToArray()).WithPreview(EvaluatedModulesScopeName),
                IModuleAndContext mc => GetObjectInfo(mc.Tree.RootContext, mc.Module),
                ObjectInfo objInf => objInf,
                IPipGraph graph => PipGraphInfo(graph),
                Pip pip => GenericObjectInfo(pip, $"<{pip.PipType}>").Build(),
                PipProvenance prov => ProvenanceInfo(prov),
                EnvironmentVariable envVar => EnvironmentVariableInfo(envVar),
                PipFragment pipFrag => PipFragmentInfo(context, pipFrag),
                Thunk thunk => thunk.Value != null?GetObjectInfo(context, thunk.Value) : new ObjectInfo("<not evaluated>"),
                    FunctionLikeExpression lambda => LambdaInfo(lambda),
                    Closure cls => LambdaInfo(cls.Function),
                    SymbolAtom sym => new ObjectInfo(sym.ToString(StringTable)),
                    StringId id => new ObjectInfo(id.ToString(StringTable)),
                    PipId id => new ObjectInfo($"{id.Value}"),
                    UndefinedLiteral _ => new ObjectInfo("undefined", UndefinedLiteral.Instance),
                    UndefinedValue _ => new ObjectInfo("undefined", UndefinedValue.Instance),
                    AbsolutePath path => new ObjectInfo($"p`{path.ToString(PathTable)}`", path),
                    RelativePath path => new ObjectInfo($"r`{path.ToString(StringTable)}`", path),
                    PathAtom atom => new ObjectInfo($"a`{atom.ToString(StringTable)}`", atom),
                    FileArtifact file => new ObjectInfo($"f`{file.Path.ToString(PathTable)}`", file),
                    DirectoryArtifact dir => new ObjectInfo($"d`{dir.Path.ToString(PathTable)}`", dir),
                    int num => new ObjectInfo($"{num}"),
                    uint num => new ObjectInfo($"{num}"),
                    short num => new ObjectInfo($"{num}", (int)num),
                    long num => new ObjectInfo($"{num}"),
                    char ch => new ObjectInfo($"'{ch}'", ch.ToString()),
                    string str => new ObjectInfo($"\"{str}\"", str),
                    Enum e => new ObjectInfo($"{e.GetType().Name}.{e}", e),
                    NumberLiteral numLit => new ObjectInfo(numLit.UnboxedValue.ToString(), numLit),
                    Func <object> func => FuncObjInfo(func),
                    ArraySegment <object> arrSeg => ArrayObjInfo(arrSeg),
                    IEnumerable enu => new ObjectInfoBuilder().Preview("IEnumerable").Prop("Result", Lazy.Create <object>(() => enu.Cast <object>().ToArray())).Build(),
                    ArrayLiteral arrLit => ArrayObjInfo(arrLit.Values.Select(v => v.Value).ToArray()).WithOriginal(arrLit),
                    ModuleBinding binding => GetObjectInfo(context, binding.Body),
                    ErrorValue error => ErrorValueInfo(),
                    object o => GenericObjectInfo(o).Build(),
                    _ => s_nullObj
            });
 private void AssertCommon(bool success, Pip pip, PipGraph graph)
 {
     Assert.True(success);
     Assert.True(File.Exists(GetDumpFilePath(pip)));
     Assert.True(VerifyContentWrittenToFile(pip, graph));
 }
Beispiel #17
0
        private static async Task <bool> CreateAndRunPip(
            PipProgram program,
            string tempDirectory,
            string outFile,
            IEnumerable <string> restInstructions,
            bool is64Bit)
        {
            Contract.Requires(restInstructions != null);
            Contract.Requires(tempDirectory != null);
            Contract.Requires(!string.IsNullOrEmpty(outFile));

            BuildXLContext context = BuildXLContext.CreateInstanceForTesting();

            using (var fileAccessListener = new FileAccessListener(Events.Log))
            {
                fileAccessListener.RegisterEventSource(BuildXL.Processes.ETWLogger.Log);

                var loggingContext   = BuildXLTestBase.CreateLoggingContextForTest();
                var fileContentTable = FileContentTable.CreateNew(loggingContext);
                var config           = ConfigurationHelpers.GetDefaultForTesting(context.PathTable, AbsolutePath.Create(context.PathTable, Path.Combine(tempDirectory, "config.dc")));
                config.Sandbox.LogObservedFileAccesses = true;

                Pip pip = null;

                var instructions = restInstructions as string[] ?? restInstructions.ToArray();

                switch (program)
                {
                case PipProgram.Cmd:
                    pip = CreateCmdPip(context, tempDirectory, outFile, is64Bit);
                    break;

                case PipProgram.Self:
                    pip = CreateSelfPip(context, tempDirectory, outFile, instructions, is64Bit);
                    break;
                }

                Contract.Assume(pip != null);

                var isSubstUsed = FileUtilities.TryGetSubstSourceAndTarget(tempDirectory, out var substSource, out var substTarget, out var errorMessage);
                XAssert.IsFalse(!isSubstUsed && errorMessage != null, errorMessage);

                PipResult executeResult = await Execute(
                    context,
                    fileContentTable,
                    config,
                    pip,
                    isSubstUsed
                    ?(substSource, substTarget)
                    : default((string, string)?));

                bool valid = false;

                switch (program)
                {
                case PipProgram.Cmd:
                    valid = ValidateCmd(fileAccessListener.FileAccesses, outFile, is64Bit);
                    break;

                case PipProgram.Self:
                    valid = ValidateSelf(
                        fileAccessListener.FileAccesses,
                        instructions.Length > 0 ? instructions[0] : string.Empty,
                        outFile,
                        is64Bit);
                    break;
                }

                return(executeResult.Status == PipResultStatus.Succeeded && valid);
            }
        }
Beispiel #18
0
        /// <summary>
        /// Gets the inputs consumed by a pip and calls an action
        /// </summary>
        public static bool ForEachInput(
            Pip pip,
            Func <FileOrDirectoryArtifact, bool> inputAction,
            bool includeLazyInputs,
            Func <FileOrDirectoryArtifact, bool> overrideLazyInputAction = null)
        {
            // NOTE: Lazy inputs must be processed AFTER regular inputs
            // This behavior is required by FileContentManager.PopulateDepdencies
            bool result = true;

            switch (pip.PipType)
            {
            case PipType.CopyFile:
                CopyFile copyFile = (CopyFile)pip;
                result = inputAction(FileOrDirectoryArtifact.Create(copyFile.Source));
                break;

            case PipType.Process:
                Process process = (Process)pip;
                foreach (var input in process.Dependencies)
                {
                    if (!inputAction(FileOrDirectoryArtifact.Create(input)))
                    {
                        return(false);
                    }
                }

                foreach (var input in process.DirectoryDependencies)
                {
                    if (!inputAction(FileOrDirectoryArtifact.Create(input)))
                    {
                        return(false);
                    }
                }

                break;

            case PipType.SealDirectory:
                SealDirectory sealDirectory = (SealDirectory)pip;
                foreach (var input in sealDirectory.Contents)
                {
                    if (!inputAction(FileOrDirectoryArtifact.Create(input)))
                    {
                        return(false);
                    }
                }

                break;

            case PipType.Ipc:
                IpcPip ipcPip = (IpcPip)pip;
                foreach (var input in ipcPip.FileDependencies)
                {
                    if (!inputAction(FileOrDirectoryArtifact.Create(input)))
                    {
                        return(false);
                    }
                }

                foreach (var input in ipcPip.DirectoryDependencies)
                {
                    if (!inputAction(FileOrDirectoryArtifact.Create(input)))
                    {
                        return(false);
                    }
                }

                if (includeLazyInputs)
                {
                    overrideLazyInputAction = overrideLazyInputAction ?? inputAction;
                    foreach (var input in ipcPip.LazilyMaterializedDependencies)
                    {
                        if (!overrideLazyInputAction(input))
                        {
                            return(false);
                        }
                    }
                }

                break;
            }

            return(result);
        }
Beispiel #19
0
 public bool TryGetTempDirectoryAncestor(AbsolutePath path, out Pip pip, out AbsolutePath temPath)
 {
     temPath = AbsolutePath.Invalid;
     pip     = null;
     return(false);
 }
        /// <summary>
        /// Prepares a pip to be serialized.
        /// </summary>
        /// <param name="pip"></param>
        /// <param name="dynamicData"></param>
        /// <param name="pathTable"></param>
        /// <param name="stringTable"></param>
        /// <param name="symbolTable"></param>
        /// <param name="pipGraph"></param>
        /// <returns>Serialized Pip object.</returns>
        public static SerializedPip CreateObjectForSerialization(Pip pip, ProcessExecutionMonitoringReportedEventData?dynamicData, PathTable pathTable, StringTable stringTable, SymbolTable symbolTable, PipGraph pipGraph)
        {
            SerializedPip serializedPip = new SerializedPip
            {
                PipMetaData = CreatePipMetadata(pip, pathTable, stringTable, pipGraph, symbolTable)
            };

            switch (pip.PipType)
            {
            case PipType.CopyFile:
                serializedPip.CopyFileSpecificDetails = CreateCopyFileSpecificDetails((CopyFile)pip, pathTable);
                break;

            case PipType.Process:
                serializedPip.ProcessSpecificDetails = CreateProcessSpecificDetails((Process)pip, pathTable, stringTable, pipGraph);
                break;

            case PipType.Ipc:
                serializedPip.IpcSpecificDetails = CreateIpcSpecificDetails((IpcPip)pip, pathTable, stringTable);
                break;

            case PipType.Value:
                serializedPip.ValueSpecificDetails = CreateValueSpecificDetails((ValuePip)pip, pathTable, symbolTable);
                break;

            case PipType.SpecFile:
                serializedPip.SpecFileSpecificDetails = CreateSpecFileSpecificDetails((SpecFilePip)pip, pathTable);
                break;

            case PipType.Module:
                serializedPip.ModuleSpecificDetails = CreateModuleSpecificDetails((ModulePip)pip, pathTable, stringTable);
                break;

            case PipType.HashSourceFile:
                serializedPip.HashSourceFileSpecificDetails = CreateHashSourceFileSpecificDetails((HashSourceFile)pip, pathTable);
                break;

            case PipType.SealDirectory:
                serializedPip.SealDirectorySpecificDetails = CreateSealDirectorySpecificDetails((SealDirectory)pip, pathTable);
                break;

            case PipType.WriteFile:
                serializedPip.WriteFileSpecificDetails = CreateWriteFileSpecificDetails((WriteFile)pip, pathTable);
                break;

            default:
                Contract.Assert(false, $"Specified pip type '{pip.PipType}' does not match any known pip types.");
                break;
            }

            if (dynamicData.HasValue)
            {
                if (dynamicData.Value.ReportedProcesses != null && dynamicData.Value.ReportedProcesses.Count > 0)
                {
                    serializedPip.ReportedProcesses = new List <ReportedProcessData>();
                    foreach (var reportedProcess in dynamicData.Value.ReportedProcesses)
                    {
                        serializedPip.ReportedProcesses.Add(CreateReportedProcessData(reportedProcess));
                    }
                }

                if (dynamicData.Value.ReportedFileAccesses != null && dynamicData.Value.ReportedFileAccesses.Count > 0)
                {
                    serializedPip.ReportedFileAccesses = new List <ReportedFileAccessData>();
                    foreach (var reportedFileAccess in dynamicData.Value.ReportedFileAccesses)
                    {
                        serializedPip.ReportedFileAccesses.Add(CreateReportedFileAccessData(reportedFileAccess, pathTable));
                    }
                }
            }

            return(serializedPip);
        }
Beispiel #21
0
 protected static bool NotMetaPip(Pip arg) => !arg.PipType.IsMetaPip();
 /// <summary>
 /// Dumps the specified Pip to a json file named {pip.SemiStableHash}.json.
 /// </summary>
 /// <param name="pip"> Pip to be dumped. </param>
 /// <param name="logPath"> Directory where the pip dump will be written. </param>
 /// <param name="pathTable"> Path table. </param>
 /// <param name="stringTable"> String table. </param>
 /// <param name="symbolTable"> Symbol table. </param>
 /// <param name="pipGraph"> Pip graph for resolving qualifier ids. </param>
 /// <param name="loggingContext"> Logging context for logging any potential errors (can be null for post build). </param>
 /// <returns> True if log file was written successfully. </returns>
 /// <remarks> An error will be logged if this function returns false. </remarks>
 public static bool DumpPip(Pip pip, string logPath, PathTable pathTable, StringTable stringTable, SymbolTable symbolTable, PipGraph pipGraph, LoggingContext loggingContext)
 {
     return(DumpPip(pip, dynamicData: null, logPath, pathTable, stringTable, symbolTable, pipGraph, loggingContext));
 }
Beispiel #23
0
 public PipRefWithDetails(PipExecutionContext context, Pip pip)
 {
     SetPipRefDetails(context, pip, this);
 }
 /// <summary>
 /// Creates pip info.
 /// </summary>
 public PipInfo CreatePipInfo(Pip pip)
 {
     return(new PipInfo(pip, PipContext));
 }
Beispiel #25
0
 public bool TryGetTempDirectoryAncestor(AbsolutePath path, out Pip pip, out AbsolutePath temPath)
 {
     throw new NotImplementedException();
 }
 private void AddPip(Pip pip)
 {
     m_pips.Enqueue(pip);
     pip.PipId = new PipId((uint)Interlocked.Increment(ref m_nextPipId));
 }
Beispiel #27
0
 public string GetDescription(Pip pip)
 {
     return(pip.GetDescription(PipGraph.Context));
 }
Beispiel #28
0
 /// <inheritdoc />
 protected bool AddPip(Pip pip)
 {
     m_pips.Enqueue(pip);
     pip.PipId = new PipId((uint)Interlocked.Increment(ref m_nextPipId));
     return(true);
 }
Beispiel #29
0
            public void MarkExecuted(Pip executed)
            {
                bool added = m_executed.TryAdd(executed, Unit.Void);

                XAssert.IsTrue(added, "Executed multiple times");
            }
        /// <summary>
        /// Completes pip's independent static weak fingerprint with the fingerprints of pip's dependencies when appropriate.
        /// </summary>
        private ContentFingerprint CompleteFingerprint(PipWithFingerprint pipWithFingerprint, out string completeFingerprintText)
        {
            ContentFingerprint completeFingerprint = pipWithFingerprint.Fingerprint;

            completeFingerprintText = pipWithFingerprint.FingerprintText ?? string.Empty;
            Pip pip = pipWithFingerprint.Pip;

            if (pip is Process process)
            {
                if (m_sealDirectoryFingerprintLookup != null)
                {
                    using (var hasher = CreateHashingHelper(true))
                    {
                        hasher.Add("IndependentFingerprint", completeFingerprint.Hash);
                        hasher.AddOrderIndependentCollection(
                            "DirectoryDependencyFingerprints",
                            process.DirectoryDependencies,
                            (fp, d) => fp.Add(d.Path, m_sealDirectoryFingerprintLookup(d).Hash),
                            DirectoryComparer);
                        completeFingerprint     = new ContentFingerprint(hasher.GenerateHash());
                        completeFingerprintText = FingerprintTextEnabled
                            ? completeFingerprintText + Environment.NewLine + hasher.FingerprintInputText
                            : completeFingerprintText;
                    }
                }
            }
            else if (pip is SealDirectory sealDirectory &&
                     sealDirectory.Kind == SealDirectoryKind.SharedOpaque)
            {
                if (!sealDirectory.IsComposite)
                {
                    // For non-composite shared opaque directories, contents and composed directories are always empty, and therefore the static fingerprint
                    // is not strong enough, i.e. multiple shared opaques can share the same directory root. So in this case we need to add the fingerprint of the producer
                    if (m_directoryProducerFingerprintLookup != null)
                    {
                        DirectoryArtifact directory = sealDirectory.Directory;
                        using (var hasher = CreateHashingHelper(true))
                        {
                            hasher.Add("IndependentFingerprint", completeFingerprint.Hash);
                            hasher.Add(directory, m_directoryProducerFingerprintLookup(directory).Hash);
                            completeFingerprint     = new ContentFingerprint(hasher.GenerateHash());
                            completeFingerprintText = FingerprintTextEnabled
                                ? completeFingerprintText + Environment.NewLine + hasher.FingerprintInputText
                                : completeFingerprintText;
                        }
                    }
                }
                else if (sealDirectory.ComposedDirectories != null)
                {
                    using (var hasher = CreateHashingHelper(true))
                    {
                        hasher.Add("IndependentFingerprint", completeFingerprint.Hash);
                        hasher.AddCollection <DirectoryArtifact, IReadOnlyList <DirectoryArtifact> >(
                            "ComposedDirectoryFingerprints",
                            sealDirectory.ComposedDirectories,
                            (fp, d) => fp.Add(d.Path, m_sealDirectoryFingerprintLookup(d).Hash));
                        hasher.Add("ContentFilter",
                                   sealDirectory.ContentFilter.HasValue ? $"{sealDirectory.ContentFilter.Value.Kind} {sealDirectory.ContentFilter.Value.Regex}" : "");
                        hasher.Add("ActionKind", sealDirectory.CompositionActionKind.ToString());
                        completeFingerprint     = new ContentFingerprint(hasher.GenerateHash());
                        completeFingerprintText = FingerprintTextEnabled
                            ? completeFingerprintText + Environment.NewLine + hasher.FingerprintInputText
                            : completeFingerprintText;
                    }
                }
            }

            return(completeFingerprint);
        }