I'm working on a port of rust to another platform and I'm trying to debug a crash in one of the internal functions. I built a copy of gdb 7.12.1 and was trying to figure out the syntax for specifying types when printing values. This seems to work for the most part: (gdb) ptype syntax::ast::Ident type = struct syntax::ast::Ident { name: syntax::symbol::Symbol, ctxt: syntax::ext::hygiene::SyntaxContext, } However, some cases produce unexpected results: (gdb) ptype syntax::ast::Mod type = struct syntax::ast::Mod { RUST$ENUM$DISR: syntax::ast::ItemKind, __0: syntax::ast::Mod, } Does not match what I expect from src/libsyntax/ast.rs: pub struct Mod { /// A span from the first token past `{` to the last token until `}`. /// For `mod foo;`, the inner span ranges from the first token /// to the last token in the external file. pub inner: Span, pub items: Vec<P<Item>>, } Is this expected? What are the caveats when attempting to debug the rust compiler itself? The rust compiler was built with debug info and without optimizations enabled for debugging purposes. Bug 20168 seems related.
Another respondent to where I originally posted this query pointed out that "Your ptype is showing the enum variant ItemKind::Mod and not the type Mod, both are from syntax::ast."
Confirmed even with my relatively old rustc build.
I see two definitions of Mod at the same level in the debuginfo. I didn't investigate further but this is in keeping with comment#1. I think there's a rustc bug open about this already, I will dig it up later. <3><196df>: Abbrev Number: 29 (DW_TAG_structure_type) <196e0> DW_AT_name : (indirect string, offset: 0x1c7f5f): Mod <196e4> DW_AT_byte_size : 48 <4><196e5>: Abbrev Number: 26 (DW_TAG_member) <196e6> DW_AT_name : (indirect string, offset: 0x154): RUST$ENUM$DISR <196ea> DW_AT_type : <0x16dc0> <196ee> DW_AT_data_member_location: 0 <4><196ef>: Abbrev Number: 26 (DW_TAG_member) <196f0> DW_AT_name : (indirect string, offset: 0xe8): __0 <196f4> DW_AT_type : <0x196fa> <196f8> DW_AT_data_member_location: 8 <4><196f9>: Abbrev Number: 0 <3><196fa>: Abbrev Number: 29 (DW_TAG_structure_type) <196fb> DW_AT_name : (indirect string, offset: 0x1c7f5f): Mod <196ff> DW_AT_byte_size : 40 <4><19700>: Abbrev Number: 26 (DW_TAG_member) <19701> DW_AT_name : (indirect string, offset: 0x4c0f): inner <19705> DW_AT_type : <0x1fad05> <19709> DW_AT_data_member_location: 0 <4><1970a>: Abbrev Number: 26 (DW_TAG_member) <1970b> DW_AT_name : (indirect string, offset: 0x33cd): items <1970f> DW_AT_type : <0x1c25bd> <19713> DW_AT_data_member_location: 16
Maybe it is https://github.com/rust-lang/rust/issues/32924 That seems related, though the example there is a bit different.
I can get the same unusual debuginfo from a simple test: pub struct Mod { v: i32 } pub enum ItemKind { Mod(Mod) } fn x() -> ItemKind { return ItemKind::Mod(Mod{v: 23}); } pub fn main() { match x() { ItemKind::Mod(z) => { println!("{}", z.v); } } } This yields: <2><5d>: Abbrev Number: 7 (DW_TAG_structure_type) <5e> DW_AT_name : (indirect string, offset: 0x353): Mod <62> DW_AT_byte_size : 4 <3><63>: Abbrev Number: 8 (DW_TAG_member) <64> DW_AT_name : (indirect string, offset: 0x141): __0 <68> DW_AT_type : <0x6e> <6c> DW_AT_data_member_location: 0 <3><6d>: Abbrev Number: 0 <2><6e>: Abbrev Number: 7 (DW_TAG_structure_type) <6f> DW_AT_name : (indirect string, offset: 0x353): Mod <73> DW_AT_byte_size : 4 <3><74>: Abbrev Number: 8 (DW_TAG_member) <75> DW_AT_name : (indirect string, offset: 0x351): v <79> DW_AT_type : <0x5e9> <7d> DW_AT_data_member_location: 0 <3><7e>: Abbrev Number: 0 However, I couldn't get gdb to print the wrong type here. So, something else must be going on.
I had an outdated gdb. With my simple test case and a new gdb build I get: (gdb) ptype q::Mod type = struct q::Mod ( q::Mod, ) ... which is the wrong Mod. Also the output here is weird. Ideally it would print Mod(q::Mod).
> Also the output here is weird. Ideally it would print Mod(q::Mod). Err... we shouldn't really access this directly. But 'ptype q::ItemKind' prints: type = enum q::ItemKind { Mod, } ... where I think Mod(Mod) would perhaps be more useful.
(In reply to Tom Tromey from comment #7) > But 'ptype q::ItemKind' prints: This happens because the DWARF for ItemKind doesn't have a name for the first member. <2><50>: Abbrev Number: 5 (DW_TAG_union_type) <51> DW_AT_name : (indirect string, offset: 0x357): ItemKind <55> DW_AT_byte_size : 4 <3><56>: Abbrev Number: 6 (DW_TAG_member) <57> DW_AT_type : <0x5d> <5b> DW_AT_data_member_location: 0 <3><5c>: Abbrev Number: 0 The "skip_to" logic in rust_print_type is wrong for this type. Manually setting skip_to=0 makes it print the right thing. Maybe this code is assuming that an enum must have more than one member.
The master branch has been updated by Tom Tromey <tromey@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=f0fd41c1926984fd1a524ff551286cba694539a0 commit f0fd41c1926984fd1a524ff551286cba694539a0 Author: Tom Tromey <tom@tromey.com> Date: Fri Feb 3 22:11:46 2017 -0700 Fix ptype of single-member Rust enums While looking into PR rust/21097, I found that ptype of a single-element enum in Rust did not always format the result properly. In particular, it would leave out the members of a tuple struct. Further testing showed that it also did the wrong thing for ordinary struct members as well. This patch fixes these problems. I'm marking it as being associated with the PR, since that is where the discovery was made; but this doesn't actually fix that PR (which I think ultimately is due to a Rust compiler bug). Built and regtested on x86-64 Fedora 25, using the system Rust compiler. I'm checking this in. 2017-02-03 Tom Tromey <tom@tromey.com> PR rust/21097: * rust-lang.c (rust_print_type) <TYPE_CODE_UNION>: Handle enums with a single member. 2017-02-03 Tom Tromey <tom@tromey.com> PR rust/21097: * gdb.rust/simple.exp: Add new tests.
This works now, presumably because the Rust compiler bug was fixed.