bazel-contrib / bazel-contrib/toolchains_llvm
`--fission=yes` alone does not generate real `.dwp` files
- 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
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