Search in sources :

Example 1 with ActionExecutionException

use of com.google.devtools.build.lib.actions.ActionExecutionException in project bazel by bazelbuild.

the class SkyframeBuilder method processResult.

/**
   * Process the Skyframe update, taking into account the keepGoing setting.
   *
   * <p>Returns optional {@link ExitCode} based on following conditions: 1. null, if result had no
   * errors. 2. Optional.absent(), if result had errors but none of the errors specified an exit
   * code. 3. Optional.of(e), if result had errors and one of them specified exit code 'e'. Throws
   * on fail-fast failures.
   */
@Nullable
private static Optional<ExitCode> processResult(ExtendedEventHandler eventHandler, EvaluationResult<?> result, boolean keepGoing, SkyframeExecutor skyframeExecutor) throws BuildFailedException, TestExecException {
    if (result.hasError()) {
        for (Map.Entry<SkyKey, ErrorInfo> entry : result.errorMap().entrySet()) {
            Iterable<CycleInfo> cycles = entry.getValue().getCycleInfo();
            skyframeExecutor.reportCycles(eventHandler, cycles, entry.getKey());
        }
        if (result.getCatastrophe() != null) {
            rethrow(result.getCatastrophe());
        }
        if (keepGoing) {
            // If build fails and keepGoing is true, an exit code is assigned using reported errors
            // in the following order:
            //   1. First infrastructure error with non-null exit code
            //   2. First non-infrastructure error with non-null exit code
            //   3. Null (later default to 1)
            ExitCode exitCode = null;
            for (Map.Entry<SkyKey, ErrorInfo> error : result.errorMap().entrySet()) {
                Throwable cause = error.getValue().getException();
                if (cause instanceof ActionExecutionException) {
                    ActionExecutionException actionExecutionCause = (ActionExecutionException) cause;
                    ExitCode code = actionExecutionCause.getExitCode();
                    // a lower 'reporting' priority.
                    if (ExitCodeComparator.INSTANCE.compare(code, exitCode) > 0) {
                        exitCode = code;
                    }
                }
            }
            return Optional.fromNullable(exitCode);
        }
        ErrorInfo errorInfo = Preconditions.checkNotNull(result.getError(), result);
        Exception exception = errorInfo.getException();
        if (exception == null) {
            Preconditions.checkState(!Iterables.isEmpty(errorInfo.getCycleInfo()), errorInfo);
            // cycles above.
            throw new BuildFailedException(null, /*hasCatastrophe=*/
            false);
        } else {
            rethrow(exception);
        }
    }
    return null;
}
Also used : SkyKey(com.google.devtools.build.skyframe.SkyKey) BuildFailedException(com.google.devtools.build.lib.actions.BuildFailedException) ErrorInfo(com.google.devtools.build.skyframe.ErrorInfo) ExitCode(com.google.devtools.build.lib.util.ExitCode) CycleInfo(com.google.devtools.build.skyframe.CycleInfo) ActionExecutionException(com.google.devtools.build.lib.actions.ActionExecutionException) Map(java.util.Map) BuildFileNotFoundException(com.google.devtools.build.lib.packages.BuildFileNotFoundException) AbruptExitException(com.google.devtools.build.lib.util.AbruptExitException) TestExecException(com.google.devtools.build.lib.actions.TestExecException) MissingInputFileException(com.google.devtools.build.lib.actions.MissingInputFileException) ActionExecutionException(com.google.devtools.build.lib.actions.ActionExecutionException) BuildFailedException(com.google.devtools.build.lib.actions.BuildFailedException) Nullable(javax.annotation.Nullable)

Example 2 with ActionExecutionException

use of com.google.devtools.build.lib.actions.ActionExecutionException in project bazel by bazelbuild.

the class CppLinkAction method executeFake.

// Don't forget to update FAKE_LINK_GUID if you modify this method.
@ThreadCompatible
private void executeFake() throws ActionExecutionException {
    // The uses of getLinkConfiguration in this method may not be consistent with the computed key.
    // I.e., this may be incrementally incorrect.
    final Collection<Artifact> linkstampOutputs = getLinkCommandLine().getLinkstamps().values();
    // Prefix all fake output files in the command line with $TEST_TMPDIR/.
    final String outputPrefix = "$TEST_TMPDIR/";
    List<String> escapedLinkArgv = escapeLinkArgv(linkCommandLine.getRawLinkArgv(), linkstampOutputs, outputPrefix);
    // Write the commands needed to build the real target to the fake target
    // file.
    StringBuilder s = new StringBuilder();
    Joiner.on('\n').appendTo(s, "# This is a fake target file, automatically generated.", "# Do not edit by hand!", "echo $0 is a fake target file and not meant to be executed.", "exit 0", "EOS", "", "makefile_dir=.", "");
    try {
        // Concatenate all the (fake) .o files into the result.
        for (LinkerInput linkerInput : getLinkCommandLine().getLinkerInputs()) {
            Artifact objectFile = linkerInput.getArtifact();
            if ((CppFileTypes.OBJECT_FILE.matches(objectFile.getFilename()) || CppFileTypes.PIC_OBJECT_FILE.matches(objectFile.getFilename())) && linkerInput.isFake()) {
                // (IOException)
                s.append(FileSystemUtils.readContentAsLatin1(objectFile.getPath()));
            }
        }
        s.append(getOutputFile().getBaseName()).append(": ");
        for (Artifact linkstamp : linkstampOutputs) {
            s.append("mkdir -p " + outputPrefix + linkstamp.getExecPath().getParentDirectory() + " && ");
        }
        Joiner.on(' ').appendTo(s, ShellEscaper.escapeAll(linkCommandLine.finalizeAlreadyEscapedWithLinkstampCommands(escapedLinkArgv, outputPrefix)));
        s.append('\n');
        if (getOutputFile().exists()) {
            // (IOException)
            getOutputFile().setWritable(true);
        }
        FileSystemUtils.writeContent(getOutputFile(), ISO_8859_1, s.toString());
        // (IOException)
        getOutputFile().setExecutable(true);
        for (Artifact linkstamp : linkstampOutputs) {
            FileSystemUtils.touchFile(linkstamp.getPath());
        }
    } catch (IOException e) {
        throw new ActionExecutionException("failed to create fake link command for rule '" + getOwner().getLabel() + ": " + e.getMessage(), this, false);
    }
}
Also used : IOException(java.io.IOException) ActionExecutionException(com.google.devtools.build.lib.actions.ActionExecutionException) Artifact(com.google.devtools.build.lib.actions.Artifact) ThreadCompatible(com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadCompatible)

Example 3 with ActionExecutionException

use of com.google.devtools.build.lib.actions.ActionExecutionException in project bazel by bazelbuild.

the class CppCompileAction method processDepset.

public DependencySet processDepset(Path execRoot, Reply reply) throws ActionExecutionException {
    try {
        DotdFile dotdFile = getDotdFile();
        Preconditions.checkNotNull(dotdFile);
        DependencySet depSet = new DependencySet(execRoot);
        // Perhaps we produced the file locally.
        if (dotdFile.artifact() != null || reply == null) {
            return depSet.read(dotdFile.getPath());
        } else {
            // This is an in-memory .d file.
            return depSet.process(reply.getContents());
        }
    } catch (IOException e) {
        // Some kind of IO or parse exception--wrap & rethrow it to stop the build.
        throw new ActionExecutionException("error while parsing .d file", e, this, false);
    }
}
Also used : DependencySet(com.google.devtools.build.lib.util.DependencySet) IOException(java.io.IOException) ActionExecutionException(com.google.devtools.build.lib.actions.ActionExecutionException)

Example 4 with ActionExecutionException

use of com.google.devtools.build.lib.actions.ActionExecutionException in project bazel by bazelbuild.

the class FakeCppCompileAction method execute.

@Override
@ThreadCompatible
public void execute(ActionExecutionContext actionExecutionContext) throws ActionExecutionException, InterruptedException {
    setModuleFileFlags();
    Executor executor = actionExecutionContext.getExecutor();
    // First, do a normal compilation, to generate the ".d" file. The generated object file is built
    // to a temporary location (tempOutputFile) and ignored afterwards.
    LOG.info("Generating " + getDotdFile());
    CppCompileActionContext context = executor.getContext(actionContext);
    CppCompileActionContext.Reply reply = null;
    try {
        // We delegate stdout/stderr to nowhere, i.e. same as redirecting to /dev/null.
        reply = context.execWithReply(this, actionExecutionContext.withFileOutErr(new FileOutErr()));
    } catch (ExecException e) {
        // We ignore failures here (other than capturing the Distributor reply).
        // The compilation may well fail (that's the whole point of negative compilation tests).
        // We execute it here just for the side effect of generating the ".d" file.
        reply = context.getReplyFromException(e, this);
        if (reply == null) {
            // This can only happen if the ExecException does not come from remote execution.
            throw e.toActionExecutionException("Fake C++ Compilation of rule '" + getOwner().getLabel() + "'", executor.getVerboseFailures(), this);
        }
    }
    IncludeScanningContext scanningContext = executor.getContext(IncludeScanningContext.class);
    Path execRoot = executor.getExecRoot();
    NestedSet<Artifact> discoveredInputs;
    if (getDotdFile() == null) {
        discoveredInputs = NestedSetBuilder.<Artifact>stableOrder().build();
    } else {
        HeaderDiscovery.Builder discoveryBuilder = new HeaderDiscovery.Builder().setAction(this).setDotdFile(getDotdFile()).setSourceFile(getSourceFile()).setSpecialInputsHandler(specialInputsHandler).setDependencySet(processDepset(execRoot, reply)).setPermittedSystemIncludePrefixes(getPermittedSystemIncludePrefixes(execRoot)).setAllowedDerivedinputsMap(getAllowedDerivedInputsMap());
        if (cppSemantics.needsIncludeValidation()) {
            discoveryBuilder.shouldValidateInclusions();
        }
        discoveredInputs = discoveryBuilder.build().discoverInputsFromDotdFiles(execRoot, scanningContext.getArtifactResolver());
    }
    // Clear in-memory .d files early.
    reply = null;
    // depends on.
    try {
        validateInclusions(discoveredInputs, actionExecutionContext.getArtifactExpander(), executor.getEventHandler());
    } catch (ActionExecutionException e) {
        // TODO(bazel-team): (2009) make this into an error, once most of the current warnings
        // are fixed.
        executor.getEventHandler().handle(Event.warn(getOwner().getLocation(), e.getMessage() + ";\n  this warning may eventually become an error"));
    }
    updateActionInputs(discoveredInputs);
    // Generate a fake ".o" file containing the command line needed to generate
    // the real object file.
    LOG.info("Generating " + outputFile);
    // A cc_fake_binary rule generates fake .o files and a fake target file,
    // which merely contain instructions on building the real target. We need to
    // be careful to use a new set of output file names in the instructions, as
    // to not overwrite the fake output files when someone tries to follow the
    // instructions. As the real compilation is executed by the test from its
    // runfiles directory (where writing is forbidden), we patch the command
    // line to write to $TEST_TMPDIR instead.
    final String outputPrefix = "$TEST_TMPDIR/";
    String argv = Joiner.on(' ').join(Iterables.transform(getArgv(outputFile.getExecPath()), new Function<String, String>() {

        @Override
        public String apply(String input) {
            String result = ShellEscaper.escapeString(input);
            // -c <tempOutputFile>, but here it has to be outputFile, so we replace it.
            if (input.equals(tempOutputFile.getPathString())) {
                result = outputPrefix + ShellEscaper.escapeString(outputFile.getExecPathString());
            }
            if (input.equals(outputFile.getExecPathString()) || input.equals(getDotdFile().getSafeExecPath().getPathString())) {
                result = outputPrefix + ShellEscaper.escapeString(input);
            }
            return result;
        }
    }));
    // the compilation would fail.
    try {
        // Ensure that the .d file and .o file are siblings, so that the "mkdir" below works for
        // both.
        Preconditions.checkState(outputFile.getExecPath().getParentDirectory().equals(getDotdFile().getSafeExecPath().getParentDirectory()));
        FileSystemUtils.writeContent(outputFile.getPath(), ISO_8859_1, outputFile.getPath().getBaseName() + ": " + "mkdir -p " + outputPrefix + "$(dirname " + outputFile.getExecPath() + ")" + " && " + argv + "\n");
    } catch (IOException e) {
        throw new ActionExecutionException("failed to create fake compile command for rule '" + getOwner().getLabel() + ": " + e.getMessage(), this, false);
    }
}
Also used : Path(com.google.devtools.build.lib.vfs.Path) FileOutErr(com.google.devtools.build.lib.util.io.FileOutErr) ExecException(com.google.devtools.build.lib.actions.ExecException) IOException(java.io.IOException) Artifact(com.google.devtools.build.lib.actions.Artifact) Function(com.google.common.base.Function) Executor(com.google.devtools.build.lib.actions.Executor) ActionExecutionException(com.google.devtools.build.lib.actions.ActionExecutionException) ThreadCompatible(com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadCompatible)

Example 5 with ActionExecutionException

use of com.google.devtools.build.lib.actions.ActionExecutionException in project bazel by bazelbuild.

the class TreeArtifactBuildTest method testDigestInjection.

// This is more a smoke test than anything, because it turns out that:
// 1) there is no easy way to turn fast digests on/off for these test cases, and
// 2) injectDigest() doesn't really complain if you inject bad digests or digests
// for nonexistent files. Instead some weird error shows up down the line.
// In fact, there are no tests for injectDigest anywhere in the codebase.
// So all we're really testing here is that injectDigest() doesn't throw a weird exception.
// TODO(bazel-team): write real tests for injectDigest, here and elsewhere.
@Test
public void testDigestInjection() throws Exception {
    TreeArtifactTestAction action = new TreeArtifactTestAction(outOne) {

        @Override
        public void execute(ActionExecutionContext actionExecutionContext) throws ActionExecutionException {
            try {
                writeFile(outOneFileOne, "one");
                writeFile(outOneFileTwo, "two");
                MetadataHandler md = actionExecutionContext.getMetadataHandler();
                FileStatus stat = outOneFileOne.getPath().stat(Symlinks.NOFOLLOW);
                md.injectDigest(outOneFileOne, new InjectedStat(stat.getLastModifiedTime(), stat.getSize(), stat.getNodeId()), Hashing.md5().hashString("one", Charset.forName("UTF-8")).asBytes());
                stat = outOneFileTwo.getPath().stat(Symlinks.NOFOLLOW);
                md.injectDigest(outOneFileTwo, new InjectedStat(stat.getLastModifiedTime(), stat.getSize(), stat.getNodeId()), Hashing.md5().hashString("two", Charset.forName("UTF-8")).asBytes());
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    };
    registerAction(action);
    buildArtifact(action.getSoleOutput());
}
Also used : FileStatus(com.google.devtools.build.lib.vfs.FileStatus) ActionExecutionContext(com.google.devtools.build.lib.actions.ActionExecutionContext) InjectedStat(com.google.devtools.build.lib.actions.cache.InjectedStat) MetadataHandler(com.google.devtools.build.lib.actions.cache.MetadataHandler) ActionExecutionException(com.google.devtools.build.lib.actions.ActionExecutionException) BuildFailedException(com.google.devtools.build.lib.actions.BuildFailedException) IOException(java.io.IOException) Test(org.junit.Test)

Aggregations

ActionExecutionException (com.google.devtools.build.lib.actions.ActionExecutionException)26 Artifact (com.google.devtools.build.lib.actions.Artifact)15 IOException (java.io.IOException)14 ActionExecutionContext (com.google.devtools.build.lib.actions.ActionExecutionContext)6 AlreadyReportedActionExecutionException (com.google.devtools.build.lib.actions.AlreadyReportedActionExecutionException)6 Path (com.google.devtools.build.lib.vfs.Path)5 Map (java.util.Map)5 Test (org.junit.Test)5 Action (com.google.devtools.build.lib.actions.Action)4 BuildFailedException (com.google.devtools.build.lib.actions.BuildFailedException)4 Executor (com.google.devtools.build.lib.actions.Executor)4 MissingInputFileException (com.google.devtools.build.lib.actions.MissingInputFileException)4 SkyKey (com.google.devtools.build.skyframe.SkyKey)4 TreeFileArtifact (com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact)3 ExecException (com.google.devtools.build.lib.actions.ExecException)3 ThreadCompatible (com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadCompatible)3 ValueOrException2 (com.google.devtools.build.skyframe.ValueOrException2)3 VisibleForTesting (com.google.common.annotations.VisibleForTesting)2 SpecialArtifact (com.google.devtools.build.lib.actions.Artifact.SpecialArtifact)2 ArtifactPrefixConflictException (com.google.devtools.build.lib.actions.ArtifactPrefixConflictException)2