This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[commit] Work around bad GCC DIE trees
- From: Daniel Jacobowitz <drow at false dot org>
- To: gdb-patches at sourceware dot org
- Date: Tue, 30 Jun 2009 11:51:57 -0400
- Subject: [commit] Work around bad GCC DIE trees
Jan recently added inherit_abstract_dies, which finds children of an
abstract origin that are not referenced by the concrete instance and
stitches them into the child tree. This turned up GCC PR 40573 in one
of the new inline testcases; for details see:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40573
This patch works around the strange nesting. I've tested it on
x86_64-linux with GCC 4.2, 4.3, and 4.4, then checked it in.
--
Daniel Jacobowitz
CodeSourcery
2009-06-30 Daniel Jacobowitz <dan@codesourcery.com>
* dwarf2read.c (inherit_abstract_dies): Work around GCC PR 40573.
2009-06-30 Daniel Jacobowitz <dan@codesourcery.com>
* gdb.opt/inline-locals.exp: Remove XFAIL with duplicated arg1.
Index: dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.318
diff -u -p -r1.318 dwarf2read.c
--- dwarf2read.c 29 Jun 2009 15:18:07 -0000 1.318
+++ dwarf2read.c 30 Jun 2009 15:48:12 -0000
@@ -3331,14 +3331,24 @@ inherit_abstract_dies (struct die_info *
child_die = die->child;
while (child_die && child_die->tag)
{
- attr = dwarf2_attr (child_die, DW_AT_abstract_origin, cu);
+ /* For each CHILD_DIE, find the corresponding child of
+ ORIGIN_DIE. If there is more than one layer of
+ DW_AT_abstract_origin, follow them all; there shouldn't be,
+ but GCC versions at least through 4.4 generate this (GCC PR
+ 40573). */
+ struct die_info *child_origin_die = child_die;
+ while (1)
+ {
+ attr = dwarf2_attr (child_origin_die, DW_AT_abstract_origin, cu);
+ if (attr == NULL)
+ break;
+ child_origin_die = follow_die_ref (child_origin_die, attr, &cu);
+ }
+
/* According to DWARF3 3.3.8.2 #3 new entries without their abstract
counterpart may exist. */
- if (attr)
+ if (child_origin_die != child_die)
{
- struct die_info *child_origin_die;
-
- child_origin_die = follow_die_ref (child_die, attr, &cu);
if (child_die->tag != child_origin_die->tag
&& !(child_die->tag == DW_TAG_inlined_subroutine
&& child_origin_die->tag == DW_TAG_subprogram))
@@ -3346,7 +3356,13 @@ inherit_abstract_dies (struct die_info *
_("Child DIE 0x%x and its abstract origin 0x%x have "
"different tags"), child_die->offset,
child_origin_die->offset);
- *offsets_end++ = child_origin_die->offset;
+ if (child_origin_die->parent != origin_die)
+ complaint (&symfile_complaints,
+ _("Child DIE 0x%x and its abstract origin 0x%x have "
+ "different parents"), child_die->offset,
+ child_origin_die->offset);
+ else
+ *offsets_end++ = child_origin_die->offset;
}
child_die = sibling_die (child_die);
}
Index: testsuite/gdb.opt/inline-locals.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.opt/inline-locals.exp,v
retrieving revision 1.1
diff -u -p -r1.1 inline-locals.exp
--- testsuite/gdb.opt/inline-locals.exp 28 Jun 2009 00:20:24 -0000 1.1
+++ testsuite/gdb.opt/inline-locals.exp 30 Jun 2009 15:48:12 -0000
@@ -62,22 +62,9 @@ if { ! $no_frames } {
-re "arg1 = $decimal\r\n$gdb_prompt $" {
pass $msg
}
- -re "arg1 = <value optimized out>\r\narg1 = <value optimized out>\r\n$gdb_prompt $" {
- # GCC 4.4 loses location information for arg1 (like GCC
- # 4.3) and also generates a strange DIE tree that causes
- # us to display the argument twice: inlined func1 has the
- # abstract func1 for DW_AT_abstract_origin but its arg1
- # child has the out of line func1's arg1 for
- # DW_AT_abstract_origin, with a location list unrelated to
- # the inlined instance.
- if { [test_compiler_info "gcc-4-4-*"] || [test_compiler_info "gcc-4-5-*"] } {
- setup_xfail *-*-* gcc/40573
- }
- fail $msg
- }
-re "arg1 = <value optimized out>\r\n$gdb_prompt $" {
- # GCC 4.3 loses location information for arg1. GCC 4.2 is OK.
- if { [test_compiler_info "gcc-4-3-*"] } {
+ # GCC 4.3 and later lose location information for arg1. GCC 4.2 is OK.
+ if { [test_compiler_info "gcc-4-3-*"] || [test_compiler_info "gcc-4-4-*"]} {
setup_xfail *-*-*
}
fail $msg
@@ -114,16 +101,9 @@ if { ! $no_frames } {
-re "arg1 = $decimal\r\n$gdb_prompt $" {
pass $msg
}
- -re "arg1 = <value optimized out>\r\narg1 = <value optimized out>\r\n$gdb_prompt $" {
- # See the similar GCC 4.4 XFAIL above for an explanation.
- if { [test_compiler_info "gcc-4-4-*"] || [test_compiler_info "gcc-4-5-*"] } {
- setup_xfail *-*-* gcc/40573
- }
- fail $msg
- }
-re "arg1 = <value optimized out>\r\n$gdb_prompt $" {
- # GCC 4.3 loses location information for arg1. GCC 4.2 is OK.
- if { [test_compiler_info "gcc-4-3-*"] } {
+ # GCC 4.3 and later lose location information for arg1. GCC 4.2 is OK.
+ if { [test_compiler_info "gcc-4-3-*"] || [test_compiler_info "gcc-4-4-*"]} {
setup_xfail *-*-*
}
fail $msg