public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Keith Seitz <keiths@redhat.com>
To: Tom Tromey <tromey@redhat.com>
Cc: gdb-patches@sourceware.org
Subject: Re: [RFA] Delayed physname computation
Date: Tue, 11 May 2010 21:18:00 -0000	[thread overview]
Message-ID: <4BE9C9A0.2030605@redhat.com> (raw)
In-Reply-To: <m3eii2njnx.fsf@fleche.redhat.com>

[-- Attachment #1: Type: text/plain, Size: 2695 bytes --]

I'm attaching the revised version of this patch, which implements your 
requests. I am also attaching a related patch (more below).

On 04/26/2010 11:38 AM, Tom Tromey wrote:
>>>>>> "Keith" == Keith Seitz<keiths@redhat.com>  writes:
>
> Keith>  Yeah, I wasn't 100% sure whether this needed a cleanup,
> Keith>  either. Nonetheless, we have two options, catch any errors (which I
> Keith>  think was suggested in another thread for a different problem) or add
> Keith>  a cleanup. A little paranoia can't hurt that much. If you have a
> Keith>  preference, I'll implement that.
>
> One of us can handle it in a followup patch.

I've added a cleanup for this.

>>> Can this call to dwarf2_physname exhibit the problem that this patch is
>>> trying to circumvent?
>
> Keith>  Unfortunately, it very well could. I guess it would be almost as
> Keith>  useful if this called dwarf2_fullname instead. What do you think?
>
> Yeah.  I think it is important for the error case not to crash.
> Printing something useful is good, maybe even the CU+DIE would be
> enough.

I've change this to call dwarf2_full_name, which should tell us 
everything except any overload information -- more than enough, IMO, for 
a developer to track down the underlying cause.

Now for the "new" part. Fedora testing has revealed a problem with the 
optimization that this delayed physname patch uses (allocating all the 
memory at once instead of piecemeal). The assert in add_to_method_list 
could be triggered.

This was happening because, for some code, like that below, gdb would 
call dwarf2_full_name (and determine_prefix) while reading in a specific 
DIE, which would then eventually try to read in the same DIE's type. 
This resulted in add_to_method_list being called twice for the same DIE 
and gdb would assert.

Here's an example that exhibits this "problem" (which I dub an obstack 
"leak" because we might end up attempting to allocate/assign two 
different struct type's for the same DIE):

class a
{
private:
   class b
   {
   public:
     b () { }
   };

   std::vector<b> list;
};

If you put a printf in set_die_type, you'll see that this function is 
called twice (with different type structs) for the same DIE.

Since there is no way to detect/trigger this in gdb without the delayed 
physname patch, there seems little point IMO in testing specifically for 
this. However it would be trivial for me to write up a testcase for 
this. Just say the word.

Keith

ChangeLog (for the obstack leak patch)
2010-05-11  Keith Seitz  <keiths@redhat.com>

         * dwarf2read.c (read_structure_type): Check if the current
         DIE's type was already completed after dwarf2_full_name
         was called.

[-- Attachment #2: delayed_physnames-2.patch --]
[-- Type: text/plain, Size: 22453 bytes --]

Index: dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.383
diff -u -p -r1.383 dwarf2read.c
--- dwarf2read.c	8 May 2010 04:58:45 -0000	1.383
+++ dwarf2read.c	11 May 2010 20:46:22 -0000
@@ -215,6 +215,26 @@ struct comp_unit_head
   unsigned int first_die_offset;
 };
 
+/* Type used for delaying computation of method physnames.
+   See comments for compute_delayed_physnames.  */
+struct delayed_method_info
+{
+  /* The type to which the method is attached, i.e., its parent class.  */
+  struct type *type;
+
+  /* The index of the method in the type's function fieldlists.  */
+  int fnfield_index;
+
+  /* The index of the method in the fieldlist.  */
+  int index;
+
+  /* The name of the DIE.  */
+  const char *name;
+
+  /*  The DIE associated with this method.  */
+  struct die_info *die;
+};
+
 /* Internal state when decoding a particular compilation unit.  */
 struct dwarf2_cu
 {
@@ -293,6 +313,11 @@ struct dwarf2_cu
   /* Header data from the line table, during full symbol processing.  */
   struct line_header *line_header;
 
+  /* A list of methods which need to have physnames computed
+     after all type information has been read.  */
+  int method_index;
+  struct delayed_method_info *method_list;
+
   /* Mark used when releasing cached dies.  */
   unsigned int mark : 1;
 
@@ -350,6 +375,10 @@ struct dwarf2_per_cu_data
      or NULL for partial units (which do not have an associated
      symtab).  */
   struct partial_symtab *psymtab;
+
+  /* The total number of methods found in the CU.  This field is
+     used to allocate memory for delayed physname processing.  */
+  int num_methods;
 };
 
 /* Entry in the signatured_types hash table.  */
@@ -1121,6 +1150,9 @@ static void dwarf2_clear_marks (struct d
 
 static struct type *get_die_type (struct die_info *die, struct dwarf2_cu *cu);
 
+static const char *dwarf2_physname (char *name, struct die_info *die,
+				    struct dwarf2_cu *cu);
+
 /* Try to locate the sections we need for DWARF 2 debugging
    information and return true if we have enough to do something.  */
 
@@ -2171,6 +2203,24 @@ create_all_comp_units (struct objfile *o
   dwarf2_per_objfile->n_comp_units = n_comp_units;
 }
 
+/* Count the number of methods in partial die PDI and its children, if any.
+   The result is recorded in CU.  This is used to give an upper bound
+   for the number of slots needed in the delayed method list in the CU.
+   See compute_delayed_physnames.  */
+static void
+count_partial_methods (struct partial_die_info *pdi, struct dwarf2_cu *cu)
+{
+  struct partial_die_info *die;
+  for (die = pdi->die_child; die; die = die->die_sibling)
+    {
+      if (die->tag == DW_TAG_subprogram)
+	++(cu->per_cu->num_methods);
+
+      if (die->has_children)
+	count_partial_methods (die, cu);
+    }
+}
+
 /* Process all loaded DIEs for compilation unit CU, starting at
    FIRST_DIE.  The caller should pass NEED_PC == 1 if the compilation
    unit DIE did not have PC info (DW_AT_low_pc and DW_AT_high_pc, or
@@ -2206,9 +2256,11 @@ scan_partial_symbols (struct partial_die
 	    case DW_TAG_subprogram:
 	      add_partial_subprogram (pdi, lowpc, highpc, need_pc, cu);
 	      break;
+	    case DW_TAG_union_type:
+	      count_partial_methods (pdi, cu);
+	      /* fall through */
 	    case DW_TAG_variable:
 	    case DW_TAG_typedef:
-	    case DW_TAG_union_type:
 	      if (!pdi->is_declaration)
 		{
 		  add_partial_symbol (pdi, cu);
@@ -2217,6 +2269,7 @@ scan_partial_symbols (struct partial_die
 	    case DW_TAG_class_type:
 	    case DW_TAG_interface_type:
 	    case DW_TAG_structure_type:
+	      count_partial_methods (pdi, cu);
 	      if (!pdi->is_declaration)
 		{
 		  add_partial_symbol (pdi, cu);
@@ -2565,6 +2618,7 @@ add_partial_subprogram (struct partial_d
 {
   if (pdi->tag == DW_TAG_subprogram)
     {
+      count_partial_methods (pdi, cu);
       if (pdi->has_pc_info)
         {
           if (pdi->lowpc < *lowpc)
@@ -3091,6 +3145,42 @@ load_full_comp_unit (struct dwarf2_per_c
   discard_cleanups (free_cu_cleanup);
 }
 
+/* Add a DIE to the delayed physname list.  */
+static void
+add_to_method_list (struct type *type, int fnfield_index, int index,
+		    const char *name, struct die_info *die,
+		    struct dwarf2_cu *cu)
+{
+  struct delayed_method_info *mi;
+  gdb_assert (cu->method_index < cu->per_cu->num_methods);
+  mi = &cu->method_list[cu->method_index++];
+  mi->type = type;
+  mi->fnfield_index = fnfield_index;
+  mi->index = index;
+  mi->name = name;
+  mi->die = die;
+}
+
+/* Compute the physnames of any methods on the CU's method list.
+
+   The computation of method physnames is delayed in order to avoid the
+   (bad) condition that one of the method's formal parameters is of an as yet
+   incomplete type.  */
+static void
+compute_delayed_physnames (struct dwarf2_cu *cu)
+{
+  int i;
+  for (i = 0; i < cu->method_index; ++i)
+    {
+      char *physname;
+      struct delayed_method_info *mi = &cu->method_list[i];
+      struct fn_fieldlist *fn_flp
+	= &TYPE_FN_FIELDLIST (mi->type, mi->fnfield_index);
+      physname = (char *) dwarf2_physname ((char *) mi->name, mi->die, cu);
+      fn_flp->fn_fields[mi->index].physname = physname ? physname : "";
+    }
+}
+
 /* Generate full symbol information for PST and CU, whose DIEs have
    already been loaded into memory.  */
 
@@ -3102,7 +3192,7 @@ process_full_comp_unit (struct dwarf2_pe
   struct objfile *objfile = pst->objfile;
   CORE_ADDR lowpc, highpc;
   struct symtab *symtab;
-  struct cleanup *back_to;
+  struct cleanup *back_to, *delayed_list_cleanup;
   CORE_ADDR baseaddr;
 
   baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
@@ -3112,11 +3202,31 @@ process_full_comp_unit (struct dwarf2_pe
 
   cu->list_in_scope = &file_symbols;
 
+  /* If methods were found in the partial symbol table, we allocate one
+     big buffer to hold the entire delayed list for the CU.  */
+  if (per_cu->num_methods)
+    {
+      cu->method_list
+	= xmalloc (per_cu->num_methods * sizeof (struct delayed_method_info));
+      delayed_list_cleanup = make_cleanup (xfree, cu->method_list);
+    }
+
   dwarf2_find_base_address (cu->dies, cu);
 
   /* Do line number decoding in read_file_scope () */
   process_die (cu->dies, cu);
 
+  /* Now that we have processed all the DIEs in the CU, all the types 
+     should be complete, and it should now be safe to compute all of the
+     physnames.  */
+  if (per_cu->num_methods)
+    {
+      compute_delayed_physnames (cu);
+      do_cleanups (delayed_list_cleanup);
+      delayed_list_cleanup = NULL;
+      cu->method_list = NULL;
+    }
+
   /* Some compilers don't define a DW_AT_high_pc attribute for the
      compilation unit.  If the DW_AT_high_pc is missing, synthesize
      it, by scanning the DIE's below the compilation unit.  */
@@ -4739,7 +4849,6 @@ dwarf2_add_member_fn (struct field_info 
   int i;
   struct fn_field *fnp;
   char *fieldname;
-  char *physname;
   struct nextfnfield *new_fnfield;
   struct type *this_type;
 
@@ -4751,9 +4860,6 @@ dwarf2_add_member_fn (struct field_info 
   if (fieldname == NULL)
     return;
 
-  /* Get the mangled name.  */
-  physname = (char *) dwarf2_physname (fieldname, die, cu);
-
   /* Look up member function name in fieldlist.  */
   for (i = 0; i < fip->nfnfields; i++)
     {
@@ -4779,7 +4885,7 @@ dwarf2_add_member_fn (struct field_info 
       flp->name = fieldname;
       flp->length = 0;
       flp->head = NULL;
-      fip->nfnfields++;
+      i = fip->nfnfields++;
     }
 
   /* Create a new member function field and chain it to the field list
@@ -4793,9 +4899,19 @@ dwarf2_add_member_fn (struct field_info 
 
   /* Fill in the member function field info.  */
   fnp = &new_fnfield->fnfield;
-  /* The name is already allocated along with this objfile, so we don't
-     need to duplicate it for the type.  */
-  fnp->physname = physname ? physname : "";
+
+  /* Delay processing of the physname until later.  */
+  if (cu->language == language_cplus || cu->language == language_java)
+    {
+      add_to_method_list (type, i, flp->length - 1, fieldname,
+			  die, cu);
+    }
+  else
+    {
+      char *physname = (char *) dwarf2_physname (fieldname, die, cu);
+      fnp->physname = physname ? physname : "";
+    }
+
   fnp->type = alloc_type (objfile);
   this_type = read_type_die (die, cu);
   if (this_type && TYPE_CODE (this_type) == TYPE_CODE_FUNC)
@@ -4821,7 +4937,7 @@ dwarf2_add_member_fn (struct field_info 
     }
   else
     complaint (&symfile_complaints, _("member function type missing for '%s'"),
-	       physname);
+	       dwarf2_full_name (fieldname, die, cu));
 
   /* Get fcontext from DW_AT_containing_type if present.  */
   if (dwarf2_attr (die, DW_AT_containing_type, cu) != NULL)
@@ -6758,7 +6874,9 @@ load_partial_dies (bfd *abfd, gdb_byte *
 		      || last_die->tag == DW_TAG_interface_type
 		      || last_die->tag == DW_TAG_structure_type
 		      || last_die->tag == DW_TAG_union_type))
-	      || (cu->language == language_ada
+	      || ((cu->language == language_ada
+		   || cu->language == language_cplus
+		   || cu->language == language_java)
 		  && (last_die->tag == DW_TAG_subprogram
 		      || last_die->tag == DW_TAG_lexical_block))))
 	{
Index: testsuite/gdb.dwarf2/pr11465.exp
===================================================================
RCS file: testsuite/gdb.dwarf2/pr11465.exp
diff -N testsuite/gdb.dwarf2/pr11465.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.dwarf2/pr11465.exp	11 May 2010 20:46:22 -0000
@@ -0,0 +1,39 @@
+# Copyright 2010 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# This test can only be run on targets which support DWARF-2 and use gas.
+# For now pick a sampling of likely targets.
+if {![istarget *-*-linux*]
+    && ![istarget *-*-gnu*]
+    && ![istarget *-*-elf*]
+    && ![istarget *-*-openbsd*]
+    && ![istarget arm-*-eabi*]
+    && ![istarget powerpc-*-eabi*]} {
+    return 0  
+}
+
+set testfile "pr11465"
+set srcfile ${testfile}.S
+set executable ${testfile}.x
+set binfile ${objdir}/${subdir}/${executable}
+
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" object {}] != "" } {
+    return -1
+}
+
+clean_restart $executable
+
+# Test delayed physname computations
+gdb_test "p N::c.C" { = {void \(N::C \*, void \(\*\)\(N::C\)\)}.*}
Index: testsuite/gdb.dwarf2/pr11465.S
===================================================================
RCS file: testsuite/gdb.dwarf2/pr11465.S
diff -N testsuite/gdb.dwarf2/pr11465.S
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.dwarf2/pr11465.S	11 May 2010 20:46:22 -0000
@@ -0,0 +1,355 @@
+/* Copyright 2010 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* Compiled from:
+
+    namespace N
+    {
+      class C
+      {
+      public:
+        typedef void (*t) (C);
+        C (t) {}
+      };
+      typedef C::t u;
+      u f;
+      C c (f);
+    };
+
+    int
+    main ()
+    {
+      return 0;
+    }
+*/
+
+	.text
+_ZN1N1cE:	
+	.section	.debug_info
+d:
+	.long	.Ldebug_info_end - 1f /* Length of CU info */
+1:
+	.2byte	0x2		/* DWARF version number */
+	.long	.Ldebug_abbrev0	/* Abbrev offset */
+	.byte	0x4		/* Pointer size */
+dieb:	.uleb128 0x1		/* DW_TAG_compile_unit */
+	.long	.LASF4		/* DW_AT_producer */
+	.byte	0x4		/* DW_AT_language */
+	.long	.LASF5		/* DW_AT_name */
+	.long	.LASF6		/* DW_AT_comp_dir */
+	.long	0x0		/* DW_AT_low_pc */
+	.long	0x0		/* DW_AT_high_pc */
+	.long	0x0		/* DW_AT_entry_pc */
+die29:	.uleb128 0x2		/* DW_TAG_namespace */
+	.string	"N"		/* DW_AT_name */
+die32:	.uleb128 0x3		/* DW_TAG_class_type */
+	.string	"C"		/* DW_AT_name */
+	.byte	0x1		/* DW_AT_declaration */
+die36:	.uleb128 0x4		/* DW_TAG_typedef */
+	.string	"u"		/* DW_AT_name */
+	.long	die7e-d		/* DW_AT_type */
+die3f:	.uleb128 0x5		/* DW_TAG_variable */
+	.string	"f"		/* DW_AT_name */
+	.long	.LASF0		/* DW_AT_MIPS_linkage_name */
+	.long	die36-d		/* DW_AT_type */
+	.byte	0x1		/* DW_AT_external */
+	.byte	0x1		/* DW_AT_declaration */
+die4e:	.uleb128 0x5		/* DW_TAG_variable */
+	.string	"c"		/* DW_AT_name */
+	.long	.LASF1		/* DW_AT_MIPS_linkage_name */
+	.long	die5e-d		/* DW_AT_type */
+	.byte	0x1		/* DW_AT_external */
+	.byte	0x1		/* DW_AT_declaration */
+	.byte	0x0
+die5e:	.uleb128 0x6		/* DW_TAG_class_type */
+	.long	die32-d		/* DW_AT_specification */
+	.byte	0x1		/* DW_AT_byte_size */
+die6a:	.uleb128 0x7		/* DW_TAG_subprogram */
+	.byte	0x1		/* DW_AT_external */
+	.string	"C"		/* DW_AT_name */
+	.byte	0x1		/* DW_AT_declaration */
+die71:	.uleb128 0x8		/* DW_TAG_formal_parameter */
+	.long	die8f-d		/* DW_AT_type */
+	.byte	0x1		/* DW_AT_artificial */
+die77:	.uleb128 0x9		/* DW_TAG_formal_parameter */
+	.long	die7e-d		/* DW_AT_type */
+	.byte	0x0
+	.byte	0x0
+die7e:	.uleb128 0xa		/* DW_TAG_pointer_type */
+	.byte	0x4		/* DW_AT_byte_size */
+	.long	die84-d		/* DW_AT_type */
+die84:	.uleb128 0xb		/* DW_TAG_subroutine_type */
+die89:	.uleb128 0x9		/* DW_TAG_formal_parameter */
+	.long	die5e-d		/* DW_AT_type */
+	.byte	0x0
+die8f:	.uleb128 0xa		/* DW_TAG_pointer_type */
+	.byte	0x4		/* DW_AT_byte_size */
+	.long	die5e-d		/* DW_AT_type */
+die95:	.uleb128 0xc		/* DW_TAG_subprogram */
+	.long	die6a-d		/* DW_AT_specification */
+	.byte	0x2		/* DW_AT_inline */
+die9f:	.uleb128 0xd		/* DW_TAG_formal_parameter */
+	.long	.LASF7		/* DW_AT_name */
+	.long	dieaf-d		/* DW_AT_type */
+	.byte	0x1		/* DW_AT_artificial */
+diea9:	.uleb128 0x9		/* DW_TAG_formal_parameter */
+	.long	die7e-d		/* DW_AT_type */
+	.byte	0x0
+dieaf:	.uleb128 0xe		/* DW_TAG_const_type */
+	.long	die8f-d		/* DW_AT_type */
+dieb4:	.uleb128 0xf		/* DW_TAG_subprogram */
+	.long	die95-d		/* DW_AT_abstract_origin */
+	.long	_ZN1N1cE	/* DW_AT_low_pc */
+	.long	_ZN1N1cE	/* DW_AT_high_pc */
+diec9:	.uleb128 0x10		/* DW_TAG_subprogram */
+	.long	die9f-d		/* DW_AT_abstract_origin */
+	.byte	2f-1f		/* DW_AT_location */
+1:
+	.byte	0x50		/* DW_OP_reg0 */
+2:
+died1:	.uleb128 0x10		/* DW_TAG_formal_parameter */
+	.long	diea9-d		/* DW_AT_abstract_origin */
+	.byte	2f-1f		/* DW_AT_location */
+1:
+	.byte	0x51		/* DW_OP_reg1 */
+2:
+	.byte	0x0
+dieda:	.uleb128 0x11		/* DW_TAG_subprogram */
+	.byte	0x1		/* DW_AT_external */
+	.long	.LASF8		/* DW_AT_name */
+	.long	dief2-d		/* DW_AT_type */
+	.long	_ZN1N1cE	/* DW_AT_low_pc */
+	.long	_ZN1N1cE	/* DW_AT_high_pc */
+dief2:	.uleb128 0x12		/* DW_TAG_base_type */
+	.byte	0x4		/* DW_AT_byte_size */
+	.byte	0x5		/* DW_AT_encoding */
+	.string	"int"		/* DW_AT_name */
+die149:	.uleb128 0x16		/* DW_TAG_variable */
+	.long	die4e-d		/* DW_AT_specification */
+	.byte	0x5		/* DW_AT_location */
+	.byte	0x3
+	.long	_ZN1N1cE
+	.byte	0x0
+.Ldebug_info_end:
+	.section	.debug_abbrev
+.Ldebug_abbrev0:
+	.uleb128 0x1		/* abbrev code*/
+	.uleb128 0x11		/* DW_TAG_compile_unit */
+	.byte	0x1		/* DW_children_yes */
+	.uleb128 0x25		/* DW_AT_producer*/
+	.uleb128 0xe		/* DW_FORM_strp */
+	.uleb128 0x13		/* DW_AT_language */
+	.uleb128 0xb		/* DW_FORM_data1 */
+	.uleb128 0x3		/* DW_AT_name */
+	.uleb128 0xe		/* DW_FORM_strp */
+	.uleb128 0x1b		/* DW_AT_comp_dir */
+	.uleb128 0xe		/* DW_FORM_strp */
+	.uleb128 0x11		/* DW_AT_low_pc */
+	.uleb128 0x1		/* DW_FORM_addr */
+	.uleb128 0x12		/* DW_AT_high_pc */
+	.uleb128 0x1		/* DW_FORM_addr */
+	.uleb128 0x52		/* DW_AT_entry_pc */
+	.uleb128 0x1		/* DW_FORM_addr */
+	.byte	0x0
+	.byte	0x0
+	.uleb128 0x2		/* abbrev code */
+	.uleb128 0x39		/* DW_TAG_namespace */
+	.byte	0x1		/* DW_children_yes */
+	.uleb128 0x3		/* DW_AT_name */
+	.uleb128 0x8		/* DW_FORM_string */
+	.byte	0x0
+	.byte	0x0
+	.uleb128 0x3		/* abbrev code */
+	.uleb128 0x2		/* DW_TAG_class_type */
+	.byte	0x0		/* DW_has_children_no */
+	.uleb128 0x3		/* DW_AT_name */
+	.uleb128 0x8		/* DW_FORM_string */
+	.uleb128 0x3c		/* DW_AT_declaration */
+	.uleb128 0xc		/* DW_FORM_flag */
+	.byte	0x0
+	.byte	0x0
+	.uleb128 0x4		/* abbrev code */
+	.uleb128 0x16		/* DW_TAG_typedef */
+	.byte	0x0		/* DW_has_children_no */
+	.uleb128 0x3		/* DW_AT_name */
+	.uleb128 0x8		/* DW_FORM_string */
+	.uleb128 0x49		/* DW_AT_type */
+	.uleb128 0x13		/* DW_FORM_ref4 */
+	.byte	0x0
+	.byte	0x0
+	.uleb128 0x5		/* abbrev code */
+	.uleb128 0x34		/* DW_TAG_variable */
+	.byte	0x0		/* DW_has_children_no */
+	.uleb128 0x3		/* DW_AT_name */
+	.uleb128 0x8		/* DW_FORM_string */
+	.uleb128 0x2007		/* DW_AT_MIPS_linkage_name */
+	.uleb128 0xe		/* DW_FORM_strp */
+	.uleb128 0x49		/* DW_AT_TYPE */
+	.uleb128 0x13		/* DW_FORM_ref4 */
+	.uleb128 0x3f		/* DW_AT_external */
+	.uleb128 0xc		/* DW_FORM_flag */
+	.uleb128 0x3c		/* DW_AT_declaration */
+	.uleb128 0xc		/* DW_FORM_flag */
+	.byte	0x0
+	.byte	0x0
+	.uleb128 0x6		/* abbrev code */
+	.uleb128 0x2		/* DW_TAG_class_type */
+	.byte	0x1		/* DW_has_children_yes */
+	.uleb128 0x47		/* DW_AT_specification */
+	.uleb128 0x13		/* DW_FORM_ref4 */
+	.uleb128 0xb		/* DW_AT_byte_size */
+	.uleb128 0xb		/* DW_FORM_data1 */
+	.byte	0x0
+	.byte	0x0
+	.uleb128 0x7		/* abbrev code */
+	.uleb128 0x2e		/* DW_TAG_subprogra */
+	.byte	0x1		/* DW_has_children_yes */
+	.uleb128 0x3f		/* DW_AT_external */
+	.uleb128 0xc		/* DW_FORM_flag */
+	.uleb128 0x3		/* DW_AT_name */
+	.uleb128 0x8		/* DW_FORM_string */
+	.uleb128 0x3c		/* DW_AT_declaration */
+	.uleb128 0xc		/* DW_FORM_flag */
+	.byte	0x0
+	.byte	0x0
+	.uleb128 0x8		/* abbrev code */
+	.uleb128 0x5		/* DW_TAG_formal_parameter */
+	.byte	0x0		/* DW_has_children_no */
+	.uleb128 0x49		/* DW_AT_type */
+	.uleb128 0x13		/* DW_FORM_ref4 */
+	.uleb128 0x34		/* DW_AT_artificial */
+	.uleb128 0xc		/* DW_FORM_flag */
+	.byte	0x0
+	.byte	0x0
+	.uleb128 0x9		/* abbrev code */
+	.uleb128 0x5		/* DW_TAG_formal_parameter */
+	.byte	0x0		/* DW_has_children_no */
+	.uleb128 0x49		/* DW_AT_type */
+	.uleb128 0x13		/* DW_FORM_ref4 */
+	.byte	0x0
+	.byte	0x0
+	.uleb128 0xa		/* abbrev code */
+	.uleb128 0xf		/* DW_TAG_pointer_type */
+	.byte	0x0		/* DW_has_children_no */
+	.uleb128 0xb		/* DW_AT_byte_size */
+	.uleb128 0xb		/* DW_FORM_data1 */
+	.uleb128 0x49		/* DW_AT_type */
+	.uleb128 0x13		/* DW_FORM_ref4 */
+	.byte	0x0
+	.byte	0x0
+	.uleb128 0xb		/* abbrev code */
+	.uleb128 0x15		/* DW_TAG_subroutine_type */
+	.byte	0x1		/* DW_has_children_yes */
+	.byte	0x0
+	.byte	0x0
+	.uleb128 0xc		/* abbrev code */
+	.uleb128 0x2e		/* DW_TAG_subprogram */
+	.byte	0x1		/* DW_has_children_yes */
+	.uleb128 0x47		/* DW_AT_specification */
+	.uleb128 0x13		/* DW_FORM_ref4 */
+	.uleb128 0x20		/* DW_AT_inline */
+	.uleb128 0xb		/* DW_FORM_data1 */
+	.byte	0x0
+	.byte	0x0
+	.uleb128 0xd		/* abbrev code */
+	.uleb128 0x5		/* DW_TAG_formal_parameter */
+	.byte	0x0		/* DW_has_children_no */
+	.uleb128 0x3		/* DW_AT_name */
+	.uleb128 0xe		/* DW_FORM_strp */
+	.uleb128 0x49		/* DW_AT_type */
+	.uleb128 0x13		/* DW_FORM_ref4 */
+	.uleb128 0x34		/* DW_AT_artificial */
+	.uleb128 0xc		/* DW_FORM_flag */
+	.byte	0x0
+	.byte	0x0
+	.uleb128 0xe		/* abbrev code */
+	.uleb128 0x26		/* DW_TAG_const_type */
+	.byte	0x0		/* DW_has_children_no */
+	.uleb128 0x49		/* DW_AT_type */
+	.uleb128 0x13		/* DW_FORM_ref4 */
+	.byte	0x0
+	.byte	0x0
+	.uleb128 0xf		/* abbrev code */
+	.uleb128 0x2e		/* DW_TAG_subprogram */
+	.byte	0x1		/* DW_has_children_yes */
+	.uleb128 0x31		/* DW_AT_abstract_origin */
+	.uleb128 0x13		/* DW_FORM_ref4 */
+	.uleb128 0x11		/* DW_AT_low_pc */
+	.uleb128 0x1		/* DW_FORM_addr */
+	.uleb128 0x12		/* DW_AT_high_pc */
+	.uleb128 0x1		/* DW_FORM_addr */
+	.byte	0x0
+	.byte	0x0
+	.uleb128 0x10		/* abbrev code */
+	.uleb128 0x5		/* DW_TAG_formal_parameter */
+	.byte	0x0		/* DW_has_children_no */
+	.uleb128 0x31		/* DW_AT_abstract_origin */
+	.uleb128 0x13		/* DW_FORM_ref4 */
+	.uleb128 0x2		/* DW_AT_location */
+	.uleb128 0xa		/* DW_FORM_block1 */
+	.byte	0x0
+	.byte	0x0
+	.uleb128 0x11		/* abbrev code */
+	.uleb128 0x2e		/* DW_TAG_subprogram */
+	.byte	0x0		/* DW_has_children_no */
+	.uleb128 0x3f		/* DW_AT_external */
+	.uleb128 0xc		/* DW_FORM_flag */
+	.uleb128 0x3		/* DW_AT_name */
+	.uleb128 0xe		/* DW_FORM_strp */
+	.uleb128 0x49		/* DW_AT_type */
+	.uleb128 0x13		/* DW_FORM_ref4 */
+	.uleb128 0x11		/* DW_AT_low_pc */
+	.uleb128 0x1		/* DW_FORM_addr */
+	.uleb128 0x12		/* DW_AT_high_pc */
+	.uleb128 0x1		/* DW_FORM_addr */
+	.byte	0x0
+	.byte	0x0
+	.uleb128 0x12		/* abbrev code */
+	.uleb128 0x24		/* DW_TAG_base_type */
+	.byte	0x0		/* DW_has_children_no */
+	.uleb128 0xb		/* DW_AT_byte_size */
+	.uleb128 0xb		/* DW_FORM_data1 */
+	.uleb128 0x3e		/* DW_AT_encoding */
+	.uleb128 0xb		/* DW_FORM_data1 */
+	.uleb128 0x3		/* DW_AT_name */
+	.uleb128 0x8		/* DW_FORM_string */
+	.byte	0x0
+	.byte	0x0
+	.uleb128 0x16		/* abbrev code */
+	.uleb128 0x34		/* DW_TAG_variable */
+	.byte	0x0		/* DW_has_children_no */
+	.uleb128 0x47		/* DW_AT_specification */
+	.uleb128 0x13		/* DW_FORM_ref4 */
+	.uleb128 0x2		/* DW_AT_location */
+	.uleb128 0xa		/* DW_FORM_block1 */
+	.byte	0x0
+	.byte	0x0
+	.byte	0x0
+	.section	.debug_str
+.LASF0:
+	.string	"_ZN1N1fE"
+.LASF7:
+	.string	"this"
+.LASF6:
+	.string	""
+.LASF8:
+	.string	"main"
+.LASF1:
+	.string	"_ZN1N1cE"
+.LASF5:
+	.string	"pr11465.cc"
+.LASF4:
+	.string	"GNU C++ 4.4.2"
+	.ident	"GCC: (GNU) 4.4.2"

[-- Attachment #3: obstack-leak.patch --]
[-- Type: text/plain, Size: 531 bytes --]

--- dwarf2read.c.orig	2010-05-11 13:46:27.922551500 -0700
+++ dwarf2read.c	2010-05-11 13:46:32.198710619 -0700
@@ -5179,6 +5179,11 @@ read_structure_type (struct die_info *di
 	  if (die->tag == DW_TAG_structure_type
 	      || die->tag == DW_TAG_class_type)
 	    TYPE_NAME (type) = TYPE_TAG_NAME (type);
+
+	  /* dwarf2_full_name might have already finished building the DIE's
+	     type.  If so, there is no need to continue.  */
+	  if (get_die_type (die, cu) != NULL)
+	    return get_die_type (die, cu);
 	}
       else
 	{

  reply	other threads:[~2010-05-11 21:18 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-04-20 20:23 Keith Seitz
2010-04-21  6:38 ` Jan Kratochvil
2010-04-23 23:04   ` Tom Tromey
2010-04-23 23:03 ` Tom Tromey
2010-04-23 23:34   ` Keith Seitz
2010-04-26 18:38     ` Tom Tromey
2010-05-11 21:18       ` Keith Seitz [this message]
2010-06-04 22:37         ` Tom Tromey
2010-04-25 10:33 ` Jan Kratochvil

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4BE9C9A0.2030605@redhat.com \
    --to=keiths@redhat.com \
    --cc=gdb-patches@sourceware.org \
    --cc=tromey@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).