diff options
author | Tom Tromey <tom@tromey.com> | 2016-06-26 11:06:44 -0600 |
---|---|---|
committer | Tom Tromey <tom@tromey.com> | 2016-07-22 11:42:08 -0600 |
commit | e98c9e7ce1c9fd2a5ad99ae2de637b4c16d999b3 (patch) | |
tree | b348597921f5b85f0a264b31ac483eed37ed0923 /gdb/dwarf2read.c | |
parent | eed2386e45968fa4fee8d093895f4789044fb077 (diff) | |
download | gdb-e98c9e7ce1c9fd2a5ad99ae2de637b4c16d999b3.zip gdb-e98c9e7ce1c9fd2a5ad99ae2de637b4c16d999b3.tar.gz gdb-e98c9e7ce1c9fd2a5ad99ae2de637b4c16d999b3.tar.bz2 |
PR rust/20162 - fix gdb regressions caused by rust 1.10
PR rust/20162 started life as a reminder to test gdb with versions of
rust after 1.8; but now concerns some gdb regressions seen with rust
1.10 ("beta") and 1.11 ("nightly").
The failures turn out to be a discrepancy between how rustc emits
DWARF and how gdb interprets it. In particular, rustc will emit DWARF
like:
<2><bc>: Abbrev Number: 9 (DW_TAG_structure_type)
<bd> DW_AT_name : (indirect string, offset: 0x46a): HasMethods
<c1> DW_AT_byte_size : 4
...
<3><cc>: Abbrev Number: 11 (DW_TAG_subprogram)
...
<df> DW_AT_name : (indirect string, offset: 0x514f): new
gdb wants to see a separate top-level DW_TAG_subprogram that refers to
this one via DW_AT_specification; but rustc doesn't emit one. By my
reading of DWARF 4 5.5.7, this is ok, and gdb is incorrect here.
Fixing this involved a new case in scan_partial_symbols, and then a
further change in process_structure_scope to account for the fact
that, in Rust, such functions are not methods and should not be
attached to the structure type.
Next, it turns out that rust is emitting bad values for
DW_AT_linkage_name, e.g.:
<db> DW_AT_linkage_name: (indirect string, offset: 0x422): _ZN7methods8{{impl}}3newE
The the "{{impl}}" stuff is apparently some side effect of a change to
the compiler's internal representation. Oops!
This also had a simple fix -- disregard these mangled names.
With these changes, there are no regressions in the gdb Rust tests
with either 1.10 or 1.11. 1.9, the stable release, is still pretty
broken, but I think there's nothing much to do about that.
These changes are a bit hackish, but no worse, I think, than other
kinds of quirk handling already done in the DWARF parser. I have
reported all the rustc bugs upstream. I plan to remove these hacks
from gdb some suitable time after they have been fixed in released
versions of Rust.
2016-07-22 Tom Tromey <tom@tromey.com>
PR rust/20162:
* dwarf2read.c (scan_partial_symbols) <DW_TAG_structure_type>:
Call scan_partial_symbols for children when reading a Rust CU.
(dwarf2_physname): Ignore invalid DW_AT_linkage_name generated by
rustc.
(process_structure_scope) <DW_TAG_subprogram>: Call
read_func_scope for Rust.
Diffstat (limited to 'gdb/dwarf2read.c')
-rw-r--r-- | gdb/dwarf2read.c | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 58b502b..924b417 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -6695,6 +6695,9 @@ scan_partial_symbols (struct partial_die_info *first_die, CORE_ADDR *lowpc, { add_partial_symbol (pdi, cu); } + if (cu->language == language_rust && pdi->has_children) + scan_partial_symbols (pdi->die_child, lowpc, highpc, + set_addrmap, cu); break; case DW_TAG_enumeration_type: if (!pdi->is_declaration) @@ -8733,6 +8736,12 @@ dwarf2_physname (const char *name, struct die_info *die, struct dwarf2_cu *cu) if (mangled == NULL) mangled = dwarf2_string_attr (die, DW_AT_MIPS_linkage_name, cu); + /* rustc emits invalid values for DW_AT_linkage_name. Ignore these. + See https://github.com/rust-lang/rust/issues/32925. */ + if (cu->language == language_rust && mangled != NULL + && strchr (mangled, '{') != NULL) + mangled = NULL; + /* DW_AT_linkage_name is missing in some cases - depend on what GDB has computed. */ if (mangled != NULL) @@ -13315,8 +13324,16 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu) } else if (child_die->tag == DW_TAG_subprogram) { - /* C++ member function. */ - dwarf2_add_member_fn (&fi, child_die, type, cu); + /* Rust doesn't have member functions in the C++ sense. + However, it does emit ordinary functions as children + of a struct DIE. */ + if (cu->language == language_rust) + read_func_scope (child_die, cu); + else + { + /* C++ member function. */ + dwarf2_add_member_fn (&fi, child_die, type, cu); + } } else if (child_die->tag == DW_TAG_inheritance) { |