From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 20248 invoked by alias); 4 Jul 2004 19:01:04 -0000 Mailing-List: contact gdb-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sources.redhat.com Received: (qmail 20239 invoked from network); 4 Jul 2004 19:01:02 -0000 Received: from unknown (HELO smtp10.atl.mindspring.net) (207.69.200.246) by sourceware.org with SMTP; 4 Jul 2004 19:01:02 -0000 Received: from user-119a90a.biz.mindspring.com ([66.149.36.10] helo=berman.michael-chastain.com) by smtp10.atl.mindspring.net with esmtp (Exim 3.33 #1) id 1BhCED-00046G-00; Sun, 04 Jul 2004 15:00:41 -0400 Received: by berman.michael-chastain.com (Postfix, from userid 502) id A16794B104; Sun, 4 Jul 2004 15:00:59 -0400 (EDT) To: drow@false.org, mark@codesourcery.com, mec.gnu@mindspring.com Subject: Re: gcc HEAD dwarf-2, synthetic methods no longer public, gdb confused Cc: gdb@sources.redhat.com Message-Id: <20040704190059.A16794B104@berman.michael-chastain.com> Date: Sun, 04 Jul 2004 19:01:00 -0000 From: mec.gnu@mindspring.com (Michael Elizabeth Chastain) X-SW-Source: 2004-07/txt/msg00025.txt.bz2 drow> Is the method code emitted beforehand? How about afterwards? I'm drow> assuming that it is emitted in both cases. Is it marked .globl before drow> and after? Good question; I forgot to mention this. All of the code is exactly the same before and after. 'diff old.s new.s' says that the differences are only in .debug_info. The synthetic symbols are .weak and not .globl, with both versions of gcc. Here are all the .globl and .weak symbols (run through c++filt): .globl Empty::Empty[not-in-charge]() .globl Empty::Empty[in-charge]() .globl Empty::Empty[not-in-charge](Empty const&) .globl Empty::Empty[in-charge](Empty const&) .globl Empty::operator=(Empty const&) .globl Empty::~Empty [not-in-charge]() .globl Empty::~Empty [in-charge]() .globl Alpha::Alpha[not-in-charge]() .globl Alpha::Alpha[in-charge]() .globl refer(Alpha*) .weak Alpha::operator=(Alpha const&) .weak Alpha::~Alpha [in-charge]() .globl foo() .weak Alpha::Alpha[in-charge](Alpha const&) .globl main class 'Empty' has its own ctor, copy-ctor, assign-op, and dtor. class 'Alpha' has a data member of type 'Empty' and just a ctor, so that gcc synthesizes the 'Alpha' copy-ctor, assign-op, and dtor. The whole source file is appended. Compiled with 'gcc -gdwarf-2 -S' on native i686-pc-linux-gnu. drow> This is a longstanding bug; it just seems to happen sometimes. drow> Probably the order we parse something has changed. drow> DW_AT_MIPS_linkage_name should die anyway, but GDB currently still drow> requires it. Ah, I did some more reading, dwarf2read.c is not as hairy as it looks. But lookup_symbol is seriously complicated. === The .globl/.weak symbols use fully mangled names. Of course they must, for the linker to work! The symbol for the synthetic copy constructor is _ZN5AlphaC1ERKS_, which demangles to 'Alpha::Alpha[in-charge](Alpha const&)'. 'maint symbols' says: # old gcc HEAD [20] t 0x80485e0 _ZN5AlphaC1ERKS_ section .text Alpha::Alpha(Alpha const&) synthetic.cc # new gcc HEAD [20] t 0x80485e0 _ZN5AlphaC1ERKS_ section .text Alpha::Alpha(Alpha const&) synthetic.cc This looks okay to me. It's always been a .weak non-.globl symbol, and it's always had a fully mangled name. === But 'maint psymbols' reveals some quirks in the partial symbols: # old gcc HEAD Partial symtab for source file synthetic.cc (object 0x82f93f4) Read from object file /berman/home/mec.gnu/gcc/pr-synthetic/22-0710.exe (0x82eb730) Global partial symbols: `Alpha', struct domain, type, 0x0 `Alpha', type, 0x0 `Alpha', function, 0x8048450 `Alpha', function, 0x8048470 `Alpha', function, 0x80485e0 `_ZN5AlphaaSERKS_' `Alpha::operator=(Alpha const&)', function, 0x804859c `~Alpha', function, 0x80485ca Static partial symbols: ... # new gcc HEAD Partial symtab for source file synthetic.cc (object 0x82f93b0) Read from object file /berman/home/mec.gnu/gcc/pr-synthetic/22-0720.exe (0x82eb730) Global partial symbols: `Alpha', struct domain, type, 0x0 `Alpha', type, 0x0 `Alpha', function, 0x8048450 `Alpha', function, 0x8048470 Static partial symbols: `operator=', function, 0x804859c `~Alpha', function, 0x80485ca `Alpha', function, 0x80485e0 In gdb's symbol tables, static partial symbols have higher search priority than global partial symbols. With both versions of gcc, the global partial symbols have two psymbols for the types 'class Alpha' and 'Alpha' and then two psymbols for the two copies of the user-supplied ctor Alpha::Alpha. The symbols for the two ctors are lacking DW_AT_MIPS_linkage_name, so they are named 'Alpha' instead of 'Alpha::Alpha[not-in-charge]()' and 'Alpha::Alpha[in-charge]()'. Then there are three synthetic methods: assign-op, copy-ctor, and dtor. With old gcc HEAD, these are DW_AT_external, and they appear in the global partial symbols. With new gcc HEAD, these are not DW_AT_external, and they appear in the static partial symbols. Also, the synthetic assign-op lost its DW_AT_MIPS_linkage_name. The synthetic copy-ctor and synthetic dtor never had DW_AT_MIPS_linkage_name. As it turns out, the synthetic assign-op is not important to this issue, but I saw the difference in 'diff' and thought it was importnat. === gdb has a complicated search order for symbol names. The interesting part of the call tree is: lookup_symbol_file lookup_symbol_static [2] lookup_symbol_aux_block lookup_symbol_global lookup_symbol_aux_symtabs [1] lookup_symbol_aux_psymtabs lookup_possible_namespace_symbol [1] is the point where gdb finds 'Alpha' with old gcc HEAD. It finds the global symbol for the type 'Alpha'. [2] is the point where gdb finds 'Alpha' with new gcc HEAD. It finds the synthetic copy-ctor named 'Alpha' in the static partial symbols, which have higher search priority than global partial symbols. That's why gdb works with old gcc HEAD. All five symbols named 'Alpha' are in the same psymtab and gdb happens to find the right one. With new gcc HEAD, the synthetic ctor is a static psymbol, so it has higher priority. So 'ptype Alpha' finds this symbol and returns the type of this function. === What to do? It would be helpful if gcc emitted DW_AT_MIPS_linkage_name for the synthetic symbols. Mark, can we do this? It would be helpful if gdb were smarter about symbol names for ctor's and copy-ctor's, which have the same name as the class. Right now, we lose if one of those pops up with no DW_AT_MIPS_linkage_name. And I will add a new test program to the test suite for this. === #include class Empty { public: Empty (); Empty (const Empty &); const Empty & operator= (const Empty &); ~Empty (); }; Empty::Empty () { printf ("ctor\n"); } Empty::Empty (const Empty &) { printf ("copy ctor\n"); } const Empty & Empty::operator= (const Empty & e) { printf ("assignment operator\n"); } Empty::~Empty () { printf ("dtor\n"); } class Alpha { public: Alpha (); private: int a_; Empty empty_; }; Alpha::Alpha () : a_ (117) { ; } void refer (Alpha * a) { static Alpha asave; asave = *a; } void foo () { Alpha a1; Alpha a2 (a1); Alpha a3 = a1; refer (&a1); refer (&a2); refer (&a3); return; } int main () { foo (); return 0; }