-
Notifications
You must be signed in to change notification settings - Fork 13k
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
DWARF variant metadata for compressed enums with niche is ambiguous #62839
Comments
This is the debuginfo I'm seeing for your example:
If you had to, I think you could do this by checking if the discriminant overlaps any members in any of the variants. So for the example, the discriminant at 0x000003db overlaps with the
I'm not sure that there is a need to handle this differently. The only difference is that one variant does not have a |
Thank you for your response, may I ask what you used to pretty print the debug info? 🙂 If there is a "classic" discriminant, then I read the value of the discriminant, if it's 0, it's the first variant, it it's 1, it's the second variant etc. By knowing the variant, I can pretty print it correctly inside GDB. However, if the niche is used, the value of the discriminant is some arbitrary value (the memory contents of the niche variant) or 0 (that actually means that the enum contains the second variant because the first one cannot contain zero as a valid value, e.g. it's a reference). If I knew that the enum is a niche enum, I could assume that zero in discriminant means it's the second variant and everything else means that it's the first, niche variant (however I think that there may be also more complicated cases, I'm not sure about that). The problem is that I don't currently see a way how to extract the information that the first member doesn't have the |
I used
Right.
You can tell it is a niche enum by looking at the
I don't know anything about how to extract that information in gdb, but if that isn't possible in gdb, then the solution is to fix gdb. As far as I can tell, the DWARF contains all the required information, and the old method of encoding information in the names was a hack that is no longer needed. I'm pretty sure @tromey had this all working in gdb though. |
Thank you, this is what I wanted to confirm. @tromey do you have any suggestions on how to extract this information from |
A few things to say on this topic. First, if this is just about the display of Rust enums on the gdb command line, then you should not need a pretty-printer at all, any more. gdb understands how to handle enums directly. Using the example given above, I get:
Second, note that the state before #54004 was not ideal -- there were variants that weren't represented by the encoding scheme. I would be opposed to an attempt to go back to that approach. That said, I think there are two things that are reasonable to want that gdb doesn't implement:
|
Thank you for the details! With GDB 8.1, it only prints However, in IntelliJ we need support for this in the Python API layer. The IDE doesn't just print the variable, it shows it in a hierarchical tree, to display the elements of a If you think that adding this functionality to the Python API is feasible, I'd like to try to add it. Where would this have to go, would GDB have to be modified? Before it was possible to read the enum variant even though GDB didn't support it directly, because Rust generated debug info in a way that allowed this. The new enum debug generation is much cleaner, but it would be nice to get this little feature back :) |
Yeah, gdb would have to be modified. It turns out there is a gdb bug for this. My current thought (and I'll update that bug as well) is to mark the The idea then would be that a Rust |
Accessing the discriminant was just a means to an end to select the correct variant of the enum. The real functionality that we need (and that I guess any other Rust debugger or pretty printer would like to have) is exactly what you describe, given a |
FWIW the gdb patch landed a while back. It is in the latest release. |
Thanks for the info, it works with newer GDB (>= 10.1) and this issue can be thus closed. |
After the change of DWARF metadata generation for enums (#54004), compressed enums with niches are not distinguishable from tagged or empty enums in GDB pretty printing (not in the actual Rust pretty printers, as they do not support the new format yet).
In the new enum debug metadata format, enums have a variant field that should serve as a discriminant to pretty print the correct variant of the enum. However, when the Rust enum has a niche discriminant, the variant contains some integer value that has to be interpreted in a special way. Before #54004, compressed enums were marked (https://github.com/rust-lang/rust/blob/master/src/etc/debugger_pretty_printers_common.py#L230 ) and could be distinguished from normal enums. But currently, the variant field has the same name for all kinds of enums and therefore it is not possible to distinguish (and correctly pretty print) compressed enums.
Example:
This is a niche enum that gets its debug niche value here (https://github.com/rust-lang/rust/blob/master/src/librustc_codegen_llvm/debuginfo/metadata.rs#L1516).
Printing this in GDB:
outputs:
As opposed to a tagged enum:
which outputs:
I don't see any way how can I distinguish that this is not a normal enum and that the discriminant has to be handled in a special way. And even if there was such a way, how am I supposed to interpret the discriminant? In the old version the name of the discriminant encoded some metadata that helped to interpret the value (https://github.com/rust-lang/rust/blob/master/src/etc/debugger_pretty_printers_common.py#L289), but there's nothing like that in the new version. Am I missing something?
I noticed this while modifying enum pretty printers in the IntelliJ Rust plugin (intellij-rust/intellij-rust#4155).
Related issues:
#54004
#55701
#59509
The text was updated successfully, but these errors were encountered: