From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 707 invoked by alias); 28 Mar 2011 09:20:03 -0000 Received: (qmail 564 invoked by uid 22791); 28 Mar 2011 09:20:01 -0000 X-SWARE-Spam-Status: No, hits=-6.2 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_HI,SPF_HELO_PASS,TW_BJ,TW_FN,TW_GD,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; Mon, 28 Mar 2011 09:19:47 +0000 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p2S9Jl7d012163 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Mon, 28 Mar 2011 05:19:47 -0400 Received: from host1.jankratochvil.net (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id p2S9Jj0r015982 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Mon, 28 Mar 2011 05:19:46 -0400 Received: from host1.jankratochvil.net (localhost [127.0.0.1]) by host1.jankratochvil.net (8.14.4/8.14.4) with ESMTP id p2S9Ji6P022288; Mon, 28 Mar 2011 11:19:44 +0200 Received: (from jkratoch@localhost) by host1.jankratochvil.net (8.14.4/8.14.4/Submit) id p2S9JilV022278; Mon, 28 Mar 2011 11:19:44 +0200 Date: Mon, 28 Mar 2011 12:35:00 -0000 From: Jan Kratochvil To: Tom Tromey Cc: gdb-patches@sourceware.org, Dodji Seketeli Subject: Re: [patch] DWARF-3+ DW_AT_accessibility defaults #2 (GCC PR debug/45124) Message-ID: <20110328091943.GA21984@host1.jankratochvil.net> References: <20110321154428.GA3761@host1.jankratochvil.net> <20110322095904.GA29625@host1.jankratochvil.net> <20110322181620.GA21984@host1.jankratochvil.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20110322181620.GA21984@host1.jankratochvil.net> User-Agent: Mutt/1.5.21 (2010-09-15) 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: 2011-03/txt/msg01123.txt.bz2 On Tue, 22 Mar 2011 19:16:20 +0100, Jan Kratochvil wrote: > If GCC 4.6.0 GA still will not produce DW_AT_producer for DW_TAG_type_unit > there will be no way to distinguish what does DW_TAG_type_unit assume as > a default for DW_AT_accessibility. which has happened now with 4.6.0 GA. Posted now: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48229#c5 # It cannot work as GDB often looks up the type without any referrer from # DW_TAG_compile_unit, such as during the `ptype' GDB command. A draft patch # thus has many regressions such as: # -PASS: gdb.base/nofield.exp: ptype struct not_empty # +FAIL: gdb.base/nofield.exp: ptype struct not_empty (GDB internal error) # # This means GDB will have to start full read (like -readnow) of CUs till it # finds some CU referencing the specific type to find its DW_AT_producer. During # scan of .debug_info for GDB partial symbols GDB currently skips over subtrees # of DIEs which reference the type signature for performance reasons, it no # longer can. # # With .gdb_index there is no GDB partial symbols scan but .gdb_index also # indexes types by their name and there is no referrer ever seen during the # `ptype' GDB command. # # So it means performance regression for non-.gdb_index case and a possible new # extension/version of .gdb_index to handle it. So any solution is not easy now. While playing with it one should have: [patch] Fix -readnow for -gdwarf-4 unused type units http://sourceware.org/ml/gdb-patches/2011-03/msg01119.html Thanks, Jan --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -446,6 +446,11 @@ struct dwarf2_per_cu_data /* Data needed by the "quick" functions. */ struct dwarf2_per_cu_quick_data *quick; } v; + + /* Track the .debug_info CUs referring to .debug_types CUs, even + transitively. If unknown it is NULL, otherwise it points to + a .debug_info CU. */ + struct dwarf2_per_cu_data *referrer; }; /* Entry in the signatured_types hash table. */ @@ -2446,8 +2451,22 @@ dw2_expand_all_symtabs (struct objfile *objfile) dw2_setup (objfile); - for (i = 0; i < (dwarf2_per_objfile->n_comp_units - + dwarf2_per_objfile->n_type_comp_units); ++i) + /* N_TYPE_COMP_UNITS - .debug_types CUs - do not have to be read in as each + such PER_CU belongs into one of these cases: + (1) per_cu->referrer == NULL + It is an unused DW_TAG_type_unit which no referrers. Such unit + cannot be read-in even just for a verification by OBJF_READNOW as + producer_is_gxx_lt_4_6 would not know how to read it. + (2) per_cu->referrer->cu == NULL + This DW_TAG_type_unit has been already read it before as a dependency + for some DW_TAG_compile_unit. producer_is_gxx_lt_4_6 would no longer + know how to read it with DW_TAG_compile_unit no longer available. + And also: + (3) per_cu->referrer->cu != NULL + We can read this DW_TAG_type_unit but it would be read in the second + time, there is no need to do so. */ + + for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i) { struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i); @@ -6216,6 +6235,83 @@ dwarf2_record_block_ranges (struct die_info *die, struct block *block, } } +/* Check for GCC PR debug/45124 fix which is not present in any G++ version up + to 4.5.any while it is present already in G++ 4.6.0 - the PR has been fixed + during 4.6.0 experimental. */ + +static int +producer_is_gxx_lt_4_6 (struct dwarf2_cu *cu) +{ + int major, minor; + + if (cu->producer == NULL && cu->per_cu->from_debug_types) + { + struct dwarf2_per_cu_data *referrer; + + /* We may get to a .debug_types CU only through a pointer from + a .debug_info CU. .debug_types CUs without such pointer are skipped + in dw2_expand_all_symtabs. */ + referrer = cu->per_cu->referrer; + gdb_assert (referrer != NULL); + + /* On a second and further referrer the first referrer stored in + referrer may have its CU already freed. But that time + DEBUG_TYPES_TYPE_HASH is used to look up the type and the + .debug_types CU is not read in the second time at all. */ + gdb_assert (referrer->cu != NULL); + + cu = referrer->cu; + } + + if (cu->producer == NULL) + { + /* For unknown compilers expect their behavior is DWARF version + compliant. */ + + return 0; + } + + /* Whitespaces are ignored in both PRODUCER and the format string. */ + if (sscanf (cu->producer, "GNU C++ %d.%d", &major, &minor) != 2) + { + /* For non-GCC compilers expect their behavior is DWARF version + compliant. */ + + return 0; + } + + return major < 4 || (major == 4 && minor < 6); +} + +/* Return the default accessibility type if it is not overriden by + DW_AT_accessibility. */ + +static enum dwarf_access_attribute +dwarf2_default_access_attribute (struct die_info *die, struct dwarf2_cu *cu) +{ + if (cu->header.version < 3 || producer_is_gxx_lt_4_6 (cu)) + { + /* The default DWARF 2 accessibility for members is public, the default + accessibility for inheritance is private. */ + + if (die->tag != DW_TAG_inheritance) + return DW_ACCESS_public; + else + return DW_ACCESS_private; + } + else + { + /* DWARF 3+ defines the default accessibility a different way. The same + rules apply now for DW_TAG_inheritance as for the members and it only + depends on the container kind. */ + + if (die->parent->tag == DW_TAG_class_type) + return DW_ACCESS_private; + else + return DW_ACCESS_public; + } +} + /* Add an aggregate field to the field list. */ static void @@ -6246,23 +6342,19 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die, } fip->nfields++; - /* Handle accessibility and virtuality of field. - The default accessibility for members is public, the default - accessibility for inheritance is private. */ - if (die->tag != DW_TAG_inheritance) - new_field->accessibility = DW_ACCESS_public; - else - new_field->accessibility = DW_ACCESS_private; - new_field->virtuality = DW_VIRTUALITY_none; - attr = dwarf2_attr (die, DW_AT_accessibility, cu); if (attr) new_field->accessibility = DW_UNSND (attr); + else + new_field->accessibility = dwarf2_default_access_attribute (die, cu); if (new_field->accessibility != DW_ACCESS_public) fip->non_public_fields = 1; + attr = dwarf2_attr (die, DW_AT_virtuality, cu); if (attr) new_field->virtuality = DW_UNSND (attr); + else + new_field->virtuality = DW_VIRTUALITY_none; fp = &new_field->field; @@ -6578,6 +6670,7 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die, char *fieldname; struct nextfnfield *new_fnfield; struct type *this_type; + enum dwarf_access_attribute accessibility; if (cu->language == language_ada) error (_("unexpected member function in Ada type")); @@ -6676,16 +6769,17 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die, /* Get accessibility. */ attr = dwarf2_attr (die, DW_AT_accessibility, cu); if (attr) + accessibility = DW_UNSND (attr); + else + accessibility = dwarf2_default_access_attribute (die, cu); + switch (accessibility) { - switch (DW_UNSND (attr)) - { - case DW_ACCESS_private: - fnp->is_private = 1; - break; - case DW_ACCESS_protected: - fnp->is_protected = 1; - break; - } + case DW_ACCESS_private: + fnp->is_private = 1; + break; + case DW_ACCESS_protected: + fnp->is_protected = 1; + break; } /* Check for artificial methods. */ @@ -13254,6 +13348,17 @@ static int maybe_queue_comp_unit (struct dwarf2_cu *this_cu, struct dwarf2_per_cu_data *per_cu) { + /* Try to fill-in referrer for .debug_types CUs. While + THIS_CU->CU may become NULL soon it should be already processed by + producer_is_gxx_lt_4_6 that time. */ + if (per_cu->from_debug_types && per_cu->referrer == NULL) + { + if (!this_cu->per_cu->from_debug_types) + per_cu->referrer = this_cu->per_cu; + else + per_cu->referrer = this_cu->per_cu->referrer; + } + /* We may arrive here during partial symbol reading, if we need full DIEs to process an unusual case (e.g. template arguments). Do not queue PER_CU, just tell our caller to load its DIEs. */