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 defining a Starlark transition involving platforms #8936

Closed
lberki opened this issue Jul 19, 2019 · 5 comments
Closed

Crash when defining a Starlark transition involving platforms #8936

lberki opened this issue Jul 19, 2019 · 5 comments
Assignees
Labels
P1 I'll work on this now. (Assignee required) team-Configurability platforms, toolchains, cquery, select(), config transitions

Comments

@lberki
Copy link
Contributor

lberki commented Jul 19, 2019

I'm trying to create a Starlark split transition that changes the current platform based on a flag. Code:

touch WORKSPACE
cat >rules.bzl <<EOF
def _my_flag_impl(ctx):
    return [config_common.FeatureFlagInfo(value = ctx.build_setting_value)]

my_flag = rule(
    implementation = _my_flag_impl,
    build_setting = config.string_list(flag = True),
)

def _my_transition_impl(inputs, outputs):
    result = {}

    for platform in inputs["//:my_flag"]:
        result[platform] = {"//command_line_option:platforms": [platform]}

    return result

_my_transition = transition(
    implementation = _my_transition_impl,
    inputs = ["//:my_flag"],
    outputs = [
	"//command_line_option:platforms",
    ],
)

def _my_rule_impl(ctx):
    return []

my_rule = rule(
    implementation = _my_rule_impl,
    attrs = {
	"deps": attr.label_list(
            cfg = _my_transition,
	),
        "_whitelist_function_transition": attr.label(
            default = "@bazel_tools//tools/whitelists/function_transition_whitelist",
	),
    },
)
EOF

cat > BUILD <<EOF
load(":rules.bzl", "my_flag", "my_rule")

my_flag(
    name = "my_flag",
    build_setting_default = [],
)

cc_binary(
    name = "bin",
    srcs = ["bin.cc"],
)

my_rule(
    name = "my_rule",
    deps = [":bin"],
)
EOF

bazel build --//:my_flag=//:foo,//:bar :my_rule

The result is a big ugly crash. The relevant part of the stack trace is:

java.lang.ClassCastException: class java.lang.String cannot be cast to class com.google.devtools.build.lib.cmdline.Label (java.lang.String is in module java.base of loader 'bootstrap'; com.google.devtools.build.lib.cmdline.Label is in unnamed module of loader 'app')
	at com.google.devtools.build.lib.skyframe.PlatformMappingValue.computeMapping(PlatformMappingValue.java:218)
	at com.google.devtools.build.lib.skyframe.PlatformMappingValue.lambda$map$0(PlatformMappingValue.java:191)
	at com.google.common.cache.LocalCache$LocalManualCache$1.load(LocalCache.java:4875)
	at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3527)
	at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2276)
	at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2154)
	at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2044)
	at com.google.common.cache.LocalCache.get(LocalCache.java:3951)
	at com.google.common.cache.LocalCache$LocalManualCache.get(LocalCache.java:4870)
	at com.google.devtools.build.lib.skyframe.PlatformMappingValue.map(PlatformMappingValue.java:191)
	at com.google.devtools.build.lib.skyframe.BuildConfigurationValue.keyWithPlatformMapping(BuildConfigurationValue.java:68)
	at com.google.devtools.build.lib.analysis.config.ConfigurationResolver.resolveConfigurations(ConfigurationResolver.java:302)
	at com.google.devtools.build.lib.skyframe.ConfiguredTargetFunction.computeDependencies(ConfiguredTargetFunction.java:584)
	at com.google.devtools.build.lib.skyframe.ConfiguredTargetFunction.compute(ConfiguredTargetFunction.java:317)
	at com.google.devtools.build.skyframe.AbstractParallelEvaluator$Evaluate.run(AbstractParallelEvaluator.java:451)
@lberki lberki added the team-Configurability platforms, toolchains, cquery, select(), config transitions label Jul 19, 2019
@gregestren gregestren self-assigned this Jul 19, 2019
@gregestren gregestren added P1 I'll work on this now. (Assignee required) and removed untriaged labels Jul 19, 2019
@gregestren
Copy link
Contributor

I think the simplest immediate fix to get your code working is to change

result[platform] = {"//command_line_option:platforms": [platform]}

to

result[platform] = {"//command_line_option:platforms": [Label(platform)]}

That got it working for me.

This also works:

def _my_transition_impl(inputs, outputs):
    result = []
    for platform in inputs["//ltest:my_flag"]:
        result.append({"//command_line_option:platforms": [Label(platform)]})
    return result

The most working version of split transitions today is going to be [{new settings1}, {new settings 2}, etc.]. In theory {"key1": {new settings 1}, etc.} should work. But I don't think the key accessing logic has been written yet.

But obviously Bazel shouldn't crash. I'll prioritize a fix to stop that.

As for the typing, I think the core Starlark folks were hesitant to add too many types to the config module. Half the point of Starlark flags is that they can model more complex types purely in Starlark (in _my_flag_impl). But there's a caveat that I don't think transitions take the results of _my_flag_impl because that creates weird dependencies on the transitions.

@aiuto
Copy link
Contributor

aiuto commented Apr 23, 2020

cc/ @bazelbuild/configurability

@gregestren
Copy link
Contributor

Lots more context at

// TODO(b/153867317): check for crashing options types in this logic.

I recognize that bug isn't fully visible to all - ping me if you'd like to hear more details.

tl;dr; is I might have a way forward on this that doesn't just fix the crash but (maybe?) resolves the subtleties described above.

@aiuto
Copy link
Contributor

aiuto commented Apr 23, 2020 via email

@gregestren
Copy link
Contributor

Still a worthy ping, especially given its priority and length of time sitting around. :)

luca-digrazia pushed a commit to luca-digrazia/DatasetCommitsDiffSearch that referenced this issue Sep 4, 2022
    This is by no means a complete solution. We have a real challenge here in
    that list-typed native options traditionally (before Starlark configuation)
    can only take strings at the command-line. So their converters expect
    inputs to be raw strings.

    Now with SBC the values can be actual lists of Starlark objects. Those
    lists may or may not type-match the option type. Because of the "string inputs
    only" expectations, there's no easy way for the converters to check this.

    Before this change, this could produce crashes (see GitHub bug) because
    Blaze saw this as a list-typed option assigned to a list value, but didn't
    check that the element type doesn't match (expected Label, actual string).

    This change improves the situation, but only partially, and not for
    allowMultiple options. See new code comments for details.

    Fixes bazelbuild/bazel#8936.

    PiperOrigin-RevId: 308284734
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
P1 I'll work on this now. (Assignee required) team-Configurability platforms, toolchains, cquery, select(), config transitions
Projects
None yet
Development

No branches or pull requests

4 participants