gdb crash when printing C++ class

Kris Warkentin kewarken@qnx.com
Fri Dec 10 20:00:00 GMT 2004


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



More information about the Gdb mailing list