From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 6737 invoked by alias); 27 Nov 2001 06:05:35 -0000 Mailing-List: contact gdb-patches-help@sourceware.cygnus.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 6714 invoked from network); 27 Nov 2001 06:05:30 -0000 Received: from unknown (HELO www.cgsoftware.com) (208.155.65.221) by hostedprojects.ges.redhat.com with SMTP; 27 Nov 2001 06:05:30 -0000 Received: from localhost (localhost [127.0.0.1]) by www.cgsoftware.com (8.9.3/8.9.3) with ESMTP id BAA08266; Tue, 27 Nov 2001 01:05:22 -0500 Date: Wed, 14 Nov 2001 00:15:00 -0000 From: Daniel Berlin To: Daniel Jacobowitz cc: Jim Blandy , Subject: Re: [RFA/c++] Fix printing classes with virtual base classes In-Reply-To: <20011127003659.A3965@nevyn.them.org> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII X-SW-Source: 2001-11/txt/msg00268.txt.bz2 Message-ID: <20011114001500.owSudccVxY0RLdqeXqGaC2p0a7X3xvTmJRDqZ-wIgO0@z> On Tue, 27 Nov 2001, Daniel Jacobowitz wrote: > On Mon, Nov 26, 2001 at 11:39:34PM -0500, Jim Blandy wrote: > > > > I'm with you on VALUE_OFFSET and VALUE_EMBEDDED_OFFSET. I'm pretty > > sure VALUE_OFFSET can be eliminated from GDB entirely, with some minor > > changes to the representation of subvalues of registers and > > convenience variables. > > I am exceedingly tempted to do this. > > > Can you explain exactly what TYPE_VPTR_FIELDNO means, and how it works > > in heavily derived classes? What I think you're basically doing there > > is taking the address of the field indicated by TYPE_VPTR_FIELDNO, > > casting that to a void *, and then casting that to the `struct > > gdb_gnu_v3_abi_vtable' type. I have this vague memory that maybe > > using TYPE_VPTR_FIELDNO correctly would fix that. > > I certainly can't explain it :) This code mostly mystifies me. It's taking advantage of g++ magic. I didn't add it, and have wanted to rid us of it for years. It's evil. It's a a field that g++ uses internally to track where the virtual function table is. If you want to see how fragile C++ support is in gdb, change the vfield name in gcc/cp/cp-tree.h and watch what happens. While you are there, notice that they don't use $ to begin it because it confuses gdb (bad), and that it actually won't match the string we test against, depending on what the assembler supports in terms of label names (It might be __vptr_a instead of _vptr.a). Cute, no? > It seems that the vptr for a given class is always a field of the class, Yes, it has to be, g++ generates them. However, be aware that they may not always be correct at all times during execution. I see comments like this in the g++ code /* If this class uses a different vtable than its primary base then when we will need to initialize our vptr after the base class constructor runs. */ Giving me the impression that it can be very dangerous to rely on them at all times in gdb. GCC knows when it's safe to use them, because it's generating the code. We don't. > and may actually overlap where the vptr for its first virtual base > class. It's going to depend on a number of factors. > TYPE_VPTR_FIELDNO tells us where it is. For example, in GCC > 2.x, this code: > > class Foo > { > int bar; > public: > virtual int thug() { return 1; } > }; > > class Foo2 > { > int bar2; > }; > > class Baz : public Foo2, public Foo { > int baz; > public: > virtual int thugs() { return 1; } > }; > > will cause vptr_fieldno for Baz to be 1, indicating its vptr is stored > in memory at the beginning of field 1. > > Gnu v2 code handles this by casting the Baz to a Foo, at which point > magic happens, and somehow the vptr is visible. This suggests that my > fix is not the best way of doing it, and I should be using > TYPE_VPTR_BASETYPE somehow instead. I may need to think some more. > > Upon further reflection, TYPE_VPTR_FIELDNO is supposed to be a field > index in TYPE_VPTR_BASETYPE. Yes. > Interesting. I think there's something > wrong here; more comments tomorrow. Wouldn't surprise me a bit. > > > I wonder if that dereferencing code could be simplified with a > > judicious use of `lookup_pointer_type (vtable_type)' and > > `value_deref'... > > I suppose it would read simpler if I took a value_addr () and cast a > bit. But magic happens in value casting that I don't want to happen.