1) g++ emits classes in DWARF with the DW_TAG_structure_type rather than the DW_TAG_class_type which is suggested in the DWARF V3 specification. This makes it hard for a debugger to show the type name correctly since it can't tell whether the class was _really_ introduced by the class or struct keywords. 2) g++ does not emit any debug information for the vtable pointer in classes with virtual functions. It would be much nicer if this information were emitted (tagged with AT_artificial), since it's often very useful to be able to see the vtable pointer while debugging, as that's how one can work out which class an object _actually_ is when one is looking at a base class pointer. Release: 3.1 Environment: System: Linux pc4 2.4.18 #1 Tue Apr 2 10:17:01 BST 2002 i686 unknown Architecture: i686 host: i686-pc-linux-gnu build: i686-pc-linux-gnu target: i686-pc-linux-gnu configured with: /home1/GNU/gcc-3.1/configure How-To-Repeat: Using code like this #define class_body(classname) \ { \ char * classname##_data; \ public: \ classname () { classname##_data = #classname " data"; } \ virtual char * get_##classname##_data () { return classname##_data; } \ } class A class_body (A); class B class_body (B); class foo: virtual public A, public B class_body (foo); int main (int argc, char **argv) { foo f00; int i = 1; } Compile it and use readelf to look at the dwarf. One can then observe 1) <1><cb>: Abbrev Number: 7 (DW_TAG_structure_type) DW_AT_sibling : <1b3> DW_AT_name : foo DW_AT_byte_size : 20 DW_AT_decl_file : 1 DW_AT_decl_line : 12 DW_AT_containing_type: <2e1> So "foo" is a "struct", not a "class". 2) Eliding the member functions, the contents of class foo are <1><cb>: Abbrev Number: 7 (DW_TAG_structure_type) DW_AT_sibling : <1b3> DW_AT_name : foo DW_AT_byte_size : 20 DW_AT_decl_file : 1 DW_AT_decl_line : 12 DW_AT_containing_type: <2e1> <2><db>: Abbrev Number: 8 (DW_TAG_inheritance) DW_AT_type : <227> DW_AT_data_member_location: 6 byte block: 12 6 3c 1c 6 22 (DW_OP_dup; DW_OP_deref; DW_OP_lit12; DW_OP_minus; DW_OP_deref; DW_OP_plus; ) DW_AT_virtuality : 1 (virtual) DW_AT_accessibility: 1 (public) <2><e9>: Abbrev Number: 9 (DW_TAG_inheritance) DW_AT_type : <2e1> DW_AT_data_member_location: 2 byte block: 23 0 (DW_OP_plus_uconst: 0; ) DW_AT_accessibility: 1 (public) <2><f2>: Abbrev Number: 10 (DW_TAG_member) DW_AT_name : foo_data DW_AT_decl_file : 1 DW_AT_decl_line : 12 DW_AT_type : <bd> DW_AT_data_member_location: 2 byte block: 23 8 (DW_OP_plus_uconst: 8; ) DW_AT_accessibility: 3 (private) So there is no information about the vtable pointer.
From: Daniel Jacobowitz <drow@mvista.com> To: jcownie@etnus.com Cc: gcc-gnats@gcc.gnu.org Subject: Re: c++/7081: DWARF enhancements for C++ Date: Thu, 20 Jun 2002 12:04:59 -0400 On Thu, Jun 20, 2002 at 10:13:22AM +0100, jcownie@etnus.com wrote: > > >Number: 7081 > >Category: c++ > >Synopsis: DWARF enhancements for C++ > >Confidential: no > >Severity: non-critical > >Priority: medium > >Responsible: unassigned > >State: open > >Class: change-request > >Submitter-Id: net > >Arrival-Date: Thu Jun 20 02:16:04 PDT 2002 > >Closed-Date: > >Last-Modified: > >Originator: James Cownie > >Release: 3.1 > >Organization: > Etnus LLC > >Environment: > System: Linux pc4 2.4.18 #1 Tue Apr 2 10:17:01 BST 2002 i686 unknown > Architecture: i686 > > > host: i686-pc-linux-gnu > build: i686-pc-linux-gnu > target: i686-pc-linux-gnu > configured with: /home1/GNU/gcc-3.1/configure > >Description: > 1) g++ emits classes in DWARF with the DW_TAG_structure_type rather > than the DW_TAG_class_type which is suggested in the DWARF V3 > specification. This makes it hard for a debugger to show the type > name correctly since it can't tell whether the class was _really_ > introduced by the class or struct keywords. This one's true, but... > 2) g++ does not emit any debug information for the vtable pointer in > classes with virtual functions. It would be much nicer if this > information were emitted (tagged with AT_artificial), since it's > often very useful to be able to see the vtable pointer while > debugging, as that's how one can work out which class an object > _actually_ is when one is looking at a base class pointer. This one isn't really necessary. The ABI specifies where the vtable pointer will be, and GDB is quite capable of using that knowledge to identify the runtime type. I believe even 'whatis' will do this for you. Whichever debugger you're using must have an understanding of the binary's ABI to debug C++ anyway... -- Daniel Jacobowitz Carnegie Mellon University MontaVista Software Debian GNU/Linux Developer
From: James Cownie <jcownie@etnus.com> To: gcc-gnats@gcc.gnu.org Cc: Subject: Re: c++/7081: DWARF enhancements for C++ Date: Thu, 20 Jun 2002 17:36:01 +0100 > This one isn't really necessary. The ABI specifies where the vtable > pointer will be, and GDB is quite capable of using that knowledge to > identify the runtime type. I believe even 'whatis' will do this for > you. Whichever debugger you're using must have an understanding of the > binary's ABI to debug C++ anyway... Requiring that the debugger know this from the ABI (rather than being told it by the compiler) is exactly why it takes a long time for debuggers to catch up when the compiler ABI is changed :-( -- Jim James Cownie <jcownie@etnus.com> Etnus, LLC. +44 117 9071438 http://www.etnus.com
Hello, can you confirm what the current status of this report is? Particularly, are the proposed enhancements still missing from gcc 3.3 and/or gcc mainline? Thanks, Dara
Subject: Re: DWARF enhancements for C++ > can you confirm what the current status of this report is? > Particularly, are the proposed enhancements still missing from gcc 3.3 > and/or gcc mainline? Thanks, GCC 3.3 still emits DW_TAG_structure_type when DW_TAG_class should be used. I don't have a mainline gcc to check, but if you do it should be trivial to do. Daniel's comment suggests that the second issue (vtable information) isn't going to get fixed. I think that's a pity, because replicating the class layout algorithm in the debugger seems unnecessarily complex to me (after all, the same argument would say that there's no need to output offsets for class members since they can be generated from the ABI too). Having the same piece of code in the debugger and the compiler leads to the possibility of actually having a _slightly different_ piece of code in each place with concomitant bugs, and means that when the ABI changes (as it did between GCC 2.x and GCC 3.x) the change has to occur in both places. (Yes, I know, it's _right_ now and isn't ever going to change again :-) Whatever, fixing the tag would be worthwhile even if you don't want to emit information about the vtable pointer. -- Jim James Cownie <jcownie@etnus.com> Etnus, LLC. +44 117 9071438 http://www.etnus.com
It is in 3.3 but no one has checked the mainline yet.
Present in mainline also. I'm now inclined to agree with the submitter that both should be fixed.
While i'll fix the first, i don't have the info to fix the second, and until their is a DWARF3 standard way of describing this, or an extension is proposed, i plan on closing this bug as fixed, and let him file a second bug. This should have been two bugs anyway. The questions that need to be answered include: 1. What exactly do you want in terms of info about the vtable pointer? The location? The way to get at each element of the vtable? What? 2. This is not externally visible, or programmer created, info. It's completely internal to the ABI. It should *not* be described as a member variable or a member function of the class. Thus, it needs a new tag. Otherwise, we'd have to fudge the name to be something like "vtable", which will cause people unfamiliar with the internals of C++ to ask us where this "vtable" member is coming from in their debugger. In reality, it should be a DW_TAG_vtable or something, that is a child of the class, and contains attributes like DW_AT_location telling you the location of the vtable, and probably some child describing how to get each element as a dwarf3 function.
There was a patch posted here: http://gcc.gnu.org/ml/gcc-patches/2003-06/msg01748.html This was partly OKed, and then the thread died out while discussing how to best implement the C++ FE part of the patch. I'm just including this info here for reference.
I won't get back to this for a while
Mine
Subject: Bug 7081 Author: aoliva Date: Sat Dec 15 20:19:23 2007 New Revision: 130960 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=130960 Log: gcc/ChangeLog: PR debug/7081 * dwarf2out.c (dwarf_tag_name): Synchronize with dwarf2.h. (is_type_die): Cover interface types. (class_or_namespace_scope_p): Cover interface and class types. (record_type_tag): New. (gen_inlined_structure_type_die): Use it. (gen_struct_or_union_type_die): Likewise. (prune_unused_types_walk): Cover interface types. * langhooks.h (classify_record): New enum. (classify_record): New member in struct langhooks_for_types. * langhooks-def.h (LANG_HOOKS_CLASSIFY_RECORD): New. (LANGHOOKS_FOR_TYPES_INITIALIZER): Adjust. gcc/cp/ChangeLog: PR debug/7081 * cp-lang.c (cp_classify_record): New. (LANG_HOOKS_CLASSIFY_RECORD): Override. gcc/java/ChangeLog: PR debug/7081 * lang.c (java_classify_record): New. (LANG_HOOKS_CLASSIFY_RECORD): Override. Modified: trunk/gcc/ChangeLog trunk/gcc/cp/ChangeLog trunk/gcc/cp/cp-lang.c trunk/gcc/dwarf2out.c trunk/gcc/java/ChangeLog trunk/gcc/java/lang.c trunk/gcc/langhooks-def.h trunk/gcc/langhooks.h
1) is now fixed. I wish I'd had time to get to 2), but my time slot for this is over for the time being, so I'll leave this up for grabs.
Please make this Bug CLOSED as the point 1 has been fixed by Alexandre Oliva and the point 2 is already filed as PR debug/11208.
Part fixed, part refiled.