Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crash when incoming edge transition depends on a configurable attribute #23278

Open
jacky8hyf opened this issue Aug 12, 2024 · 2 comments
Open
Assignees
Labels
P2 We'll consider working on this in future. (Assignee optional) team-Configurability platforms, toolchains, cquery, select(), config transitions type: bug

Comments

@jacky8hyf
Copy link

jacky8hyf commented Aug 12, 2024

Description of the bug:

Bazel crashes if an incoming edge transition reads attr that is set to a select() expression.

Which category does this issue belong to?

No response

What's the simplest, easiest way to reproduce this bug? Please provide a minimal example if possible.

# MODULE.bazel
# empty file
# BUILD.bazel
load(":a.bzl", "transitioned_files")

transitioned_files(
    name = "ok",
    target_platform = select({
        "//conditions:default": None, # LINE A
    })
)
# a.bzl
def _platform_transition_impl(_settings, attr):
    print(attr.target_platform)  # THIS CRASHES
    return None

platform_transition = transition(
    implementation = _platform_transition_impl,
    inputs = [],
    outputs = ["//command_line_option:platforms"],
)

def _transitioned_files_impl(_ctx):
    pass

transitioned_files = rule(
    implementation = _transitioned_files_impl,
    attrs = {
        "target_platform": attr.label(),
    },
    cfg = platform_transition,
)

Then run

bazel build //:ok

This crashes with the following trace:

$ bazel build :ok
Starting local Bazel server and connecting to it...
Analyzing: target //:ok (1 packages loaded, 0 targets configured)
    currently loading: @@bazel_tools//tools
[0 / 1] checking cached actions
FATAL: bazel crashed due to an internal error. Printing stack trace:
java.lang.RuntimeException: Unrecoverable error while evaluating node 'ConfiguredTargetKey{label=//:ok, config=BuildConfigurationKey[b357dd09923b37f48f631ab81341a90e6b4443fce0a2dddfde9d204ca537a54e]}' (requested by nodes 'BuildDriverKey of ActionLookupKey: ConfiguredTargetKey{label=//:ok, config=BuildConfigurationKey[b357dd09923b37f48f631ab81341a90e6b4443fce0a2dddfde9d204ca537a54e]}')
	at com.google.devtools.build.skyframe.AbstractParallelEvaluator$Evaluate.run(AbstractParallelEvaluator.java:550)
	at com.google.devtools.build.lib.concurrent.AbstractQueueVisitor$WrappedRunnable.run(AbstractQueueVisitor.java:414)
	at java.base/java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(Unknown Source)
	at java.base/java.util.concurrent.ForkJoinTask.doExec(Unknown Source)
	at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(Unknown Source)
	at java.base/java.util.concurrent.ForkJoinPool.scan(Unknown Source)
	at java.base/java.util.concurrent.ForkJoinPool.runWorker(Unknown Source)
	at java.base/java.util.concurrent.ForkJoinWorkerThread.run(Unknown Source)
Caused by: net.starlark.java.eval.Starlark$UncheckedEvalException: NullPointerException thrown during Starlark evaluation (ANALYSIS)
	at <starlark>.print(<builtin>:0)
	at <starlark>._platform_transition_impl(/mnt/sdc/android/tmpdir2/a.bzl:4)
Caused by: java.lang.NullPointerException: null value in entry: //conditions:default=null
	at com.google.common.collect.CollectPreconditions.checkEntryNotNull(CollectPreconditions.java:33)
	at com.google.common.collect.SingletonImmutableBiMap.<init>(SingletonImmutableBiMap.java:43)
	at com.google.common.collect.ImmutableBiMap.of(ImmutableBiMap.java:83)
	at com.google.common.collect.ImmutableMap.of(ImmutableMap.java:130)
	at com.google.common.collect.ImmutableMap.copyOf(ImmutableMap.java:709)
	at com.google.common.collect.ImmutableMap.copyOf(ImmutableMap.java:688)
	at com.google.devtools.build.lib.packages.SelectorValue.<init>(SelectorValue.java:56)
	at com.google.devtools.build.lib.packages.BuildType$SelectorList.repr(BuildType.java:637)
	at net.starlark.java.eval.StarlarkValue.str(StarlarkValue.java:45)
	at net.starlark.java.eval.StarlarkValue.debugPrint(StarlarkValue.java:61)
	at net.starlark.java.eval.Printer.debugPrint(Printer.java:119)
	at net.starlark.java.eval.MethodLibrary.print(MethodLibrary.java:885)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(Unknown Source)
	at java.base/java.lang.reflect.Method.invoke(Unknown Source)
	at net.starlark.java.eval.MethodDescriptor.call(MethodDescriptor.java:178)
	at net.starlark.java.eval.BuiltinFunction.fastcall(BuiltinFunction.java:78)
	at net.starlark.java.eval.Starlark.fastcall(Starlark.java:806)
	at net.starlark.java.eval.Eval.evalCall(Eval.java:682)
	at net.starlark.java.eval.Eval.eval(Eval.java:497)
	at net.starlark.java.eval.Eval.exec(Eval.java:271)
	at net.starlark.java.eval.Eval.execStatements(Eval.java:82)
	at net.starlark.java.eval.Eval.execFunctionBody(Eval.java:66)
	at net.starlark.java.eval.StarlarkFunction.fastcall(StarlarkFunction.java:179)
	at net.starlark.java.eval.Starlark.fastcall(Starlark.java:806)
	at com.google.devtools.build.lib.analysis.config.StarlarkDefinedConfigTransition$RegularTransition.evaluate(StarlarkDefinedConfigTransition.java:563)
	at com.google.devtools.build.lib.analysis.starlark.FunctionTransitionUtil.applyAndValidate(FunctionTransitionUtil.java:99)
	at com.google.devtools.build.lib.analysis.starlark.StarlarkRuleTransitionProvider$FunctionPatchTransition.patch(StarlarkRuleTransitionProvider.java:201)
	at com.google.devtools.build.lib.analysis.config.transitions.PatchTransition.apply(PatchTransition.java:75)
	at com.google.devtools.build.lib.analysis.config.transitions.ComposingTransition.apply(ComposingTransition.java:69)
	at com.google.devtools.build.lib.analysis.config.StarlarkTransitionCache.computeIfAbsent(StarlarkTransitionCache.java:79)
	at com.google.devtools.build.lib.analysis.producers.TransitionApplier.applyStarlarkTransition(TransitionApplier.java:126)
	at com.google.devtools.build.lib.analysis.producers.TransitionApplier.step(TransitionApplier.java:96)
	at com.google.devtools.build.skyframe.state.TaskTreeNode.run(TaskTreeNode.java:94)
	at com.google.devtools.build.skyframe.state.Driver.drive(Driver.java:87)
	at com.google.devtools.build.lib.skyframe.ConfiguredTargetFunction.computeTargetAndConfiguration(ConfiguredTargetFunction.java:479)
	at com.google.devtools.build.lib.skyframe.ConfiguredTargetFunction.compute(ConfiguredTargetFunction.java:249)
	at com.google.devtools.build.skyframe.AbstractParallelEvaluator$Evaluate.run(AbstractParallelEvaluator.java:461)
	at com.google.devtools.build.lib.concurrent.AbstractQueueVisitor$WrappedRunnable.run(AbstractQueueVisitor.java:414)
	at java.base/java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(Unknown Source)
	at java.base/java.util.concurrent.ForkJoinTask.doExec(Unknown Source)
	at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(Unknown Source)
	at java.base/java.util.concurrent.ForkJoinPool.scan(Unknown Source)
	at java.base/java.util.concurrent.ForkJoinPool.runWorker(Unknown Source)
	at java.base/java.util.concurrent.ForkJoinWorkerThread.run(Unknown Source)

I expect it to not crash and print None.

If I change BUILD.bazel, LINE A to the following:

        "//conditions:default": "@platforms//host",

Then it will print a select expression, instead of the evaluated result:

$ bazel build :ok
Starting local Bazel server and connecting to it...
DEBUG: /mnt/sdc/android/tmpdir2/a.bzl:4:10: select({Label("//conditions:default"): Label("@@platforms//host:host")})
DEBUG: /mnt/sdc/android/tmpdir2/a.bzl:4:10: select({Label("//conditions:default"): Label("@@platforms//host:host")})
DEBUG: /mnt/sdc/android/tmpdir2/a.bzl:4:10: select({Label("//conditions:default"): Label("@@platforms//host:host")})
INFO: Analyzed target //:ok (6 packages loaded, 9 targets configured).
INFO: Found 1 target...
Target //:ok up-to-date (nothing to build)
INFO: Elapsed time: 2.173s, Critical Path: 0.02s
INFO: 1 process: 1 internal.
INFO: Build completed successfully, 1 total action

I expect it to print a simple Label("@@platforms//host:host") instead of the un-evaluated expression.

If it were an outgoing-edge transition, then it properly prints None and Label("@@platforms//host:host") respectively. This bug only happens on the incoming edge transition.

transitioned_files = rule(
    implementation = _transitioned_files_impl,
    attrs = {
        "src": attr.label(
            cfg = platform_transition,
        ),
        "target_platform": attr.label(),
    },
)
$ bazel build :ok
DEBUG: /mnt/sdc/android/tmpdir2/a.bzl:4:10: @@platforms//host:host

Which operating system are you running Bazel on?

Linux

What is the output of bazel info release?

release 7.3.0

If bazel info release returns development version or (@non-git), tell us how you built Bazel.

No response

What's the output of git remote get-url origin; git rev-parse HEAD ?

No response

If this is a regression, please try to identify the Bazel commit where the bug was introduced with bazelisk --bisect.

No response

Have you found anything relevant by searching the web?

No response

Any other information, logs, or outputs that you want to share?

This is probably a WAI, but I don't see any documentation describing the behavior in https://bazel.build/extending/config. Perhaps a documentation update would be sufficient?

Also, I wouldn't expect a crash, but a proper error message that this is not a supported use case.

@jacky8hyf
Copy link
Author

I forgot to put in the "category"; it should be "configurability".

@Wyverald Wyverald added the team-Configurability platforms, toolchains, cquery, select(), config transitions label Aug 12, 2024
@fmeum
Copy link
Collaborator

fmeum commented Aug 13, 2024

CC @aranguyen

@aranguyen aranguyen self-assigned this Oct 4, 2024
@aranguyen aranguyen added the P2 We'll consider working on this in future. (Assignee optional) label Oct 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
P2 We'll consider working on this in future. (Assignee optional) team-Configurability platforms, toolchains, cquery, select(), config transitions type: bug
Projects
None yet
Development

No branches or pull requests

8 participants