Fix BZ 25065 - Ensure that physnames are computed for inherited DIEs
authorKevin Buettner <kevinb@redhat.com>
Sat, 12 Oct 2019 21:35:56 +0000 (14:35 -0700)
committerKevin Buettner <kevinb@redhat.com>
Wed, 27 Nov 2019 20:03:19 +0000 (13:03 -0700)
This is a fix for BZ 25065.

GDB segfaults when running either gdb.cp/subtypes.exp or
gdb.cp/local.exp in conjunction with using the -flto compiler/linker
flag.

A much simpler program, which was used to help create the test for
this fix, is:

-- doit.cc --
int main()
{
  class Foo {
  public:
    int doit ()
    {
      return 0;
    }
  };

  Foo foo;

  return foo.doit ();
}
-- end doit.cc --

gcc -o doit -flto -g doit.cc
gdb -q doit
Reading symbols from doit...
(gdb) ptype main::Foo
type = class Foo {
Segmentation fault (core dumped)

The segfault occurs due to a NULL physname in
c_type_print_base_struct_union in c-typeprint.c.  Specifically,
calling is_constructor_name() eventually causes the SIGSEGV is this
code in c-typeprint.c:

      const char *physname = TYPE_FN_FIELD_PHYSNAME (f, j);
      int is_full_physname_constructor =
TYPE_FN_FIELD_CONSTRUCTOR (f, j)
|| is_constructor_name (physname)
|| is_destructor_name (physname)
|| method_name[0] == '~';

However, looking at compute_delayed_physnames(), we see that
the TYPE_FN_FIELD_PHYSNAME field should never be NULL.  This
field will be set to "" for NULL physnames:

      physname = dwarf2_physname (mi.name, mi.die, cu);
      TYPE_FN_FIELD_PHYSNAME (fn_flp->fn_fields, mi.index)
= physname ? physname : "";

For this particular case, it turns out that compute_delayed_physnames
wasn't being called, which left TYPE_FN_FIELD_PHYSNAME set to the NULL
value that it started with when that data structure was allocated.

The place to fix it, I think, is towards the end of
inherit_abstract_dies().

My first attempt at fix caused the origin CU's method_list (which is
simply the list of methods whose physnames still need to be computed)
to be added to the CU which is doing the inheriting.  One drawback
with this approach is that compute_delayed_physnames is (eventually)
called with a CU that's different than the CU in which the methods
were found.  It's not clear whether this will cause problems or not.

A safer approach, which is what I ultimately settled on, is to call
compute_delayed_physnames() from inherit_abstract_dies().  One
potential drawback is that all needed types might not be known at that
point.  However, in my testing, I haven't seen a problem along these
lines.

gdb/ChangeLog:

* dwarf2read.c (inherit_abstract_dies): Ensure that delayed
physnames are computed for inherited DIEs.

Change-Id: I6c6ffe96b301a9daab9f653956b89e3a33fa9445

gdb/ChangeLog
gdb/dwarf2read.c

index f1ed42a17bcbc7f1f649e32eb140c228bcc1a5c4..0816e73381b249de88b30c7407ea632d9b45455b 100644 (file)
@@ -1,3 +1,8 @@
+2019-11-27  Kevin Buettner  <kevinb@redhat.com>
+
+       * dwarf2read.c (inherit_abstract_dies): Ensure that delayed
+       physnames are computed for inherited DIEs.
+
 2019-11-27  Tom Tromey  <tromey@adacore.com>
 
        * dwarf2read.h (struct dwarf2_per_objfile): Remove unnecessary
index 1ca801c3977233dbef728193f0f02ea48fa03452..40626a1562f0ca96106dfa78b727b0cb712e704f 100644 (file)
@@ -13697,6 +13697,9 @@ inherit_abstract_dies (struct die_info *die, struct dwarf2_cu *cu)
       origin_child_die = sibling_die (origin_child_die);
     }
   origin_cu->list_in_scope = origin_previous_list_in_scope;
+
+  if (cu != origin_cu)
+    compute_delayed_physnames (origin_cu);
 }
 
 static void