Summary: | Problem with nested namespaces | ||
---|---|---|---|
Product: | gdb | Reporter: | klaas.gadeyne |
Component: | c++ | Assignee: | Not yet assigned to anyone <unassigned> |
Status: | RESOLVED FIXED | ||
Severity: | normal | CC: | carlton, drow, gdb-prs, tromey |
Priority: | P3 | ||
Version: | unknown | ||
Target Milestone: | --- | ||
Host: | Target: | ||
Build: | Last reconfirmed: |
Description
klaas.gadeyne
2004-03-23 16:48:01 UTC
From: Daniel Jacobowitz <drow@false.org> To: klaas.gadeyne@mech.kuleuven.ac.be Cc: gdb-gnats@sources.redhat.com Subject: Re: c++/1593: Problem with nested namespaces Date: Tue, 23 Mar 2004 11:59:57 -0500 On Tue, Mar 23, 2004 at 04:44:06PM -0000, klaas.gadeyne@mech.kuleuven.ac.be wrote: > namespace WRAPPED > { > class Foo : public BASE::Foo > { > public: > Foo() : BASE::Foo(){}; > virtual ~Foo(){}; > }; > } > So mywrapped is now reported to be empty, where I expected to see > something like > > 1: mywrapped = {<Foo> = {<No data fields>}, <No data fields>} > The problem does not exist when: > - The code is compiled with g++ 2.95.4 > - All code is inlined in 1 file (yes, that's why there are 3 files above :) > - I omit the member function method and put the constructor implementation > in the cpp file. > - When Foo in namespace WRAPPED is renamed into Boo Yes. Unfortunately, this isn't a bug in GDB - there just isn't enough information in the object files. If you try a prerelease snapshot of GCC 3.4, I believe it will work OK. The basic problem is that by explicitly providing a constructor and destructor, you've suppressed the implicit operator=. In GCC 3.x (but not in 2.95.4, to explain the first bullet above), this is the only default method whose full mangled name appears in the debug information - constructors and destructors don't. We use it to infer the correct name of the type. The other things just tweak the search order. We're looking up the type Foo by name and finding the wrong one - we don't realize it's really WRAPPED::Foo. -- Daniel Jacobowitz MontaVista Software Debian GNU/Linux Developer From: David Carlton <carlton@kealia.com> To: Daniel Jacobowitz <drow@false.org> Cc: GNATS Filer <gdb-gnats@sources.redhat.com> Subject: Re: c++/1593: Problem with nested namespaces Date: Tue, 23 Mar 2004 09:31:23 -0800 On 23 Mar 2004 17:08:02 -0000, Daniel Jacobowitz <drow@false.org> said: > The basic problem is that by explicitly providing a constructor and > destructor, you've suppressed the implicit operator=. Now I'm confused. Looking at the assembly file, you're quite right: there isn't an operator= listed in the class definition. But I think there should be one - a user-defined constructor/destructor doesn't suppress a compiler-defined operator=. So, for example, if you replace his main() by this: int main() { Foo mywrapped; Foo mywrapped2; mywrapped2 = mywrapped; return 0; } then you'll see operator= in the class definition in the debug info. Which suggests to me that GCC (I used Red Hat's 3.2, but it must also be the case for the GCC 3.3 that he used) doesn't emit identical debug info for the definition of the same class in different translation units. Which really sucks, from GDB's point of view. From: Daniel Jacobowitz <drow@false.org> To: David Carlton <carlton@kealia.com> Cc: GNATS Filer <gdb-gnats@sources.redhat.com> Subject: Re: c++/1593: Problem with nested namespaces Date: Tue, 23 Mar 2004 12:46:06 -0500 On Tue, Mar 23, 2004 at 09:31:23AM -0800, David Carlton wrote: > On 23 Mar 2004 17:08:02 -0000, Daniel Jacobowitz <drow@false.org> said: > > > The basic problem is that by explicitly providing a constructor and > > destructor, you've suppressed the implicit operator=. > > Now I'm confused. Looking at the assembly file, you're quite right: > there isn't an operator= listed in the class definition. But I think > there should be one - a user-defined constructor/destructor doesn't > suppress a compiler-defined operator=. So, for example, if you > replace his main() by this: > > int main() > { > Foo mywrapped; > Foo mywrapped2; > > mywrapped2 = mywrapped; > > return 0; > } > > then you'll see operator= in the class definition in the debug info. > > Which suggests to me that GCC (I used Red Hat's 3.2, but it must also > be the case for the GCC 3.3 that he used) doesn't emit identical debug > info for the definition of the same class in different translation > units. Which really sucks, from GDB's point of view. OK, now I'm _really_ confused. I think that I said the wrong thing in the first place, and then both you and I have arranged to see what we expected to see since. In particular: GDB 6.0 goes into an infinite loop GDB 6.1 works as described in the report $1 = {<> = {<No data fields>}, <No data fields>} (gdb) ptype mywrapped type = class WRAPPED::Foo : public Foo { public: void Foo(void); ~Foo(int); } So it's the base type whose name we got wrong. BASE::Foo in wrapper_object.o has an operator= and we infer its name. BASE::Foo in wrapper.o is just a declaration. So it has nothing from which to infer its name, and we lose. If we had DW_TAG_namespace, we would still get the right results. I see the operator= for WRAPPED::Foo with both versions of main(); could you recheck? -- Daniel Jacobowitz MontaVista Software Debian GNU/Linux Developer From: David Carlton <carlton@kealia.com> To: Daniel Jacobowitz <drow@false.org> Cc: GNATS Filer <gdb-gnats@sources.redhat.com> Subject: Re: c++/1593: Problem with nested namespaces Date: Tue, 23 Mar 2004 11:03:12 -0800 On 23 Mar 2004 17:48:01 -0000, Daniel Jacobowitz <drow@false.org> said: > GDB 6.0 goes into an infinite loop > GDB 6.1 works as described in the report > $1 = {<> = {<No data fields>}, <No data fields>} > (gdb) ptype mywrapped > type = class WRAPPED::Foo : public Foo { > public: > void Foo(void); > ~Foo(int); > } > So it's the base type whose name we got wrong. > BASE::Foo in wrapper_object.o has an operator= and we infer its > name. BASE::Foo in wrapper.o is just a declaration. That's what I was missing - I had just assumed that, since there were methods mentioned in the debug info for BASE::Foo, that it was a definition, but it is in fact a declaration. And it's fine for declarations to contain different amounts of information in different translation units, of course. > So it has nothing from which to infer its name, and we lose. > If we had DW_TAG_namespace, we would still get the right results. That should be the case. Though, unfortunately, it isn't so simple; when I used my hacked GCC 3.2 that generates DW_TAG_namespace, things work fine: (gdb) p mywrapped $1 = {<BASE::Foo> = {_vptr.Foo = 0x80496c0}, <No data fields>} But when I use "g++ (GCC) 3.5.0 20040119", we're back to our old behavior: (gdb) p mywrapped $1 = {<> = {<No data fields>}, <No data fields>} I'll have to look into that further. (Hmm: should determine_class_name restore processing_current_prefix if it has to change it? Probably, but looking at the callers, we're currently safe, so that's not the issue here.) With a recent (F11) gcc and CVS head gdb, I get: (gdb) p mywrapped $1 = (WRAPPED::Foo) { <BASE::Foo> = { _vptr.Foo = 0x8048730 }, <No data fields>} This looks correct to me. Given the age of the reported GCC, I am closing this as fixed. |