From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 16757 invoked by alias); 21 May 2010 09:33:15 -0000 Received: (qmail 16736 invoked by uid 22791); 21 May 2010 09:33:12 -0000 X-SWARE-Spam-Status: No, hits=-5.6 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_HI,SPF_HELO_PASS,TW_BJ,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 21 May 2010 09:33:07 +0000 Received: from int-mx05.intmail.prod.int.phx2.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.18]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o4L9Wr2o021182 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 21 May 2010 05:32:53 -0400 Received: from host0.dyn.jankratochvil.net (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx05.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o4L9Wooi021271 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Fri, 21 May 2010 05:32:52 -0400 Received: from host0.dyn.jankratochvil.net (localhost [127.0.0.1]) by host0.dyn.jankratochvil.net (8.14.4/8.14.4) with ESMTP id o4L9Woc7005326; Fri, 21 May 2010 11:32:50 +0200 Received: (from jkratoch@localhost) by host0.dyn.jankratochvil.net (8.14.4/8.14.4/Submit) id o4L9Wnps005325; Fri, 21 May 2010 11:32:49 +0200 Date: Fri, 21 May 2010 12:18:00 -0000 From: Jan Kratochvil To: Joel Brobecker Cc: gdb-patches@sourceware.org, Keith Seitz Subject: Re: [patch] Fix duplicate types for single DIE Message-ID: <20100521093249.GA4719@host0.dyn.jankratochvil.net> References: <20100513115029.GA27341@host0.dyn.jankratochvil.net> <20100520233131.GN3019@adacore.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20100520233131.GN3019@adacore.com> User-Agent: Mutt/1.5.20 (2009-08-17) X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2010-05/txt/msg00478.txt.bz2 On Fri, 21 May 2010 01:31:31 +0200, Joel Brobecker wrote: > > Tom Tromey may not agree with new internal_error as expressed in [...] > This is a situation where we can recover without much hassle by just > allocating a new slot, so I'd just emit a complaint, and allow the > user to continue debugging. OK, that looks better, changed. > There's something I can seem to be able to understand: Why does > set_descriptive_type need to be called after set_die_type? I mean, > from a conceptual point of view, it sort of makes sense. But I can't > see how in practice changing the call order makes any difference... Created there a new comment at set_die_type for some general rules of reading in DIEs/TYPEs and their inter-referencing. I see it was missing there. Therefore I find it more simple to just follow some paradigm than to think whether it is safe to violate it in that specific case. Moreover I was not sure about this Ada descriptive types myself (which you have made clear now). Also the order does not matter IMO, code efficiency is the same. I can remove these descriptive_type changes if you think so. Thanks, Jan 2010-05-21 Jan Kratochvil * dwarf2read.c (read_structure_type): Move set_descriptive_type after set_die_type. (read_array_type): Remove type initialization. Recheck get_die_type after initial die_type. Move set_die_type before set_descriptive_type. (read_set_type): New variable domain_type. Recheck get_die_type after initial die_type. Move attr initialization later. (read_tag_pointer_type, read_tag_reference_type): New variable target_type. Recheck get_die_type after initial die_type. (read_tag_ptr_to_member_type): Recheck get_die_type after initial die_type and die_containing_type. (read_tag_const_type, read_tag_volatile_type, read_subroutine_type): Recheck get_die_type after initial die_type. (read_subrange_type): Recheck get_die_type after initial die_type. Move set_die_type before set_descriptive_type. (set_die_type): Extend the function comment. Call complaint if DIE has some type already set. --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -5125,13 +5125,14 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu) on incomplete types. */ TYPE_STUB (type) = 1; - set_descriptive_type (type, die, cu); - /* We need to add the type field to the die immediately so we don't infinitely recurse when dealing with pointers to the structure type within the structure itself. */ set_die_type (die, type, cu); + /* set_die_type should be already done. */ + set_descriptive_type (type, die, cu); + if (die->child != NULL && ! die_is_declaration (die, cu)) { struct field_info fi; @@ -5420,7 +5421,7 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu) { struct objfile *objfile = cu->objfile; struct die_info *child_die; - struct type *type = NULL; + struct type *type; struct type *element_type, *range_type, *index_type; struct type **range_types = NULL; struct attribute *attr; @@ -5430,6 +5431,11 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu) element_type = die_type (die, cu); + /* The die_type call above may have already set the type for this DIE. */ + type = get_die_type (die, cu); + if (type) + return type; + /* Irix 6.2 native cc creates array types without children for arrays with unspecified length. */ if (die->child == NULL) @@ -5498,12 +5504,15 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu) if (name) TYPE_NAME (type) = name; + /* Install the type in the die. */ + set_die_type (die, type, cu); + + /* set_die_type should be already done. */ set_descriptive_type (type, die, cu); do_cleanups (back_to); - /* Install the type in the die. */ - return set_die_type (die, type, cu); + return type; } static enum dwarf_array_dim_ordering @@ -5546,11 +5555,22 @@ read_array_order (struct die_info *die, struct dwarf2_cu *cu) static struct type * read_set_type (struct die_info *die, struct dwarf2_cu *cu) { - struct type *set_type = create_set_type (NULL, die_type (die, cu)); - struct attribute *attr = dwarf2_attr (die, DW_AT_byte_size, cu); + struct type *domain_type, *set_type; + struct attribute *attr; + domain_type = die_type (die, cu); + + /* The die_type call above may have already set the type for this DIE. */ + set_type = get_die_type (die, cu); + if (set_type) + return set_type; + + set_type = create_set_type (NULL, domain_type); + + attr = dwarf2_attr (die, DW_AT_byte_size, cu); if (attr) TYPE_LENGTH (set_type) = DW_UNSND (attr); + return set_die_type (die, set_type, cu); } @@ -5749,8 +5769,16 @@ read_tag_pointer_type (struct die_info *die, struct dwarf2_cu *cu) struct attribute *attr_byte_size; struct attribute *attr_address_class; int byte_size, addr_class; + struct type *target_type; + + target_type = die_type (die, cu); + + /* The die_type call above may have already set the type for this DIE. */ + type = get_die_type (die, cu); + if (type) + return type; - type = lookup_pointer_type (die_type (die, cu)); + type = lookup_pointer_type (target_type); attr_byte_size = dwarf2_attr (die, DW_AT_byte_size, cu); if (attr_byte_size) @@ -5806,6 +5834,11 @@ read_tag_ptr_to_member_type (struct die_info *die, struct dwarf2_cu *cu) to_type = die_type (die, cu); domain = die_containing_type (die, cu); + /* The calls above may have already set the type for this DIE. */ + type = get_die_type (die, cu); + if (type) + return type; + if (TYPE_CODE (check_typedef (to_type)) == TYPE_CODE_METHOD) type = lookup_methodptr_type (to_type); else @@ -5821,10 +5854,17 @@ static struct type * read_tag_reference_type (struct die_info *die, struct dwarf2_cu *cu) { struct comp_unit_head *cu_header = &cu->header; - struct type *type; + struct type *type, *target_type; struct attribute *attr; - type = lookup_reference_type (die_type (die, cu)); + target_type = die_type (die, cu); + + /* The die_type call above may have already set the type for this DIE. */ + type = get_die_type (die, cu); + if (type) + return type; + + type = lookup_reference_type (target_type); attr = dwarf2_attr (die, DW_AT_byte_size, cu); if (attr) { @@ -5843,6 +5883,12 @@ read_tag_const_type (struct die_info *die, struct dwarf2_cu *cu) struct type *base_type, *cv_type; base_type = die_type (die, cu); + + /* The die_type call above may have already set the type for this DIE. */ + cv_type = get_die_type (die, cu); + if (cv_type) + return cv_type; + cv_type = make_cv_type (1, TYPE_VOLATILE (base_type), base_type, 0); return set_die_type (die, cv_type, cu); } @@ -5853,6 +5899,12 @@ read_tag_volatile_type (struct die_info *die, struct dwarf2_cu *cu) struct type *base_type, *cv_type; base_type = die_type (die, cu); + + /* The die_type call above may have already set the type for this DIE. */ + cv_type = get_die_type (die, cu); + if (cv_type) + return cv_type; + cv_type = make_cv_type (TYPE_CONST (base_type), 1, base_type, 0); return set_die_type (die, cv_type, cu); } @@ -5917,6 +5969,12 @@ read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu) struct attribute *attr; type = die_type (die, cu); + + /* The die_type call above may have already set the type for this DIE. */ + ftype = get_die_type (die, cu); + if (ftype) + return ftype; + ftype = lookup_function_type (type); /* All functions in C++, Pascal and Java have prototypes. */ @@ -6129,6 +6187,12 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu) LONGEST negative_mask; base_type = die_type (die, cu); + + /* The die_type call above may have already set the type for this DIE. */ + range_type = get_die_type (die, cu); + if (range_type) + return range_type; + if (TYPE_CODE (base_type) == TYPE_CODE_VOID) { complaint (&symfile_complaints, @@ -6196,9 +6260,12 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu) if (attr) TYPE_LENGTH (range_type) = DW_UNSND (attr); + set_die_type (die, range_type, cu); + + /* set_die_type should be already done. */ set_descriptive_type (range_type, die, cu); - return set_die_type (die, range_type, cu); + return range_type; } static struct type * @@ -11984,7 +12051,22 @@ offset_and_type_eq (const void *item_lhs, const void *item_rhs) } /* Set the type associated with DIE to TYPE. Save it in CU's hash - table if necessary. For convenience, return TYPE. */ + table if necessary. For convenience, return TYPE. + + The DIEs reading must have careful ordering to: + * Not cause infite loops trying to read in DIEs as a prerequisite for + reading current DIE. + * Not trying to dereference contents of still incompletely read in types + while reading in other DIEs. + * Enable referencing still incompletely read in types just by a pointer to + the type without accessing its fields. + + Therefore caller should follow these rules: + * Try to fetch any prerequisite types we may need to build this DIE type + before building the type and calling set_die_type. + * After building typer call set_die_type for current DIE as soon as + possible before fetching more types to complete the current type. + * Make the type as complete as possible before fetching more types. */ static struct type * set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu) @@ -12022,6 +12104,10 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu) ofs.type = type; slot = (struct dwarf2_offset_and_type **) htab_find_slot_with_hash (cu->type_hash, &ofs, ofs.offset, INSERT); + if (*slot) + complaint (&symfile_complaints, + _("A problem internal to GDB: DIE 0x%x has type already set"), + die->offset); *slot = obstack_alloc (&cu->objfile->objfile_obstack, sizeof (**slot)); **slot = ofs; return type;