-
Notifications
You must be signed in to change notification settings - Fork 13.2k
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
debuginfo: Set bitwidth appropriately in enum variant tags #136895
Conversation
r? @wesleywiser rustbot has assigned @wesleywiser. Use |
cc @tromey for expertise on DWARF encoding and whether I've adjusted this correctly |
This comment has been minimized.
This comment has been minimized.
8ceace4
to
59f491b
Compare
This comment has been minimized.
This comment has been minimized.
@rustbot author Looks like I have a few things to fix still, will poke it tomorrow, removing from review queue until then. |
I think the idea is fine. I don't remember enough about rustc to really comment on the implementation. I stumbled over an unexpected gdb/llvm/gcc discrepancy in the handle of |
The discriminants are not always unsigned unfortunately.
will produce via This happens because LLVM uses the discriminator type to determine the signedness when encoding, but then invokes The sign data is available to the debugger through @tromey: Based on your gdb bug, do you think pre-selecting I think we still want to make a change like this Rust side, because if LLVM is conditioning on the bitwidth, we should pass the right bitwidth. |
Previously, we unconditionally set the bitwidth to 128-bits, the largest an discrimnator would possibly be. Then, LLVM would cut down the constant by chopping off leading zeroes before emitting the DWARF. LLVM only supported 64-bit descriminators, so this would also have occasionally resulted in truncated data (or an assert) if more than 64-bits were used. LLVM added support for 128-bit enumerators in llvm/llvm-project#125578 That patchset also trusts the constant to describe how wide the variant tag is. As a result, we went from emitting tags that looked like: DW_AT_discr_value (0xfe) (`form1`) to emitting tags that looked like: DW_AT_discr_value (<0x10> fe ff ff ff 00 00 00 00 00 00 00 00 00 00 00 00 ) This makes the `DW_AT_discr_value` encode at the bitwidth of the tag, which: 1. Is probably closer to our intentions in terms of describing the data. 2. Doesn't invoke the 128-bit support which may not be supported by all debuggers / downstream tools. 3. Will result in smaller debug information.
59f491b
to
d82219a
Compare
Well, gdb doesn't. It probably should, though the spec isn't entirely clear and the thread from ages ago was also pretty unhelpful.
I think it's unclear what should be done. Currently I tend to agree with the LLVM interpretation here, and think that gdb is wrong. At the same time DWARF does recommend this:
For gdb I am hoping to get some comments on the corresponding GCC bug before taking action. And of course a fix won't appear until the next release anyway... |
@rustbot ready |
@bors r+ rollup |
debuginfo: Set bitwidth appropriately in enum variant tags Previously, we unconditionally set the bitwidth to 128-bits, the largest an enum would possibly be. Then, LLVM would cut down the constant by chopping off leading zeroes before emitting the DWARF. LLVM only supported 64-bit enumerators, so this would also have occasionally resulted in truncated data. LLVM added support for 128-bit enumerators in llvm/llvm-project#125578 That patchset trusts the constant to describe how wide the variant tag is, so the high 64-bits of zeros are considered potentially load-bearing. As a result, we went from emitting tags that looked like: DW_AT_discr_value (0xfe) (because `dwarf::BestForm` selected `data1`) to emitting tags that looked like: DW_AT_discr_value (<0x10> fe ff ff ff 00 00 00 00 00 00 00 00 00 00 00 00 ) This makes the `DW_AT_discr_value` encode at the bitwidth of the tag, which: 1. Is probably closer to our intentions in terms of describing the data. 2. Doesn't invoke the 128-bit support which may not be supported by all debuggers / downstream tools. 3. Will result in smaller debug information.
…kingjubilee Rollup of 11 pull requests Successful merges: - rust-lang#136863 (rework rigid alias handling ) - rust-lang#136869 (Fix diagnostic when using = instead of : in let binding) - rust-lang#136895 (debuginfo: Set bitwidth appropriately in enum variant tags) - rust-lang#136928 (eagerly prove WF when resolving fully qualified paths) - rust-lang#136941 (Move `llvm.ccache` to `build.ccache`) - rust-lang#136950 (rustdoc: use better, consistent SVG icons for scraped examples) - rust-lang#136957 (coverage: Eliminate more counters by giving them to unreachable nodes) - rust-lang#136960 (Compiletest should not inherit all host RUSTFLAGS) - rust-lang#136962 (unify LLVM version finding logic) - rust-lang#136970 (ci: move `x86_64-gnu-debug` job to the free runner) - rust-lang#136973 (Fix `x test --stage 1 ui-fulldeps` on macOS (until the next beta bump)) r? `@ghost` `@rustbot` modify labels: rollup
Rollup merge of rust-lang#136895 - maurer:fix-enum-discr, r=nikic debuginfo: Set bitwidth appropriately in enum variant tags Previously, we unconditionally set the bitwidth to 128-bits, the largest an enum would possibly be. Then, LLVM would cut down the constant by chopping off leading zeroes before emitting the DWARF. LLVM only supported 64-bit enumerators, so this would also have occasionally resulted in truncated data. LLVM added support for 128-bit enumerators in llvm/llvm-project#125578 That patchset trusts the constant to describe how wide the variant tag is, so the high 64-bits of zeros are considered potentially load-bearing. As a result, we went from emitting tags that looked like: DW_AT_discr_value (0xfe) (because `dwarf::BestForm` selected `data1`) to emitting tags that looked like: DW_AT_discr_value (<0x10> fe ff ff ff 00 00 00 00 00 00 00 00 00 00 00 00 ) This makes the `DW_AT_discr_value` encode at the bitwidth of the tag, which: 1. Is probably closer to our intentions in terms of describing the data. 2. Doesn't invoke the 128-bit support which may not be supported by all debuggers / downstream tools. 3. Will result in smaller debug information.
Hi. I originated this bug report within Google. I maintain an open source tool that ingests DWARF, STG, and have previously contributed to libabigail. The latter doesn't yet support variants and discriminants but would run into exactly the same problem. Making DWARF consumers do type inspection to interpret constant values is a significant burden. In the STG case, it would require either local reference chasing within the DWARF processor (something we avoid wherever possible, for performance reasons) or a post-processing pass to fix up enumerator / discriminator values whose sign was ambiguous during DIE traversal. This text was referred to in earlier comment:
It was added to the DWARF standard in response to a very similar issue to this one. https://dwarfstd.org/issues/020702.1.html LLVM appears to br emitting enumerator constants unambiguously. I would very much to see discriminator constants emitted the same way (and parsed in STG with the same code). Aside: I wonder if this also affects |
Update to LLVM 20 LLVM 20 GA is scheduled for March 11th. Rust 1.87 will be stable on May 15th. * [x] rust-lang#135764 * [x] rust-lang#136134 * [x] rust-lang/compiler-builtins#752 * [x] llvm/llvm-project#125287 * [x] rust-lang#136537 * [x] rust-lang#136895 * [x] Wait for beta branch (Feb 14). Tested: host-x86_64, host-aarch64, apple, mingw, msvc
Update to LLVM 20 LLVM 20 GA is scheduled for March 11th. Rust 1.87 will be stable on May 15th. * [x] rust-lang#135764 * [x] rust-lang#136134 * [x] rust-lang/compiler-builtins#752 * [x] llvm/llvm-project#125287 * [x] rust-lang#136537 * [x] rust-lang#136895 * [x] Wait for beta branch (Feb 14). Tested: host-x86_64, host-aarch64, apple, mingw, msvc
Update to LLVM 20 LLVM 20 GA is scheduled for March 11th. Rust 1.87 will be stable on May 15th. * [x] rust-lang/rust#135764 * [x] rust-lang/rust#136134 * [x] rust-lang/compiler-builtins#752 * [x] llvm/llvm-project#125287 * [x] rust-lang/rust#136537 * [x] rust-lang/rust#136895 * [x] Wait for beta branch (Feb 14). Tested: host-x86_64, host-aarch64, apple, mingw, msvc
Update to LLVM 20 LLVM 20 GA is scheduled for March 11th. Rust 1.87 will be stable on May 15th. * [x] rust-lang/rust#135764 * [x] rust-lang/rust#136134 * [x] rust-lang/compiler-builtins#752 * [x] llvm/llvm-project#125287 * [x] rust-lang/rust#136537 * [x] rust-lang/rust#136895 * [x] Wait for beta branch (Feb 14). Tested: host-x86_64, host-aarch64, apple, mingw, msvc
Update to LLVM 20 LLVM 20 GA is scheduled for March 11th. Rust 1.87 will be stable on May 15th. * [x] rust-lang/rust#135764 * [x] rust-lang/rust#136134 * [x] rust-lang/compiler-builtins#752 * [x] llvm/llvm-project#125287 * [x] rust-lang/rust#136537 * [x] rust-lang/rust#136895 * [x] Wait for beta branch (Feb 14). Tested: host-x86_64, host-aarch64, apple, mingw, msvc
Previously, we unconditionally set the bitwidth to 128-bits, the largest an enum would possibly be. Then, LLVM would cut down the constant by chopping off leading zeroes before emitting the DWARF. LLVM only supported 64-bit enumerators, so this would also have occasionally resulted in truncated data.
LLVM added support for 128-bit enumerators in llvm/llvm-project#125578
That patchset trusts the constant to describe how wide the variant tag is, so the high 64-bits of zeros are considered potentially load-bearing.
As a result, we went from emitting tags that looked like:
DW_AT_discr_value (0xfe)
(because
dwarf::BestForm
selecteddata1
)to emitting tags that looked like:
DW_AT_discr_value (<0x10> fe ff ff ff 00 00 00 00 00 00 00 00 00 00 00 00 )
This makes the
DW_AT_discr_value
encode at the bitwidth of the tag, which: