gdb crash when printing C++ class

Kris Warkentin
2004-12-10T20:00:59Z

Some background:

I'm using Intel's icc compiler with Dinkum C++ headers. I have a
feeling that there is something wrong with the way the debug info is
being generated but I want to understand the issue a bit better before I
send it off to them.

In gnuv3_baseclass_offset there is a section of code described by this
comment:

/* We're now looking for the cur_base_offset'th entry (negative index)
in the vcall_and_vbase_offsets array. We used to cast the object to
its TYPE_VPTR_BASETYPE, and reference the vtable as TYPE_VPTR_FIELDNO;
however, that cast can not be done without calling baseclass_offset
again
if the TYPE_VPTR_BASETYPE is a virtual base class, as described in the
v3 C++ ABI Section 2.4.I.2.b. Fortunately the ABI guarantees that the
vtable pointer will be located at the beginning of the object, so
we can
bypass the casting. Verify that the TYPE_VPTR_FIELDNO is in fact
at the
start of whichever baseclass it resides in, as a sanity measure - iff
we have debugging information for that baseclass. */

vbasetype = TYPE_VPTR_BASETYPE (type);
if (TYPE_VPTR_FIELDNO (vbasetype) < 0)
fill_in_vptr_fieldno (vbasetype);

When I try to print an ostream variable, gdb crashes because vbasetype
is dereferenced when type->main_type->vptr_basetype is null. In fact,
TYPE_VPTR_FIELDNO(type) is -1 so as one of my tests, I tried calling
fill_in_vptr_fieldno(type) but that didn't fill it in.

As a workaround to prevent the crash, I just return -1 if
TYPE_VPTR_BASETYPE(type) is null and then I get something like this:

10 ostream foo;
(gdb) p foo
$1 = {
<std::basic_ios<char, std::char_traits<char> >> = <invalid address>,
members of std::ostream:
_vptr.basic_ostream<char, std::char_traits<char> > = void
}

Using gcc with very similar headers, I get much nicer output:

10 ostream foo;
(gdb) p foo
$6 = {
<std::basic_ios<char, std::char_traits<char> >> = {
<> = {<No data fields>},
members of std::basic_ios<char, std::char_traits<char> >:
_Mystrbuf = 0x0,
_Tiestr = 0x0,
_Fillch = 32 ' '
},
members of std::ostream:
_vptr.basic_ostream = 0x804f38c
}

Where was the vptr_basetype set up in the first place? Since type
claims to have a baseclass, logically the baseclass pointer shouldn't be
void so I'm assuming it just didn't get filled in somewhere. Can anyone
give me any hints on how to determine if Intel's debug info is off?

cheers,

Kris