This is the mail archive of the gdb-cvs@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb/gdb-8.2-branch] Set CU language before processing any DIEs (symtab/23010 et al)


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

commit 9eb8d8e3e025323c9c5566b36c1fdc331aa33132
Author: Keith Seitz <keiths@redhat.com>
Date:   Tue Jul 24 12:45:51 2018 -0700

    Set CU language before processing any DIEs (symtab/23010 et al)
    
    This patch is another attempt at really fixing the multitude of assertions
    being seen where symbols of one language are being added to symbol lists of
    another language.
    
    In this specific case, the backtrace command (thread apply all bt full) that
    is looking for the compunit containing the PC of the thread. That calls
    get_prev_frame several times. This function calls (eventually)
    dwarf2_frame_prev_register. That eventually ends up calling
    find_pc_compunit_symtab.
    
    In this function (find_pc_sect_compunit_symtab actually), we loop over all
    compunits, calling the "quick" function dw2_find_pc_sect_compunit_symtab.
    That function calls dw2_instantiate_symtab to read in all the CU's symbols.
    Now the fun begins.
    
    dw2_do_instantiate_symtab queues the per_cu for reading, using a default
    "pretend" language of language_minimal with the expectation that this will
    be set later.
    
    The DIEs of this (only queued) CU are then processed.
    
    The first DIE is DW_TAG_compile_unit. That's handled by read_file_scope.
    
    (Nearly) The first thing read_file_scope does is:
    
      get_scope_pc_bounds (die, &lowpc, &highpc, cu);
    
    This function loops over the children of the current DIE (a compile_unit),
    looking for bounds. The first such child is a subprogram, and we attempt to
    get its bounds. We use dwarf2_attr to get at DW_AT_high_pc.
    
    This subprogram has DW_AT_specification set, so dwarf_attr (via
    follow_die_ref/follow_die_offset) will follow that, but follow_die_offset
    *also* attempts to load the containing CU for the spec DIE. That spec DIE
    lives inside a CU that is a partial_unit and has no language attribute. So
    it simply inherits the language from the CU that elicited the read. [That
    all happens in follow_die_offset.]
    
    The original CU's language is still language_minimal -- we haven't gotten to
    the line in read_file_scope that actually sets the language yet!
    
    And that is the cause of these problems. The call to prepare_one_comp_unit
    needs to be the *first* thing that is done when reading a CU so that the
    CU's language can be recorded (and inherited by any referenced
    partial_units).
    
    Since a test reproducer for this has been so elusive, this patch also adds a
    wrapper function around add_symbol_to_list which asserts when adding a
    symbol of one language to a list containing symbols of a different language.
    
    gdb/ChangeLog:
    2017-07-24  Keith Seitz  <keiths@redhat.com>
    
            PR symtab/23010
            * dwarf2read.c (dw2_add_symbol_to_list): New function.
            (fixup_go_packaging, new_symbol): Use dw2_add_symbol_to_list
            instead of add_symbol_to_list.
            (read_file_scope): Call prepare_one_comp_unit before reading
            any other DIEs.

Diff:
---
 gdb/ChangeLog    |  9 +++++++++
 gdb/dwarf2read.c | 28 ++++++++++++++++++++++------
 2 files changed, 31 insertions(+), 6 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 6ed5e8e..be8fc52 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,12 @@
+2018-07-24  Keith Seitz  <keiths@redhat.comt
+
+	PR symtab/23010
+	* dwarf2read.c (dw2_add_symbol_to_list): New function.
+	(fixup_go_packaging, new_symbol): Use dw2_add_symbol_to_list
+	instead of add_symbol_to_list.
+	(read_file_scope): Call prepare_one_comp_unit before reading
+	any other DIEs.
+
 2018-07-22  Tom Tromey  <tom@tromey.com>
 
 	* symfile.c (reread_symbols): Notify iter, not objfile.
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 372f45e..a056b85 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -9700,6 +9700,23 @@ compute_delayed_physnames (struct dwarf2_cu *cu)
   cu->method_list.clear ();
 }
 
+/* A wrapper for add_symbol_to_list to ensure that SYMBOL's language is
+   the same as all other symbols in LISTHEAD.  If a new symbol is added
+   with a different language, this function asserts.  */
+
+static inline void
+dw2_add_symbol_to_list (struct symbol *symbol, struct pending **listhead)
+{
+  /* Only assert if LISTHEAD already contains symbols of a different
+     language (dict_create_hashed/insert_symbol_hashed requires that all
+     symbols in this list are of the same language).  */
+  gdb_assert ((*listhead) == NULL
+	      || (SYMBOL_LANGUAGE ((*listhead)->symbol[0])
+		  == SYMBOL_LANGUAGE (symbol)));
+
+  add_symbol_to_list (symbol, listhead);
+}
+
 /* Go objects should be embedded in a DW_TAG_module DIE,
    and it's not clear if/how imported objects will appear.
    To keep Go support simple until that's worked out,
@@ -9771,7 +9788,7 @@ fixup_go_packaging (struct dwarf2_cu *cu)
       SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
       SYMBOL_TYPE (sym) = type;
 
-      add_symbol_to_list (sym, &global_symbols);
+      dw2_add_symbol_to_list (sym, &global_symbols);
 
       xfree (package_name);
     }
@@ -11431,6 +11448,7 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
   struct die_info *child_die;
   CORE_ADDR baseaddr;
 
+  prepare_one_comp_unit (cu, die, cu->language);
   baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 
   get_scope_pc_bounds (die, &lowpc, &highpc, cu);
@@ -11443,8 +11461,6 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
 
   file_and_directory fnd = find_file_and_directory (die, cu);
 
-  prepare_one_comp_unit (cu, die, cu->language);
-
   /* The XLCL doesn't generate DW_LANG_OpenCL because this attribute is not
      standardised yet.  As a workaround for the language detection we fall
      back to the DW_AT_producer string.  */
@@ -21201,7 +21217,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
 	  SYMBOL_TYPE (sym) = objfile_type (objfile)->builtin_core_addr;
 	  SYMBOL_DOMAIN (sym) = LABEL_DOMAIN;
 	  SYMBOL_ACLASS_INDEX (sym) = LOC_LABEL;
-	  add_symbol_to_list (sym, cu->list_in_scope);
+	  dw2_add_symbol_to_list (sym, cu->list_in_scope);
 	  break;
 	case DW_TAG_subprogram:
 	  /* SYMBOL_BLOCK_VALUE (sym) will be filled in later by
@@ -21459,7 +21475,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
 	case DW_TAG_common_block:
 	  SYMBOL_ACLASS_INDEX (sym) = LOC_COMMON_BLOCK;
 	  SYMBOL_DOMAIN (sym) = COMMON_BLOCK_DOMAIN;
-	  add_symbol_to_list (sym, cu->list_in_scope);
+	  dw2_add_symbol_to_list (sym, cu->list_in_scope);
 	  break;
 	default:
 	  /* Not a tag we recognize.  Hopefully we aren't processing
@@ -21479,7 +21495,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
 	}
 
       if (list_to_add != NULL)
-	add_symbol_to_list (sym, list_to_add);
+	dw2_add_symbol_to_list (sym, list_to_add);
 
       /* For the benefit of old versions of GCC, check for anonymous
 	 namespaces based on the demangled name.  */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]