[Converted from Gnats 1465] alpha.cc has a simple base class and a simple derived class. The derived class is never used but its presence is necessary for the bug to happen. "print alpha" works fine, but "print *&alpha" or "print *aap" print garbage values which change every time. See the typescript session. The problem happens with gcc 2.95.3 -gdwarf-2. It does not happen with gcc 2.95.3 -stabs+, gcc 3.3.2 -gdwarf-2, or gcc 3.3.2 -gstabs+. This is a regression versus gdb 6.0. Release: gdb HEAD 2003-09-11 20:00:00 UTC Environment: target = native, host = i686-pc-linux-gnu, osversion = red-hat-8.0 gdb = HEAD 2003-09-11 20:00:00 UTC gcc = 2.95.3 binutils = 2.14 glibc = 2.2.93-5-rh gformat = dwarf-2 glevel = 2 How-To-Repeat: See the typescript in the attachment.
Fix: There is some analysis in the attachment, too. The regression happened with this patch: 2003-09-11 David Carlton <carlton@kealia.com> * gdbtypes.h: Add TYPE_CODE_NAMESPACE. * gdbtypes.c (init_type): Handle TYPE_CODE_NAMESPACE. (recursive_dump_type): Ditto. ... The problem is in gnuv2_value_rtti_type. gnuv2_value_rtti_type calls lookup_typename on the class name, "A", to get the rtti_type. Before the namespace patch, this call to lookup_typename returned a TYPE_CODE_STRUCT. After the namespace patch, this call to lookup_typename returns a TYPE_CODE_NAMESPACE. See the attachment for more details.
From: mec.gnu@mindspring.com (Michael Elizabeth Chastain) To: carlton@kealia.com, gdb-gnats@sources.redhat.com Cc: Subject: Re: gdb/1465 Date: Wed, 26 Nov 2003 16:09:08 -0500 (EST) Here is some more analysis. I figured out about 75% of this bug and then I reached the limits of my symbol table skills. gnuv2_value_rtti_type wants to find the rtti type for the static type "A". So it calls lookup_typename. The objfile for the main executable has one symtab. This symtab has a static block, as usual. This static block has the symbol for "struct A". I want to find this symbol. The namespace symbol for "namespace A" is in some other symbol table. I don't know or care which. I don't want to find this symbol! Here is the call tree for the type lookup: gnuv2_value_rtti_type lookup_typename lookup_symbol lookup_symbol_aux lookup_symbol_aux_local check_field current_language->la_lookup_symbol_nonlocal lookup_namespace_scope lookup_namespace_scope cp_lookup_symbol_namespace cp_lookup_symbol_namespace lookup_symbol_file lookup_symbol_static [1] lookup_symbol_aux_block lookup_block_symbol lookup_symbol_aux_block lookup_block_symbol lookup_symbol_global lookup_symbol_aux_symtabs [2] lookup_block_symbol lookup_symbol_aux_psymtabs lookup_partial_symbol lookup_block_symbol lookup_possible_namespace_symbol [3] lookup_block_symbol lookup_symbol_aux_symtabs [4] lookup_block_symbol lookup_symbol_aux_psymtabs lookup_partial_symbol lookup_block_symbol lookup_primitive_typename It takes a while to grok this tree. You might have to do what I did: start at the place where gnuv2_value_rtti_type calls lookup_typename and write the tree yourself. The key functions here are gnuv2_value_rtti_type, lookup_symbol_aux, and lookup_symbol_file. gnuv2_value_rtti_type specifies block = 0. I think this is the bug. And then gdb goes through all those calls. Point [1] is supposed to find the static symbol. It doesn't match because block == 0 here! Point [2] is part of global symbol lookup. It looks in BLOCK_GLOBAL blocks. It's not supposed to match, and it doesn't. Point [3] is part of the new namespace code. It matches the synthetic symbol for "namespace A". That's where the wrong symbol gets returned to gnu2_value_rtti_type! The last working gdb was gdb HEAD 2003-09-11 19:30:00 UTC. In that gdb, point [3] does not exist, so it doesn't match. With the current gdb, point [3] matches. Point [4] is a catch-all matcher. It looks in all STATIC_BLOCK blocks in all symtabs in all objfiles. The comment says: "not strictly correct, but more useful than an error." In the last working gdb, point [4] picks up the match. The dwarf-2 reader creates these namespace symbols, but the stabs+ reader does not. With gcc 2.95.3 -gstabs+, gdb falls through point [3] without matching and proceeds to point [4], where it finds the right symbol. I think the real problem is the point where gnuv2_value_rtti_type specifies block=0. Conceptually, that looks wrong to me. gdb is looking up a type name and the type name might have different meanings in different scopes. lookup_typename really needs a correct block argument. The problem is: there is no handy block pointer lying around in gnuv2_value_rtti_type, or anywhere in the call stack above it, for that matter. Can someone help me out here? hpacc_value_rtti_type has the same structure, so it probably has the same bug. gnuv3_rtti_type calls lookup_symbol(domain=STRUCT_DOMAIN, block=0). That's why the bug does not happen with gcc v3. When domain==STRUCT_DOMAIN, lookup_symbol_file does not even call lookup_possible_namespace_symbol, so the search at [3] never happens. gnuv3_rtti_type is still flaky because it still specifies an incorrect block, so it still matches at [4] instead of [1]. Another question: v2 searches in VAR_DOMAIN, and v3 searches in STRUCT_DOMAIN. Why the difference? Also, the more I look at lookup_typename, the less I like it. It's called in only a few places. c-exp.y and objc-exp.y use "lookup_signed_typename" and "lookup_unsigned_typename" to parse "signed" and "unsigned" stuff. The only valid uses of that are for primitive type names, and those are going to be very forgiving of the incorrect block scope. And then gnuv2_rtti_type and hpacc_value_rtti_type call lookup_typename, and they are doing it wrong. And that's all the calls to lookup_typename. So my plan is: (1) Change gnuv2_value_rtti_type from lookup_typename to lookup_symbol. (2) Change both gnuv2_value_rtti_type and gnuv3_value_rtti_type to supply a proper block argument to lookup_symbol. I need help with this part. (3) Add some code to both gnuv2_value_rtti_type and gnuv3_value_rtti_type to check the type that they are using. If it's not TYPE_CODE_STRUCT (or similar) then print "rtti type botch". I would rather show the user "rtti type botch" then show the user incorrect data values. (4) Write some test cases for this. Michael C
From: David Carlton <carlton@kealia.com> To: mec.gnu@mindspring.com (Michael Elizabeth Chastain) Cc: gdb-gnats@sources.redhat.com Subject: Re: gdb/1465 Date: Wed, 26 Nov 2003 13:20:16 -0800 On Wed, 26 Nov 2003 16:09:08 -0500 (EST), mec.gnu@mindspring.com (Michael Elizabeth Chastain) said: > gnuv2_value_rtti_type wants to find the rtti type for the static type "A". > So it calls lookup_typename. > The objfile for the main executable has one symtab. > This symtab has a static block, as usual. > This static block has the symbol for "struct A". > I want to find this symbol. Right. But, as I just e-mailed in a separate thread, I think this is part of the problem here - this symbol shouldn't be in a static block, it should be in a global block. And my latest patch awaiting approval, among other things, puts it in a global block. > I think the real problem is the point where gnuv2_value_rtti_type > specifies block=0. Conceptually, that looks wrong to me. gdb is > looking up a type name and the type name might have different > meanings in different scopes. lookup_typename really needs a > correct block argument. Yes, I agree. > The problem is: there is no handy block pointer lying around in > gnuv2_value_rtti_type, or anywhere in the call stack above it, for > that matter. Can someone help me out here? There's always get_selected_block (0), or whatever it's called. But I'm not sure that that will always be the correct thing to do. > Another question: v2 searches in VAR_DOMAIN, and v3 searches in > STRUCT_DOMAIN. Why the difference? Beats me. I think VAR_DOMAIN is better. > (1) Change gnuv2_value_rtti_type from lookup_typename to > lookup_symbol. Yeah. After all, the only difference is that lookup_typename has the primitive type stuff, but that shouldn't come into play for RTTI information. David Carlton carlton@kealia.com
From: mec.gnu@mindspring.com (Michael Elizabeth Chastain) To: carlton@kealia.com, mec.gnu@mindspring.com Cc: gdb-gnats@sources.redhat.com Subject: Re: gdb/1465 Date: Wed, 26 Nov 2003 16:38:08 -0500 (EST) Hi David, > Right. But, as I just e-mailed in a separate thread, I think this is > part of the problem here - this symbol shouldn't be in a static block, > it should be in a global block. And my latest patch awaiting > approval, among other things, puts it in a global block. But what about: int foo () { class A { ... }; } int bar () { class A { ... ... }; } Classes are scoped. Wouldn't you have to do a bunch of work to make sure that the namespace lookup works properly if all the symbols live in global symtabs? dc> There's always get_selected_block (0), or whatever it's called. But dc> I'm not sure that that will always be the correct thing to do. That sounds good. I'll look around there. mec> (1) Change gnuv2_value_rtti_type from lookup_typename to mec> lookup_symbol. dc> Yeah. Okay, that sounds unambiguously good. And it's only for gnuv2 so I can be sure that I'm not breaking something anything else. I'll proceed with a patch for this step then. That will make gdb work better in all the cases where there is only one "struct A" in the program. Michael C
From: David Carlton <carlton@kealia.com> To: mec.gnu@mindspring.com (Michael Elizabeth Chastain) Cc: gdb-gnats@sources.redhat.com Subject: Re: gdb/1465 Date: Wed, 26 Nov 2003 13:55:03 -0800 On 26 Nov 2003 21:48:01 -0000, mec.gnu@mindspring.com (Michael Elizabeth Chastain) said: >> Right. But, as I just e-mailed in a separate thread, I think this is >> part of the problem here - this symbol shouldn't be in a static block, >> it should be in a global block. And my latest patch awaiting >> approval, among other things, puts it in a global block. > But what about: > int foo () > { > class A { ... }; > } > int bar () > { > class A { ... ... }; > } > Classes are scoped. Wouldn't you have to do a bunch of work to > make sure that the namespace lookup works properly if all the > symbols live in global symtabs? Sorry, let me clarify that - I move the C++ class symbols that are currently in the static block to the global block. The above class symbols should be in the blocks that are local to the functions in question - I can't remember offhand if we're putting them in the correct place currently, but, if so, I shouldn't have changed that.
From: mec.gnu@mindspring.com (Michael Elizabeth Chastain) To: carlton@kealia.com Cc: gdb-gnats@sources.redhat.com Subject: Re: gdb/1465 Date: Wed, 26 Nov 2003 20:20:06 -0500 (EST) Hi David, mec> Another question: v2 searches in VAR_DOMAIN, and v3 searches in mec> STRUCT_DOMAIN. Why the difference? dc> Beats me. I think VAR_DOMAIN is better. Okay, I tried it both ways: STRUCT_DOMAIN gcc 2.95.3 -gdwarf-2 works fine gcc 3.3.2 -gdwarf-2 works fine VAR_DOMAIN gcc 2.95.3 -gdwarf-2 finds the namespace symbol gcc 3.3.2 -gdwarf-2 finds some symbol with TYPE_CODE_FUNC ! So I would like to go with STRUCT_DOMAIN. Reasons: gnuv3_rtti_type already does it with STRUCT_DOMAIN so I won't be breaking v3. And I'm pretty sure that STRUCT_DOMAIN will be okay with v2. Is that okay with you? I don't really know the whole philosophy of these class symbols like you do. Michael C
Responsible-Changed-From-To: unassigned->chastain Responsible-Changed-Why: Mine. Muhahaha!
State-Changed-From-To: open->analyzed State-Changed-Why: Analysis is in the audit trail. I'm working on a couple of patches now.
From: David Carlton <carlton@kealia.com> To: mec.gnu@mindspring.com (Michael Elizabeth Chastain) Cc: GNATS Filer <gdb-gnats@sources.redhat.com> Subject: Re: gdb/1465 Date: Mon, 01 Dec 2003 09:05:58 -0800 On 27 Nov 2003 01:28:01 -0000, mec.gnu@mindspring.com (Michael Elizabeth Chastain) said: mec> Another question: v2 searches in VAR_DOMAIN, and v3 searches in mec> STRUCT_DOMAIN. Why the difference? dc> Beats me. I think VAR_DOMAIN is better. > Okay, I tried it both ways: > STRUCT_DOMAIN > gcc 2.95.3 -gdwarf-2 works fine > gcc 3.3.2 -gdwarf-2 works fine > VAR_DOMAIN > gcc 2.95.3 -gdwarf-2 finds the namespace symbol > gcc 3.3.2 -gdwarf-2 finds some symbol with TYPE_CODE_FUNC ! > So I would like to go with STRUCT_DOMAIN. > Reasons: gnuv3_rtti_type already does it with STRUCT_DOMAIN so > I won't be breaking v3. And I'm pretty sure that STRUCT_DOMAIN > will be okay with v2. All right, STRUCT_DOMAIN it is. I would expect the symbols to be in both of them, but if they aren't, I don't have any reason not to go with STRUCT_DOMAIN. David Carlton carlton@kealia.com
From: chastain@sources.redhat.com To: gdb-gnats@sourceware.org Cc: Subject: c++/1465 Date: 5 Dec 2003 04:25:10 -0000 CVSROOT: /cvs/src Module name: src Changes by: chastain@sourceware.org 2003-12-05 04:25:09 Modified files: gdb : ChangeLog cp-support.h cp-support.c gnu-v2-abi.c gnu-v3-abi.c Log message: 2003-12-04 Michael Chastain <mec.gnu@mindspring.com> Partial fix for PR c++/1465. Fix for PR c++/1377. * cp-support.h (cp_lookup_rtti_type): New function. * cp-support.c (cp_lookup_rtti_type): New function. * gnu-v2-abi.c: Update copyright years. (gnuv2_rtti_type): Call cp_lookup_rtti_type. * gnu-v3-abi.c: Update copyright years. (gnuv3_rtti_type): Call cp_lookup_rtti_type. Patches: http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/gdb/ChangeLog.diff?cvsroot=src&r1=1.5084&r2=1.5085 http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/gdb/cp-support.h.diff?cvsroot=src&r1=1.9&r2=1.10 http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/gdb/cp-support.c.diff?cvsroot=src&r1=1.9&r2=1.10 http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/gdb/gnu-v2-abi.c.diff?cvsroot=src&r1=1.13&r2=1.14 http://sources.redhat.com/cgi-bin/cvsweb.cgi/src/gdb/gnu-v3-abi.c.diff?cvsroot=src&r1=1.19&r2=1.20
State-Changed-From-To: analyzed->closed State-Changed-Why: Fixed in the latest spin.