public inbox for gdb-cvs@sourceware.org
help / color / mirror / Atom feed
* [binutils-gdb] Fix Ada crash with .debug_types
@ 2020-04-29 17:18 Tom Tromey
  0 siblings, 0 replies; only message in thread
From: Tom Tromey @ 2020-04-29 17:18 UTC (permalink / raw)
  To: gdb-cvs

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=ed6aceddf5b2c31cda8f74982e8dd0574b3979b8

commit ed6aceddf5b2c31cda8f74982e8dd0574b3979b8
Author: Tom Tromey <tromey@adacore.com>
Date:   Wed Apr 29 11:16:57 2020 -0600

    Fix Ada crash with .debug_types
    
    PR ada/25875 concerns a gdb crash when gdb.ada/arr_enum_idx_w_gap.exp
    is run using the .debug_types board.
    
    The problem turns out to be caused by weird compiler output.  In this
    test, the compiler emits a top-level type that refers to an
    enumeration type which is nested in a function.  However, this
    function is just a declaration.
    
    This results in gdb calling read_enumeration_type for the enum type,
    but process_enumeration_scope is never called, yielding an enum with
    no fields.  This causes the crash.
    
    This patch fixes the problem by arranging to create the enum fields in
    read_enumeration_type.
    
    Tested on x86-64 Fedora 30.
    
    gdb/ChangeLog
    2020-04-29  Tom Tromey  <tromey@adacore.com>
    
            PR ada/25875:
            * dwarf2/read.c (update_enumeration_type_from_children): Compute
            type fields here.
            (read_enumeration_type): Call
            update_enumeration_type_from_children later.  Update comments.
            (process_enumeration_scope): Don't create type fields.

Diff:
---
 gdb/ChangeLog     |  9 ++++++++
 gdb/dwarf2/read.c | 61 ++++++++++++++++++++++++-------------------------------
 2 files changed, 36 insertions(+), 34 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 026219ef844..bbe50bfe550 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,12 @@
+2020-04-29  Tom Tromey  <tromey@adacore.com>
+
+	PR ada/25875:
+	* dwarf2/read.c (update_enumeration_type_from_children): Compute
+	type fields here.
+	(read_enumeration_type): Call
+	update_enumeration_type_from_children later.  Update comments.
+	(process_enumeration_scope): Don't create type fields.
+
 2020-04-29  Kamil Rytarowski  <n54@gmx.com>
 
 	* nbsd-tdep.c: Include "xml-syscall.h".
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 130c20dbd82..1813085d0d7 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -15790,8 +15790,9 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
     }
 }
 
-/* Assuming DIE is an enumeration type, and TYPE is its associated type,
-   update TYPE using some information only available in DIE's children.  */
+/* Assuming DIE is an enumeration type, and TYPE is its associated
+   type, update TYPE using some information only available in DIE's
+   children.  In particular, the fields are computed.  */
 
 static void
 update_enumeration_type_from_children (struct die_info *die,
@@ -15803,6 +15804,7 @@ update_enumeration_type_from_children (struct die_info *die,
   int flag_enum = 1;
 
   auto_obstack obstack;
+  std::vector<struct field> fields;
 
   for (child_die = die->child;
        child_die != NULL && child_die->tag;
@@ -15838,10 +15840,19 @@ update_enumeration_type_from_children (struct die_info *die,
 	    flag_enum = 0;
 	}
 
-      /* If we already know that the enum type is neither unsigned, nor
-	 a flag type, no need to look at the rest of the enumerates.  */
-      if (!unsigned_enum && !flag_enum)
-	break;
+      fields.emplace_back ();
+      struct field &field = fields.back ();
+      FIELD_NAME (field) = dwarf2_physname (name, child_die, cu);
+      SET_FIELD_ENUMVAL (field, value);
+    }
+
+  if (!fields.empty ())
+    {
+      TYPE_NFIELDS (type) = fields.size ();
+      TYPE_FIELDS (type) = (struct field *)
+	TYPE_ALLOC (type, sizeof (struct field) * fields.size ());
+      memcpy (TYPE_FIELDS (type), fields.data (),
+	      sizeof (struct field) * fields.size ());
     }
 
   if (unsigned_enum)
@@ -15909,11 +15920,6 @@ read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu)
   if (die_is_declaration (die, cu))
     TYPE_STUB (type) = 1;
 
-  /* Finish the creation of this type by using the enum's children.
-     We must call this even when the underlying type has been provided
-     so that we can determine if we're looking at a "flag" enum.  */
-  update_enumeration_type_from_children (die, type, cu);
-
   /* If this type has an underlying type that is not a stub, then we
      may use its attributes.  We always use the "unsigned" attribute
      in this situation, because ordinarily we guess whether the type
@@ -15935,7 +15941,15 @@ read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu)
 
   TYPE_DECLARED_CLASS (type) = dwarf2_flag_true_p (die, DW_AT_enum_class, cu);
 
-  return set_die_type (die, type, cu);
+  set_die_type (die, type, cu);
+
+  /* Finish the creation of this type by using the enum's children.
+     Note that, as usual, this must come after set_die_type to avoid
+     infinite recursion when trying to compute the names of the
+     enumerators.  */
+  update_enumeration_type_from_children (die, type, cu);
+
+  return type;
 }
 
 /* Given a pointer to a die which begins an enumeration, process all
@@ -15956,8 +15970,6 @@ process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu)
   if (die->child != NULL)
     {
       struct die_info *child_die;
-      struct symbol *sym;
-      std::vector<struct field> fields;
       const char *name;
 
       child_die = die->child;
@@ -15971,30 +15983,11 @@ process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu)
 	    {
 	      name = dwarf2_name (child_die, cu);
 	      if (name)
-		{
-		  sym = new_symbol (child_die, this_type, cu);
-
-		  fields.emplace_back ();
-		  struct field &field = fields.back ();
-
-		  FIELD_NAME (field) = sym->linkage_name ();
-		  FIELD_TYPE (field) = NULL;
-		  SET_FIELD_ENUMVAL (field, SYMBOL_VALUE (sym));
-		  FIELD_BITSIZE (field) = 0;
-		}
+		new_symbol (child_die, this_type, cu);
 	    }
 
 	  child_die = child_die->sibling;
 	}
-
-      if (!fields.empty ())
-	{
-	  TYPE_NFIELDS (this_type) = fields.size ();
-	  TYPE_FIELDS (this_type) = (struct field *)
-	    TYPE_ALLOC (this_type, sizeof (struct field) * fields.size ());
-	  memcpy (TYPE_FIELDS (this_type), fields.data (),
-		  sizeof (struct field) * fields.size ());
-	}
     }
 
   /* If we are reading an enum from a .debug_types unit, and the enum


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2020-04-29 17:18 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-29 17:18 [binutils-gdb] Fix Ada crash with .debug_types Tom Tromey

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).