[PATCH] Fix Ada crash with .debug_types

Tom Tromey tromey@adacore.com
Tue Apr 28 16:58:54 GMT 2020


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-28  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.
---
 gdb/ChangeLog     |  9 +++++++
 gdb/dwarf2/read.c | 62 +++++++++++++++++++++--------------------------
 2 files changed, 37 insertions(+), 34 deletions(-)

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 130c20dbd82..dc841476d6b 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,20 @@ 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);
+      if (bytes == nullptr && baton == nullptr)
+	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 +15921,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 +15942,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 +15971,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 +15984,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
-- 
2.21.1



More information about the Gdb-patches mailing list