* gcc HEAD dwarf-2, synthetic methods no longer public, gdb confused
@ 2004-07-04 11:19 Michael Elizabeth Chastain
2004-07-04 14:52 ` Daniel Jacobowitz
0 siblings, 1 reply; 6+ messages in thread
From: Michael Elizabeth Chastain @ 2004-07-04 11:19 UTC (permalink / raw)
To: gdb
Here's my next problem with gcc HEAD -gdwarf-2. I suspect this is a bug
in gdb rather than gcc.
I've got a test program with a class, Alpha, that has a
compiler-synthesized assignment operator. That is, Alpha does not
declare or define an operator=, so the C++ compiler has to generate
one itself.
With the old gcc HEAD, the dwarf-2 info looks like this:
<2><f6b>: Abbrev Number: 21 (DW_TAG_subprogram)
DW_AT_sibling : <f98>
DW_AT_external : 1
DW_AT_name : (indirect string, offset: 0x9a3): operator=
DW_AT_MIPS_linkage_name: _ZN5AlphaaSERKS_
DW_AT_type : <fd1>
DW_AT_artificial : 1
DW_AT_declaration : 1
With the new gcc HEAD, the dwarf-2 info looks like this:
<2><f6b>: Abbrev Number: 21 (DW_TAG_subprogram)
DW_AT_sibling : <f86>
DW_AT_name : (indirect string, offset: 0x999): operator=
DW_AT_type : <fbd>
DW_AT_artificial : 1
DW_AT_declaration : 1
The difference is that DW_AT_external and DW_AT_MIPS_linkage_name
have gone away.
I narrowed this down to this one large patch:
2004-06-21 Mark Mitchell <mark@codesourcery.com>
...
* method.c (use_thunk): Use start_preparsed_function.
(synthesize_method): Likewise.
(implicitly_declare_fn): Build FUNCTION_DECLs, not declarators.
...
The difference is in implicitly_declare_fn. The old gcc HEAD
built a tree node with TREE_PUBLIC set, and the new gcc HEAD
does not. This might be an accidental change in the middle of
the big declarator change.
When gdb sees the new debug info with no DW_AT_external and no
DW_AT_MIPS_linkage_name, it gets a little strange with the type
information.
# gdb HEAD 2004-06-29
# gcc HEAD 2004-06-22 07:10:00 UTC
(gdb) ptype Alpha
type = class Alpha {
private:
int a_;
Empty empty_;
public:
Alpha(void);
}
# gdb HEAD 2004-06-29
# gcc HEAD 2004-06-22 07:20:00 UTC
(gdb) ptype Alpha
type = void (Alpha * const, const Alpha &)
Interestingly, this does not affect stabs+. It does affect dwarf-2.
Also, 'ptype class Alpha' works; it's only 'ptype Alpha' that is broken.
I can't find anything in TC++PL about the scope of synthesized methods.
But it seems reasonable to me that they no longer have DW_AT_external
and a DW_AT_MIPS_linkage_name.
I haven't looked inside dwarf2read.c yet. Somehow the change in debug
info is causing it to associate the name 'Alpha' with the synthesized
copy ctor rather than with the class. operator= has the changed debug
info, but gdb thinks that 'Alpha' is associated with the synthesized
copy ctor. Something strange is happening in the dwarf-2 reader.
This causes a FAIL in class2.exp on the "print (B *) abp" test, because
gdb thinks that "B" is not the name of s class. It probably causes some
of the other FAIL's I have here as well.
So my questions are:
... is this good dwarf-2 info?
... if so, can we fix the dwarf-2 reader to handle it?
... if not, i will file a gcc pr
Michael C
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: gcc HEAD dwarf-2, synthetic methods no longer public, gdb confused
2004-07-04 11:19 gcc HEAD dwarf-2, synthetic methods no longer public, gdb confused Michael Elizabeth Chastain
@ 2004-07-04 14:52 ` Daniel Jacobowitz
2004-07-04 19:03 ` Mark Mitchell
2004-07-04 19:42 ` Mark Mitchell
0 siblings, 2 replies; 6+ messages in thread
From: Daniel Jacobowitz @ 2004-07-04 14:52 UTC (permalink / raw)
To: Michael Elizabeth Chastain, Mark Mitchell; +Cc: gdb
On Sun, Jul 04, 2004 at 07:19:19AM -0400, Michael Chastain wrote:
> Here's my next problem with gcc HEAD -gdwarf-2. I suspect this is a bug
> in gdb rather than gcc.
>
> I've got a test program with a class, Alpha, that has a
> compiler-synthesized assignment operator. That is, Alpha does not
> declare or define an operator=, so the C++ compiler has to generate
> one itself.
>
> With the old gcc HEAD, the dwarf-2 info looks like this:
>
> <2><f6b>: Abbrev Number: 21 (DW_TAG_subprogram)
> DW_AT_sibling : <f98>
> DW_AT_external : 1
> DW_AT_name : (indirect string, offset: 0x9a3): operator=
> DW_AT_MIPS_linkage_name: _ZN5AlphaaSERKS_
> DW_AT_type : <fd1>
> DW_AT_artificial : 1
> DW_AT_declaration : 1
>
> With the new gcc HEAD, the dwarf-2 info looks like this:
>
> <2><f6b>: Abbrev Number: 21 (DW_TAG_subprogram)
> DW_AT_sibling : <f86>
> DW_AT_name : (indirect string, offset: 0x999): operator=
> DW_AT_type : <fbd>
> DW_AT_artificial : 1
> DW_AT_declaration : 1
>
> The difference is that DW_AT_external and DW_AT_MIPS_linkage_name
> have gone away.
Is the method code emitted beforehand? How about afterwards? I'm
assuming that it is emitted in both cases. Is it marked .globl before
and after?
> I narrowed this down to this one large patch:
>
> 2004-06-21 Mark Mitchell <mark@codesourcery.com>
>
> ...
> * method.c (use_thunk): Use start_preparsed_function.
> (synthesize_method): Likewise.
> (implicitly_declare_fn): Build FUNCTION_DECLs, not declarators.
> ...
>
> The difference is in implicitly_declare_fn. The old gcc HEAD
> built a tree node with TREE_PUBLIC set, and the new gcc HEAD
> does not. This might be an accidental change in the middle of
> the big declarator change.
This we'd have to ask Mark about :) CC'd.
> When gdb sees the new debug info with no DW_AT_external and no
> DW_AT_MIPS_linkage_name, it gets a little strange with the type
> information.
>
> # gdb HEAD 2004-06-29
> # gcc HEAD 2004-06-22 07:10:00 UTC
> (gdb) ptype Alpha
> type = class Alpha {
> private:
> int a_;
> Empty empty_;
>
> public:
> Alpha(void);
> }
>
> # gdb HEAD 2004-06-29
> # gcc HEAD 2004-06-22 07:20:00 UTC
> (gdb) ptype Alpha
> type = void (Alpha * const, const Alpha &)
>
> Interestingly, this does not affect stabs+. It does affect dwarf-2.
> Also, 'ptype class Alpha' works; it's only 'ptype Alpha' that is broken.
This is a longstanding bug; it just seems to happen sometimes. Probably
the order we parse something has changed. DW_AT_MIPS_linkage_name
should die anyway, but GDB currently still requires it.
> ... is this good dwarf-2 info?
Maybe. The change in DW_AT_external, at least, is probably bad.
> ... if so, can we fix the dwarf-2 reader to handle it?
Probably not easily. It depends what caused the class/function bug.
> ... if not, i will file a gcc pr
--
Daniel Jacobowitz
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: gcc HEAD dwarf-2, synthetic methods no longer public, gdb confused
2004-07-04 14:52 ` Daniel Jacobowitz
@ 2004-07-04 19:03 ` Mark Mitchell
2004-07-04 19:42 ` Mark Mitchell
1 sibling, 0 replies; 6+ messages in thread
From: Mark Mitchell @ 2004-07-04 19:03 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: Michael Elizabeth Chastain, gdb
Daniel Jacobowitz wrote:
>
>>The difference is in implicitly_declare_fn. The old gcc HEAD
>>built a tree node with TREE_PUBLIC set, and the new gcc HEAD
>>does not. This might be an accidental change in the middle of
>>the big declarator change.
>>
>>
>
>This we'd have to ask Mark about :) CC'd.
>
It's an unintentional change. I'm testing a patch as we speak.
Thanks,
--
Mark Mitchell
CodeSourcery, LLC
(916) 791-8304
mark@codesourcery.com
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: gcc HEAD dwarf-2, synthetic methods no longer public, gdb confused
2004-07-04 14:52 ` Daniel Jacobowitz
2004-07-04 19:03 ` Mark Mitchell
@ 2004-07-04 19:42 ` Mark Mitchell
1 sibling, 0 replies; 6+ messages in thread
From: Mark Mitchell @ 2004-07-04 19:42 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: Michael Elizabeth Chastain, gdb
[-- Attachment #1: Type: text/plain, Size: 1562 bytes --]
Daniel Jacobowitz wrote:
>On Sun, Jul 04, 2004 at 07:19:19AM -0400, Michael Chastain wrote:
>
>
>>Here's my next problem with gcc HEAD -gdwarf-2. I suspect this is a bug
>>in gdb rather than gcc.
>>
>>I've got a test program with a class, Alpha, that has a
>>compiler-synthesized assignment operator. That is, Alpha does not
>>declare or define an operator=, so the C++ compiler has to generate
>>one itself.
>>
>>With the old gcc HEAD, the dwarf-2 info looks like this:
>>
>> <2><f6b>: Abbrev Number: 21 (DW_TAG_subprogram)
>> DW_AT_sibling : <f98>
>> DW_AT_external : 1
>> DW_AT_name : (indirect string, offset: 0x9a3): operator=
>> DW_AT_MIPS_linkage_name: _ZN5AlphaaSERKS_
>> DW_AT_type : <fd1>
>> DW_AT_artificial : 1
>> DW_AT_declaration : 1
>>
>>With the new gcc HEAD, the dwarf-2 info looks like this:
>>
>> <2><f6b>: Abbrev Number: 21 (DW_TAG_subprogram)
>> DW_AT_sibling : <f86>
>> DW_AT_name : (indirect string, offset: 0x999): operator=
>> DW_AT_type : <fbd>
>> DW_AT_artificial : 1
>> DW_AT_declaration : 1
>>
>>The difference is that DW_AT_external and DW_AT_MIPS_linkage_name
>>have gone away.
>>
>>
>
>Is the method code emitted beforehand? How about afterwards? I'm
>assuming that it is emitted in both cases. Is it marked .globl before
>and after?
>
This patch should restore the behavior before my patch.
Tested on x86_64-unknown-linux-gnu, applied on the mainline.
--
Mark Mitchell
CodeSourcery, LLC
(916) 791-8304
mark@codesourcery.com
[-- Attachment #2: diffs --]
[-- Type: text/plain, Size: 924 bytes --]
2004-07-04 Mark Mitchell <mark@codesourcery.com>
* method.c (implicitly_declare_fn): Set linkage of generated
functions.
Index: method.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/method.c,v
retrieving revision 1.292
diff -c -5 -p -r1.292 method.c
*** method.c 2 Jul 2004 01:15:42 -0000 1.292
--- method.c 4 Jul 2004 19:40:40 -0000
*************** implicitly_declare_fn (special_function_
*** 1016,1025 ****
--- 1016,1026 ----
}
grokclassfn (type, fn, kind == sfk_destructor ? DTOR_FLAG : NO_SPECIAL,
TYPE_UNQUALIFIED);
grok_special_member_properties (fn);
+ TREE_PUBLIC (fn) = !decl_function_context (TYPE_MAIN_DECL (type));
cp_finish_decl (fn, /*init=*/NULL_TREE, /*asmspec_tree=*/NULL_TREE,
/*flags=*/LOOKUP_ONLYCONVERTING);
DECL_IN_AGGR_P (fn) = 1;
DECL_ARTIFICIAL (fn) = 1;
DECL_NOT_REALLY_EXTERN (fn) = 1;
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: gcc HEAD dwarf-2, synthetic methods no longer public, gdb confused
@ 2004-07-05 23:45 Michael Elizabeth Chastain
0 siblings, 0 replies; 6+ messages in thread
From: Michael Elizabeth Chastain @ 2004-07-05 23:45 UTC (permalink / raw)
To: drow, mark; +Cc: gdb, mec.gnu
mark> This patch should restore the behavior before my patch.
mark> Tested on x86_64-unknown-linux-gnu, applied on the mainline.
It works for me. Thanks!
Michael C
===
2004-07-04 Mark Mitchell <mark@codesourcery.com>
* method.c (implicitly_declare_fn): Set linkage of generated
functions.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: gcc HEAD dwarf-2, synthetic methods no longer public, gdb confused
@ 2004-07-04 19:01 Michael Elizabeth Chastain
0 siblings, 0 replies; 6+ messages in thread
From: Michael Elizabeth Chastain @ 2004-07-04 19:01 UTC (permalink / raw)
To: drow, mark, mec.gnu; +Cc: gdb
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 <stdio.h>
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;
}
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2004-07-05 23:45 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-07-04 11:19 gcc HEAD dwarf-2, synthetic methods no longer public, gdb confused Michael Elizabeth Chastain
2004-07-04 14:52 ` Daniel Jacobowitz
2004-07-04 19:03 ` Mark Mitchell
2004-07-04 19:42 ` Mark Mitchell
2004-07-04 19:01 Michael Elizabeth Chastain
2004-07-05 23:45 Michael Elizabeth Chastain
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox