bazel-contrib / bazel-contrib/toolchains_llvm

`--fission=yes` alone does not generate real `.dwp` files

Open
#109 2 comments 1 reaction 0 assignees View on GitHub
bug help wanted
Dominant language
Starlark
Stars
371
Forks
283
Avg merge
1d 55m
Merged PRs (30d)
25

Description

My understanding is that [`--fission`](https://docs.bazel.build/versions/main/user-manual.html#flag--fission) is supposed to be a cross-platform way to generate separate debug info files for C/C++ rules (this is definitely stretching it a bit; I think `--fission` is intended to be `.dwo`/`.dwp` specific – that is, it's not supposed to generate [`.dSYM`s on macOS](https://github.com/bazelbuild/bazel/blob/7dd6ced654e0ed96e0047c369288f283481c7265/tools/osx/crosstool/cc_toolchain_config.bzl#L2362-L2388) and `.pdb`s on Windows).

In practice, `--fission=yes` alone does not generate non-empty `.dwp` files; `--features=per_object_debug_info` must also be specified.

This is because `unix_cc_toolchain_config.bzl`'s `cc_toolchain_config` [does not enable the `per_object_debug_info` feature](https://github.com/bazelbuild/bazel/blob/4b47d6f849bb2eca669f48cfdb5d1796100920f3/tools/cpp/unix_cc_toolchain_config.bzl#L376-L395) by default.

Passing in `--features=per_object_debug_info` to enable it manually (i.e. in a `.bazelrc`) is sub-optimal because this breaks compilation on other platforms like macOS where `-gsplit-dwarf` has different behavior and will not produce `.dwo` files (on macOS debug info lives in the `.o` files – as in there is no `.dwo` equivalent – and running with `-gsplit-dwarf` when producing a _binary_ will produce a `.dSYM` file, the `.dwp` equivalent).

It seems better to have the toolchain – which knows the platform it targets and has enough information to choose to enable this feature – handle this rather than to foist this onto users (afaik there isn't a create way to deal with this _outside_ of the toolchain anyways; best I can come up with is `build:linux --features=per_object_debug_info` and then requiring `--config=linux` when building for Linux, etc.).

I think it's actually safe for us to enable the `per_object_debug_info` feature by default on Linux because it's effectively gated on `fission`:
- the `per_object_debug_info` feature (which we cans see introduces the `-gsplit-dwarf` flag) lives [here](https://github.com/bazelbuild/bazel/blob/08936aecb96f2937c61bdedfebcf1c5a41a0786d/tools/cpp/unix_cc_toolchain_config.bzl#L376-L395)
+ in the above we can see that it's gated on `per_object_debug_info_file`
- `per_object_debug_info_file` comes from [here in Bazel](https://github.com/bazelbuild/bazel/blob/08936aecb96f2937c61bdedfebcf1c5a41a0786d/src/main/java/com/google/devtools/build/lib/rules/cpp/CompileBuildVariables.java#L107-L108) and is ultimately set by [this bit](https://github.com/bazelbuild/bazel/blob/08936aecb96f2937c61bdedfebcf1c5a41a0786d/src/main/java/com/google/devtools/build/lib/rules/cpp/CompileBuildVariables.java#L364-L366) in `CompileBuildVariables.setupSpecificVariables` when given a real `dwoFile`
- that function is [called from `CcCompilationHelper.setupCompileBuildVariables`](https://github.com/bazelbuild/bazel/blob/08936aecb96f2937c61bdedfebcf1c5a41a0786d/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCompilationHelper.java#L1708) which just threads through the `dwoFile` it's called with
- ^ is [called several times from functions like `CcCompilationHelper.createSourceAction`](https://github.com/bazelbuild/bazel/blob/08936aecb96f2937c61bdedfebcf1c5a41a0786d/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCompilationHelper.java#L1909-L1919) which provide a [`dwoFile`](https://github.com/bazelbuild/bazel/blob/08936aecb96f2937c61bdedfebcf1c5a41a0786d/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCompilationHelper.java#L2093-L2096) to ^ if they are passed `generateDwo = true`
- ^ is ultimately [called from functions like `CcCompilationHelper.createCcCompileActions`](https://github.com/bazelbuild/bazel/blob/08936aecb96f2937c61bdedfebcf1c5a41a0786d/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCompilationHelper.java#L1469) which ultimately ask the current `ccToolchain` (`CcToolchainProvider.shouldCreatePerObjectDebugInfo`) if generating per object debug info is enabled for the current feature configuration
- [`CcToolchainProvider.shouldCreatePerObjectDebugInfo`](https://github.com/bazelbuild/bazel/blob/506cf1be7eb08b674023937bd6939baa0a512afe/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainProvider.java#L295-L296) returns true only if [`fission` is enabled](https://github.com/bazelbuild/bazel/blob/506cf1be7eb08b674023937bd6939baa0a512afe/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java#L430) *and* if the `per_object_debug_info` feature is enabled

## steps

While we're still using `unix_cc_toolchain_config.bzl` there's not much we can do about this. These are notes for what to do when we eventually vendor in a version of `unix_cc_toolchain_config.bzl` (and potentially macOS and Windows host counterparts as well).

- [ ] enable the `per_object_debug_info` [by default](https://github.com/bazelbuild/bazel/blob/08936aecb96f2937c61bdedfebcf1c5a41a0786d/tools/cpp/unix_cc_toolchain_config.bzl#L174)
+ this should make it so that we don't have to gate the test added in #108 on Linux and so we don't have to specify the `per_object_debug_info` flag explicitly; passing in `--fission=yes` should be sufficient
- [ ] ensure that `--features=per_object_debug_info` sets the debug level high enough to generate `.dwo` files
+ [this comment](https://github.com/grailbio/bazel-toolchain/pull/108#issuecomment-928839768) has some context and bazelbuild/bazel#14038 tracks this issue and bazelbuild/rules_cc#115 has a fix
+ if bazelbuild/rules_cc#115 doesn't get merged we should do something like it when we switch to using our own `unix_cc_toolchain_config.bzl`
+ [ ] we should also remove the `-c dbg` transition workaround that was added in #108 when we do this

It's not clear yet whether this is doable/sensible but it'd be nice to have `--fission` (or some flag like it) cause `rules_cc` to generate split debug info for all the targets that support it. This would mean:
- generating `dSYM` files on macOS (but only on the final link step)
+ there's [stuff in the osx crosstool toolchain config](https://github.com/bazelbuild/bazel/blob/7dd6ced654e0ed96e0047c369288f283481c7265/tools/osx/crosstool/cc_toolchain_config.bzl#L2362-L2388) for this but it seems to depend on [build variables from the objective-C ruleset](https://github.com/bazelbuild/bazel/blob/ebb12e832d115080c5dbfc5d47ebc77e9134c489/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcVariablesExtension.java#L230-L232)?
+ some of the apple rules have support for this (`--features=apple_generate_dsym`) but I don't think that helps
+ bazelbuild/bazel#327 remains open
+ we could build [this kind of workaround](https://github.com/bazelbuild/bazel/issues/2537#issuecomment-281497449) into our link commands? but the question remains how to get `rules_cc` to give us top-level exposed `.dSYM` targets
- no idea what the story is for Windows
+ there's [`generate_pdb_file`](https://github.com/bazelbuild/bazel/blob/6dc941e58dfc1d4a9714a76b921fbe11fce658ed/tools/cpp/windows_cc_toolchain_config.bzl#L667-L669) which seems to work similarly enough to `.dwp` files except that it's [`output_group` based](https://github.com/bazelbuild/bazel/blob/c85dbbe86877b29e78025e5ddfc79b4860cb1398/src/main/java/com/google/devtools/build/lib/rules/cpp/CcBinary.java#L701-L704) instead of a separate target (it'd have been nice to just have a `debug_info` output group for all these files...) and the logic seems to live inside of `bazel` instead of in the toolchain features

All in all, probably not pursuing. We should do the first thing though.

## open questions

- [ ] I'm confused about what the [features associated](https://github.com/bazelbuild/bazel/blob/4b47d6f849bb2eca669f48cfdb5d1796100920f3/tools/cpp/unix_cc_toolchain_config.bzl#L1257) with a `cc_toolchain` actually do.
+ they definitely don't enable those features by default for the associated toolchain
+ they don't seem to indicate what features a toolchain supports (i.e. the `per_object_debug_info` feature is [*not* associated with the toolchains `unix_cc_toolchain_config.bzl` produces for macOS](https://github.com/bazelbuild/bazel/blob/4b47d6f849bb2eca669f48cfdb5d1796100920f3/tools/cpp/unix_cc_toolchain_config.bzl#L1235-L1253) but if I enable the feature manually with `--features=per_object_debug_info` I can see that feature's flags being added to the commands executed)
+ they definitely do not influence toolchain resolution
+ `cc_common.create_cc_toolchain_config_info` [ultimately](https://github.com/bazelbuild/bazel/blob/506cf1be7eb08b674023937bd6939baa0a512afe/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/cpp/CcModuleApi.java#L968) is backed by [`ccToolchainConfigInfoFromStarlark`](https://github.com/bazelbuild/bazel/blob/506cf1be7eb08b674023937bd6939baa0a512afe/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java#L1039) but other than getting stored [here](https://github.com/bazelbuild/bazel/blob/506cf1be7eb08b674023937bd6939baa0a512afe/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainConfigInfo.java#L87) I haven't really been able to tell what the features that are passed in get used for. I'll look into this more later.

Contributor guide

Open the contributing guide

Research direction

Start in tools/cpp/unix_cc_toolchain_config.bzl around the per_object_debug_info feature and its default feature list, then review the test added in #108 and its -c dbg transition workaround. Done means --fission=yes alone produces non-empty .dwp files on Linux, without explicitly enabling per_object_debug_info, while preserving the documented platform limitations.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
build-system
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.