This is the mail archive of the gdb@sourceware.cygnus.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: RTTI working for G++


Jimmy Guo <guo@cup.hp.com> writes:

> Daniel,
> 
> I recently looked into rtti print support and fixed several bugs in that
> area. 

As have I.
>  Also I've created a test case under gdb.hp/gdb.aCC/.  Looks like
> what I changed might work with G++ as well now that you're adding
> support to it.  

Possibly, i have a feeling we fixed the same bugs.
> The fix is against HP WDB source, which is based on
> sourceware's as of 1/10/00, so I'm not ready to submit against
> sourceware's tree yet.  However, one of the fixes was that when print
> object is on, and one wants to print member / methods of the derived
> type, you can now do so. 

See, i didn't consider that a bug, i considered it a lacking
feature. It just wasn't doing the lookup it would need to do, and i've
been too busy to fix it.

> Besides, there're some fixes to handle pointer
> to a derived type and explicit casting of a pointer to a base to a
> derived type. 

This i ran up against. I also handled reference types (By pretending
they were pointers).

> I feel that these fixes will complement yours.  
Most likely you are correct.
I wasn't ready to go all out and make all the symbol readers fill in
the vtable stuff like it does for HP (it's on my list for sometime).
Seeing as how i would have had to do that, as well as differentiate
between HP aCC debug symbols and other forms of debug symbols, with
another flag, i decided for right now to just put the RTTI stuff for
G++ where it was already, the else block of all the "HAS_VTABLE" if
blocks.
I only actually added one more if, in value_rtti_type, right before
the HP specific stuff starts, that says
"if(TYPE_HAS_VTABLE(known_type)) { do hp stuff } else { do g++ stuff}"

That way, i didn't break any of your HP specific stuff.

Did you notice that it's not really fun to use value_nid (damn
flyspell keeps "correcting" the IND to nid, as if "nid" was really a word
either.) in value_rtti_type? value_nid will call the RTTI routine
during it's lazy evaluation, which gets you into a recursive nightmare
if you aren't careful.


> If
> possible I want to send the diffs of the fixes to you to see if that
> would make it into your patch.  Also I can look at your patches as
> well.

I'd be glad to incorporate your fixes into my patch, and i'd
appreciate it if you'd look at mine.
I'll post it to gdb-patches in a few days.

I'm a little confused about the semantics of using_enc/full/top in value_rtti_type.

It seems if i set full to 0, on multiple inheritance, it gets the name
right, but the offset wrong, so you have the right name, and the wrong
values.
If i set full to 1, it gets the name wrong ("suspicious *", which
means it couldn't look it up right), but the values right.
Example of what i mean (when i have bar multiple inheriting 

class foo
{
public:
int a;
};
class foo2
{
public:
int b;
};
class bar:public foo1, public foo2
{
public:
int c;
};

foo *foo1=new bar();

print foo1 (full==1 will give "suspicious *", full==0 will give "bar
*")
print *foo1 (full==1 will give the proper values, full==0 gets the
offset wrong, and thus, prints the wrong values)

Even more convoluted,
print foo1->a (with full==1) will access the wrong memory, even though it had it
right 2 seconds before when it printed the full object.
I know i'm setting top properly in all cases.
I have a feeling i'm not quite grasping the way it lays out in memory
yet.

--Dan

> 
> - Jimmy Guo, guo@cup.hp.com
> 
> On Mon, 13 Mar 2000, Daniel Berlin wrote:
> 
> >Okay, i have RTTI working for g++.
> >Well, all except for multiple inheritance.
> >
> >Scratch that last part, i just made it offset properly if you have >1
> >baseclass, so al is good.
> >
> >If i could have one or two volunteers to make sure it's not just my setup,
> >and that all is well, before i post the patches asking for comments, i'd
> >appreciate it.
> >In any case, let me know what you guys think of it so far.
> >If you look at the output, you'll notice that while for printing, it will
> >print the object as if it was it's derived type, when it comes to
> >accessing members/methods, just like in C++, you can't access the members,
> >unless you specifically cast it to that derived type.
> >
> > For those wondering what the patch will do, check this out:
> >
> >The inheritance on these classes in the example looks like this
> >
> >fred is a base
> >dan and bob both inherit directly from fred.
> >george is another base.
> >george2 inherits from george and bob (public george, public bob)
> >
> >I'll rename them so they make more sense as i work up testcases.
> >
> >But anyway, here's some output:
> >
> >GNU gdb 20000204
> >Copyright 1998 Free Software Foundation, Inc.
> >GDB is free software, covered by the GNU General Public License, and you are
> >welcome to change it and/or distribute copies of it under certain conditions.
> >Type "show copying" to see the conditions.
> >There is absolutely no warranty for GDB.  Type "show warranty" for details.
> >This GDB was configured as "i386-unknown-freebsdelf4.0".
> >Setting up the environment for debugging gdb.
> >.gdbinit:5: Error in sourced command file:
> >No symbol table is loaded.  Use the "file" command.
> >(gdb) file a.out
> >Reading symbols from a.out...done.
> >(gdb) b main
> >Breakpoint 1 at 0x8048918: file a.cc, line 29.
> >(gdb) set print object on
> >(gdb) set print pretty on
> >(gdb) set print vtbl on
> >(gdb) set print array on
> >(gdb) r
> >Starting program: /usr/local/gdb/src/gdb/a.out 
> >
> >Breakpoint 1, 0x8048918 in main () at a.cc:29
> >
> >29	{
> >(gdb) n
> >31		dan=new daniel();
> >(gdb) n
> >32		cout <<typeid(*dan).name()<<endl;
> >(gdb) p dan
> >$1 = (daniel *) 0x8051030
> >(gdb) p dan[0]
> >$2 = (daniel) {
> >  <fred> = {
> >    a = 0, 
> >    _vptr$ = 0x804f390
> >  }, 
> >  members of daniel: 
> >  b = 0
> >}
> >(gdb) ptype dan
> >type = class fred {
> >  public:
> >    int a;
> >
> >    fred & operator=(fred const &);
> >    fred(fred const &);
> >    fred(void);
> >    virtual int ab(void);
> >} *
> >(gdb) p dan[0]->b
> >There is no member or method named b.
> >(gdb) n
> >6daniel
> >33		dan=new bob();
> >(gdb) 
> >34		dan=new george2();
> >(gdb) p dan
> >$3 = (bob *) 0x8051040
> >(gdb) p dan[0]
> >$4 = (bob) {
> >  <fred> = {
> >    a = 0, 
> >    _vptr$ = 0x804f378
> >  }, 
> >  members of bob: 
> >  c = 0
> >}
> >(gdb) p dan[0].c
> >There is no member or method named c.
> >(gdb) n
> >35		dan->a=55;
> >(gdb) p dan[0]
> >$5 = (george2 [incomplete object]) {
> >  <george> = {
> >    d = 0
> >  }, 
> >  <bob> = {
> >    <fred> = {
> >      a = 0, 
> >      _vptr$ = 0x804f360
> >    }, 
> >    members of bob: 
> >    c = 0
> >  }, 
> >  members of george2: 
> >  e = 0
> >}
> >(gdb) l
> >30		fred *dan;
> >31		dan=new daniel();
> >32		cout <<typeid(*dan).name()<<endl;
> >33		dan=new bob();
> >34		dan=new george2();
> >35		dan->a=55;
> >36		cout <<typeid(*dan).name()<<endl;
> >37	}
> >38	
> >(gdb) n
> >36		cout <<typeid(*dan).name()<<endl;
> >(gdb) p dan
> >$7 = (suspicious *) 0x8050064
> >(gdb) p dan[0]
> >$8 = (george2 [incomplete object]) {
> >  <george> = {
> >    d = 0
> >  }, 
> >  <bob> = {
> >    <fred> = {
> >      a = 55, 
> >      _vptr$ = 0x804f360
> >    }, 
> >    members of bob: 
> >    c = 0
> >  }, 
> >  members of george2: 
> >  e = 0
> >}
> >(gdb) c
> >Continuing.
> >7george2
> >
> >Program exited normally.
> >(gdb) q
> >
> >Script done on Mon Mar 13 19:34:51 2000

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]