[03/14] Introduce dwarf2_per_objfile::obstack

Message ID 20200215165444.32653-4-tom@tromey.com
State New, archived
Headers

Commit Message

Tom Tromey Feb. 15, 2020, 4:54 p.m. UTC
  Currently much of the DWARF-related data is stored on the obfile
obstack.  This prevents sharing this data across objfiles, so this
patch adds a new obstack to dwarf2_per_objfile.

One way to check whether this is correct is to look at the remaining
uses of objfile_obstack in the DWARF code and note that they all
appear in the "full CU" code paths.

The converse -- storing per-objfile data on the shared obstack -- is
not good, but it is just a memory leak, not a potential
use-after-free.  Double-checking this would also be useful, though.

gdb/ChangeLog
2020-02-15  Tom Tromey  <tom@tromey.com>

	* dwarf2/read.h (struct dwarf2_per_objfile) <obstack>: New
	member.
	* dwarf2/read.c (delete_file_name_entry): Fix comment.
	(create_cu_from_index_list)
	(create_signatured_type_table_from_index)
	(create_signatured_type_table_from_debug_names)
	(dw2_get_file_names_reader, dw2_get_real_path)
	(dwarf2_initialize_objfile, dwarf2_create_include_psymtab)
	(create_debug_type_hash_table, add_type_unit)
	(create_type_unit_group, read_comp_units_from_section)
	(dwarf2_compute_name, create_cus_hash_table)
	(create_dwp_hash_table, create_dwo_unit_in_dwp_v1)
	(create_dwo_unit_in_dwp_v2, open_and_init_dwp_file): Use new
	obstack.
---
 gdb/ChangeLog     | 17 +++++++++
 gdb/dwarf2/read.c | 88 ++++++++++++++++++++++-------------------------
 gdb/dwarf2/read.h |  5 +++
 3 files changed, 64 insertions(+), 46 deletions(-)
  

Comments

Simon Marchi Feb. 19, 2020, 4:13 a.m. UTC | #1
On 2020-02-15 11:54 a.m., Tom Tromey wrote:
> Currently much of the DWARF-related data is stored on the obfile
> obstack.  This prevents sharing this data across objfiles, so this
> patch adds a new obstack to dwarf2_per_objfile.
> 
> One way to check whether this is correct is to look at the remaining
> uses of objfile_obstack in the DWARF code and note that they all
> appear in the "full CU" code paths.
> 
> The converse -- storing per-objfile data on the shared obstack -- is
> not good, but it is just a memory leak, not a potential
> use-after-free.  Double-checking this would also be useful, though.

I looked and nothing wrong stood out, but there are a lot of uses and they
are not all trivial, so I might have very well missed some mistakes.

Kind of unrelated, but while reviewing this, I noticed:

- allocate_dwo_file_hash_table
- allocate_type_unit_groups_table
- allocate_signatured_type_table
- allocate_dwp_loaded_cutus_table
- allocate_dwo_unit_table

All have objfile parameters which are unused and could probably be removed.  In at least
one instance, it would allow removing ann objfile local variable.

> @@ -3202,8 +3200,12 @@ dw2_get_real_path (struct objfile *objfile,
>  		   struct quick_file_names *qfn, int index)
>  {
>    if (qfn->real_names == NULL)
> -    qfn->real_names = OBSTACK_CALLOC (&objfile->objfile_obstack,
> -				      qfn->num_file_names, const char *);
> +    {
> +      struct dwarf2_per_objfile *dwarf2_per_objfile
> +	= get_dwarf2_per_objfile (objfile);
> +      qfn->real_names = OBSTACK_CALLOC (&dwarf2_per_objfile->obstack,
> +					qfn->num_file_names, const char *);
> +    }

The callers of dw2_get_real_path should be able to pass the dwarf2_per_objfile directly,
instead of the objfile, simplifying this.

Simon
  
Tom Tromey Feb. 22, 2020, 12:44 a.m. UTC | #2
>>>>> "Simon" == Simon Marchi <simark@simark.ca> writes:

>> +      struct dwarf2_per_objfile *dwarf2_per_objfile
>> +	= get_dwarf2_per_objfile (objfile);
>> +      qfn->real_names = OBSTACK_CALLOC (&dwarf2_per_objfile->obstack,
>> +					qfn->num_file_names, const char *);
>> +    }

Simon> The callers of dw2_get_real_path should be able to pass the dwarf2_per_objfile directly,
Simon> instead of the objfile, simplifying this.

Indeed.  I made this change.

Tom
  

Patch

diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 81d8cbf0b13..d3060be630d 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -2280,8 +2280,8 @@  delete_file_name_entry (void *e)
 	xfree ((void*) file_data->real_names[i]);
     }
 
-  /* The space for the struct itself lives on objfile_obstack,
-     so we don't free it here.  */
+  /* The space for the struct itself lives on the obstack, so we don't
+     free it here.  */
 }
 
 /* Create a quick_file_names hash table.  */
@@ -2412,9 +2412,8 @@  dwarf2_per_objfile::get_tu (int index)
   return this->all_type_units[index];
 }
 
-/* Return a new dwarf2_per_cu_data allocated on OBJFILE's
-   objfile_obstack, and constructed with the specified field
-   values.  */
+/* Return a new dwarf2_per_cu_data allocated on the dwarf2_per_objfile
+   obstack, and constructed with the specified field values.  */
 
 static dwarf2_per_cu_data *
 create_cu_from_index_list (struct dwarf2_per_objfile *dwarf2_per_objfile,
@@ -2422,16 +2421,15 @@  create_cu_from_index_list (struct dwarf2_per_objfile *dwarf2_per_objfile,
                           int is_dwz,
                           sect_offset sect_off, ULONGEST length)
 {
-  struct objfile *objfile = dwarf2_per_objfile->objfile;
   dwarf2_per_cu_data *the_cu
-    = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+    = OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack,
                      struct dwarf2_per_cu_data);
   the_cu->sect_off = sect_off;
   the_cu->length = length;
   the_cu->dwarf2_per_objfile = dwarf2_per_objfile;
   the_cu->section = section;
-  the_cu->v.quick = OBSTACK_ZALLOC (&objfile->objfile_obstack,
-                                   struct dwarf2_per_cu_quick_data);
+  the_cu->v.quick = OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack,
+				    struct dwarf2_per_cu_quick_data);
   the_cu->is_dwz = is_dwz;
   return the_cu;
 }
@@ -2516,7 +2514,7 @@  create_signatured_type_table_from_index
       signature = extract_unsigned_integer (bytes + 16, 8, BFD_ENDIAN_LITTLE);
       bytes += 3 * 8;
 
-      sig_type = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+      sig_type = OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack,
 				 struct signatured_type);
       sig_type->signature = signature;
       sig_type->type_offset_in_tu = type_offset_in_tu;
@@ -2525,7 +2523,7 @@  create_signatured_type_table_from_index
       sig_type->per_cu.sect_off = sect_off;
       sig_type->per_cu.dwarf2_per_objfile = dwarf2_per_objfile;
       sig_type->per_cu.v.quick
-	= OBSTACK_ZALLOC (&objfile->objfile_obstack,
+	= OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack,
 			  struct dwarf2_per_cu_quick_data);
 
       slot = htab_find_slot (sig_types_hash.get (), sig_type, INSERT);
@@ -2573,7 +2571,7 @@  create_signatured_type_table_from_debug_names
 				     section->buffer + to_underlying (sect_off),
 				     rcuh_kind::TYPE);
 
-      sig_type = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+      sig_type = OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack,
 				 struct signatured_type);
       sig_type->signature = cu_header.signature;
       sig_type->type_offset_in_tu = cu_header.type_cu_offset_in_tu;
@@ -2582,7 +2580,7 @@  create_signatured_type_table_from_debug_names
       sig_type->per_cu.sect_off = sect_off;
       sig_type->per_cu.dwarf2_per_objfile = dwarf2_per_objfile;
       sig_type->per_cu.v.quick
-	= OBSTACK_ZALLOC (&objfile->objfile_obstack,
+	= OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack,
 			  struct dwarf2_per_cu_quick_data);
 
       slot = htab_find_slot (sig_types_hash.get (), sig_type, INSERT);
@@ -3094,7 +3092,6 @@  dw2_get_file_names_reader (const struct die_reader_specs *reader,
   struct dwarf2_per_cu_data *this_cu = cu->per_cu;
   struct dwarf2_per_objfile *dwarf2_per_objfile
     = cu->per_cu->dwarf2_per_objfile;
-  struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct dwarf2_per_cu_data *lh_cu;
   struct attribute *attr;
   void **slot;
@@ -3143,7 +3140,7 @@  dw2_get_file_names_reader (const struct die_reader_specs *reader,
       return;
     }
 
-  qfn = XOBNEW (&objfile->objfile_obstack, struct quick_file_names);
+  qfn = XOBNEW (&dwarf2_per_objfile->obstack, struct quick_file_names);
   qfn->hash.dwo_unit = cu->dwo_unit;
   qfn->hash.line_sect_off = line_offset;
   gdb_assert (slot != NULL);
@@ -3157,7 +3154,8 @@  dw2_get_file_names_reader (const struct die_reader_specs *reader,
 
   qfn->num_file_names = offset + lh->file_names_size ();
   qfn->file_names =
-    XOBNEWVEC (&objfile->objfile_obstack, const char *, qfn->num_file_names);
+    XOBNEWVEC (&dwarf2_per_objfile->obstack, const char *,
+	       qfn->num_file_names);
   if (offset != 0)
     qfn->file_names[0] = xstrdup (fnd.name);
   for (int i = 0; i < lh->file_names_size (); ++i)
@@ -3202,8 +3200,12 @@  dw2_get_real_path (struct objfile *objfile,
 		   struct quick_file_names *qfn, int index)
 {
   if (qfn->real_names == NULL)
-    qfn->real_names = OBSTACK_CALLOC (&objfile->objfile_obstack,
-				      qfn->num_file_names, const char *);
+    {
+      struct dwarf2_per_objfile *dwarf2_per_objfile
+	= get_dwarf2_per_objfile (objfile);
+      qfn->real_names = OBSTACK_CALLOC (&dwarf2_per_objfile->obstack,
+					qfn->num_file_names, const char *);
+    }
 
   if (qfn->real_names[index] == NULL)
     qfn->real_names[index] = gdb_realpath (qfn->file_names[index]).release ();
@@ -5753,7 +5755,7 @@  dwarf2_initialize_objfile (struct objfile *objfile, dw_index_kind *index_kind)
 	{
 	  dwarf2_per_cu_data *per_cu = dwarf2_per_objfile->get_cutu (i);
 
-	  per_cu->v.quick = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+	  per_cu->v.quick = OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack,
 					    struct dwarf2_per_cu_quick_data);
 	}
 
@@ -5909,10 +5911,7 @@  dwarf2_create_include_psymtab (const char *name, dwarf2_psymtab *pst,
   dwarf2_psymtab *subpst = new dwarf2_psymtab (name, objfile);
 
   if (!IS_ABSOLUTE_PATH (subpst->filename))
-    {
-      /* It shares objfile->objfile_obstack.  */
-      subpst->dirname = pst->dirname;
-    }
+    subpst->dirname = pst->dirname;
 
   subpst->dependencies = objfile->partial_symtabs->allocate_dependencies (1);
   subpst->dependencies[0] = pst;
@@ -6075,7 +6074,7 @@  create_debug_type_hash_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
       if (dwo_file)
 	{
 	  sig_type = NULL;
-	  dwo_tu = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+	  dwo_tu = OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack,
 				   struct dwo_unit);
 	  dwo_tu->dwo_file = dwo_file;
 	  dwo_tu->signature = header.signature;
@@ -6089,7 +6088,7 @@  create_debug_type_hash_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
 	  /* N.B.: type_offset is not usable if this type uses a DWO file.
 	     The real type_offset is in the DWO file.  */
 	  dwo_tu = NULL;
-	  sig_type = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+	  sig_type = OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack,
 				     struct signatured_type);
 	  sig_type->signature = header.signature;
 	  sig_type->type_offset_in_tu = header.type_cu_offset_in_tu;
@@ -6201,13 +6200,11 @@  static struct signatured_type *
 add_type_unit (struct dwarf2_per_objfile *dwarf2_per_objfile, ULONGEST sig,
 	       void **slot)
 {
-  struct objfile *objfile = dwarf2_per_objfile->objfile;
-
   if (dwarf2_per_objfile->all_type_units.size ()
       == dwarf2_per_objfile->all_type_units.capacity ())
     ++dwarf2_per_objfile->tu_stats.nr_all_type_units_reallocs;
 
-  signatured_type *sig_type = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+  signatured_type *sig_type = OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack,
 					      struct signatured_type);
 
   dwarf2_per_objfile->all_type_units.push_back (sig_type);
@@ -6216,7 +6213,7 @@  add_type_unit (struct dwarf2_per_objfile *dwarf2_per_objfile, ULONGEST sig,
   if (dwarf2_per_objfile->using_index)
     {
       sig_type->per_cu.v.quick =
-	OBSTACK_ZALLOC (&objfile->objfile_obstack,
+	OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack,
 			struct dwarf2_per_cu_quick_data);
     }
 
@@ -7108,18 +7105,17 @@  create_type_unit_group (struct dwarf2_cu *cu, sect_offset line_offset_struct)
 {
   struct dwarf2_per_objfile *dwarf2_per_objfile
     = cu->per_cu->dwarf2_per_objfile;
-  struct objfile *objfile = dwarf2_per_objfile->objfile;
   struct dwarf2_per_cu_data *per_cu;
   struct type_unit_group *tu_group;
 
-  tu_group = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+  tu_group = OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack,
 			     struct type_unit_group);
   per_cu = &tu_group->per_cu;
   per_cu->dwarf2_per_objfile = dwarf2_per_objfile;
 
   if (dwarf2_per_objfile->using_index)
     {
-      per_cu->v.quick = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+      per_cu->v.quick = OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack,
 					struct dwarf2_per_cu_quick_data);
     }
   else
@@ -7837,13 +7833,13 @@  read_comp_units_from_section (struct dwarf2_per_objfile *dwarf2_per_objfile,
       /* Save the compilation unit for later lookup.  */
       if (cu_header.unit_type != DW_UT_type)
 	{
-	  this_cu = XOBNEW (&objfile->objfile_obstack,
+	  this_cu = XOBNEW (&dwarf2_per_objfile->obstack,
 			    struct dwarf2_per_cu_data);
 	  memset (this_cu, 0, sizeof (*this_cu));
 	}
       else
 	{
-	  auto sig_type = XOBNEW (&objfile->objfile_obstack,
+	  auto sig_type = XOBNEW (&dwarf2_per_objfile->obstack,
 				  struct signatured_type);
 	  memset (sig_type, 0, sizeof (*sig_type));
 	  sig_type->signature = cu_header.signature;
@@ -9985,7 +9981,8 @@  dw2_linkage_name (struct die_info *die, struct dwarf2_cu *cu)
    For Ada, return the DIE's linkage name rather than the fully qualified
    name.  PHYSNAME is ignored..
 
-   The result is allocated on the objfile_obstack and canonicalized.  */
+   The result is allocated on the dwarf2_per_objfile obstack and
+   canonicalized.  */
 
 static const char *
 dwarf2_compute_name (const char *name,
@@ -11145,7 +11142,8 @@  create_cus_hash_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
       if (cus_htab == NULL)
 	cus_htab = allocate_dwo_unit_table (objfile);
 
-      dwo_unit = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_unit);
+      dwo_unit = OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack,
+				 struct dwo_unit);
       *dwo_unit = read_unit;
       slot = htab_find_slot (cus_htab.get (), dwo_unit, INSERT);
       gdb_assert (slot != NULL);
@@ -11348,7 +11346,7 @@  create_dwp_hash_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
 	     pulongest (nr_slots), dwp_file->name);
     }
 
-  htab = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwp_hash_table);
+  htab = OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack, struct dwp_hash_table);
   htab->version = version;
   htab->nr_columns = nr_columns;
   htab->nr_units = nr_units;
@@ -11545,7 +11543,6 @@  create_dwo_unit_in_dwp_v1 (struct dwarf2_per_objfile *dwarf2_per_objfile,
 			   const char *comp_dir,
 			   ULONGEST signature, int is_debug_types)
 {
-  struct objfile *objfile = dwarf2_per_objfile->objfile;
   const struct dwp_hash_table *dwp_htab =
     is_debug_types ? dwp_file->tus : dwp_file->cus;
   bfd *dbfd = dwp_file->dbfd.get ();
@@ -11650,7 +11647,7 @@  create_dwo_unit_in_dwp_v1 (struct dwarf2_per_objfile *dwarf2_per_objfile,
 			      virtual_dwo_name.c_str ());
 	}
       dwo_file = new struct dwo_file;
-      dwo_file->dwo_name = obstack_strdup (&objfile->objfile_obstack,
+      dwo_file->dwo_name = obstack_strdup (&dwarf2_per_objfile->obstack,
 					   virtual_dwo_name);
       dwo_file->comp_dir = comp_dir;
       dwo_file->sections.abbrev = sections.abbrev;
@@ -11680,11 +11677,11 @@  create_dwo_unit_in_dwp_v1 (struct dwarf2_per_objfile *dwarf2_per_objfile,
       dwo_file = (struct dwo_file *) *dwo_file_slot;
     }
 
-  dwo_unit = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_unit);
+  dwo_unit = OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack, struct dwo_unit);
   dwo_unit->dwo_file = dwo_file;
   dwo_unit->signature = signature;
   dwo_unit->section =
-    XOBNEW (&objfile->objfile_obstack, struct dwarf2_section_info);
+    XOBNEW (&dwarf2_per_objfile->obstack, struct dwarf2_section_info);
   *dwo_unit->section = sections.info_or_types;
   /* dwo_unit->{offset,length,type_offset_in_tu} are set later.  */
 
@@ -11745,7 +11742,6 @@  create_dwo_unit_in_dwp_v2 (struct dwarf2_per_objfile *dwarf2_per_objfile,
 			   const char *comp_dir,
 			   ULONGEST signature, int is_debug_types)
 {
-  struct objfile *objfile = dwarf2_per_objfile->objfile;
   const struct dwp_hash_table *dwp_htab =
     is_debug_types ? dwp_file->tus : dwp_file->cus;
   bfd *dbfd = dwp_file->dbfd.get ();
@@ -11846,7 +11842,7 @@  create_dwo_unit_in_dwp_v2 (struct dwarf2_per_objfile *dwarf2_per_objfile,
 			      virtual_dwo_name.c_str ());
 	}
       dwo_file = new struct dwo_file;
-      dwo_file->dwo_name = obstack_strdup (&objfile->objfile_obstack,
+      dwo_file->dwo_name = obstack_strdup (&dwarf2_per_objfile->obstack,
 					   virtual_dwo_name);
       dwo_file->comp_dir = comp_dir;
       dwo_file->sections.abbrev =
@@ -11890,11 +11886,11 @@  create_dwo_unit_in_dwp_v2 (struct dwarf2_per_objfile *dwarf2_per_objfile,
       dwo_file = (struct dwo_file *) *dwo_file_slot;
     }
 
-  dwo_unit = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_unit);
+  dwo_unit = OBSTACK_ZALLOC (&dwarf2_per_objfile->obstack, struct dwo_unit);
   dwo_unit->dwo_file = dwo_file;
   dwo_unit->signature = signature;
   dwo_unit->section =
-    XOBNEW (&objfile->objfile_obstack, struct dwarf2_section_info);
+    XOBNEW (&dwarf2_per_objfile->obstack, struct dwarf2_section_info);
   *dwo_unit->section = create_dwp_v2_section (dwarf2_per_objfile,
 					      is_debug_types
 					      ? &dwp_file->sections.types
@@ -12395,7 +12391,7 @@  open_and_init_dwp_file (struct dwarf2_per_objfile *dwarf2_per_objfile)
 
   dwp_file->num_sections = elf_numsections (dwp_file->dbfd);
   dwp_file->elf_sections =
-    OBSTACK_CALLOC (&objfile->objfile_obstack,
+    OBSTACK_CALLOC (&dwarf2_per_objfile->obstack,
 		    dwp_file->num_sections, asection *);
 
   bfd_map_over_sections (dwp_file->dbfd.get (),
diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h
index b06c2e218c1..a7ac3b6b025 100644
--- a/gdb/dwarf2/read.h
+++ b/gdb/dwarf2/read.h
@@ -118,6 +118,11 @@  private:
 			const dwarf2_debug_sections &names);
 
 public:
+  /* Objects that can be shared across objfiles are stored in this
+     obstack or on the psymtab obstack, while objects that are
+     objfile-specific are stored on the objfile obstack.  */
+  auto_obstack obstack;
+
   dwarf2_section_info info {};
   dwarf2_section_info abbrev {};
   dwarf2_section_info line {};