Bug 14235

Summary: verbose RTTI message polluting traces
Product: gdb Reporter: Michael Meeks <michael.meeks>
Component: pythonAssignee: Not yet assigned to anyone <unassigned>
Status: NEW ---    
Severity: normal CC: andre.poenitz, dan.colascione, jan, mbilal, tromey
Priority: P2    
Version: 7.3   
Target Milestone: ---   
Host: Target:
Build: Last reconfirmed:

Description Michael Meeks 2012-06-14 11:04:52 UTC
We have number of python pretty-printers for LibreOffice to make our component system much more usable and helpful in gdb. Unfortunately this doesn't handle the case where we don't compile the whole project with debugging symbols.

We don't compile the whole project like that due to the time it takes, and the huge size of the result (making the development interation slower) not least with ld / gdb :-)

Anyhow - with partial symbols eg. symbols missing for the libfwklo.so when generating a backtrace from a breakpoint in vcl's

void Window::Show( sal_Bool bVisible, sal_uInt16 nFlags )

method (going through framework at some stage) - I get:

(gdb) bt
#0  Window::Show (this=0x8a7cf28, bVisible=1 '\001', nFlags=0)
at /data/opt/libreoffice/master/vcl/source/window/window.cxx:6180
#1  0xb784d187 in SfxFrame::SfxFrame (this=0x8a7cde0,
i_rContainerWindow=..., i_bHidden=false)
    at /data/opt/libreoffice/master/sfx2/source/view/frame2.cxx:338
#2  0xb784d6f1 in SfxFrame::Create (i_rFrame=warning: RTTI symbol not
found for class 'framework::Frame'
warning: RTTI symbol not found for class 'framework::Frame'
warning: RTTI symbol not found for class 'framework::Frame'
warning: RTTI symbol not found for class 'framework::Frame'

    uno::Reference to {<com::sun::star::lang::XComponent> =
{<com::sun::star::uno::XInterface> = {_vptr.XInterface = 0xb163c4f0},
<No data fields>}, <No data fields>})
at /data/opt/libreoffice/master/sfx2/source/view/frame2.cxx:315

where the:

warning: RTTI symbol not found for class 'framework::Frame'

is quite annoying :-)
Comment 1 Michael Meeks 2012-06-14 11:08:33 UTC
Tom Tromey kindly provided some insight here:

Michael> But is there any way of suppressing that warning thrash for the
Michael> case where it is not enabled ?

There's no way to disable it.
File a feature request in gdb bugzilla if you want that.

I looked into this a little.  The warning here is peculiar.
Despite what it says, gdb is not actually looking for an RTTI symbol.
Instead it is just looking for the debug info for the indicated type.
Comment 2 Michael Meeks 2012-06-14 11:10:36 UTC
I believe the python pretty printers we use are here:

http://cgit.freedesktop.org/libreoffice/core/tree/solenv/gdb/libreoffice/
Comment 3 Jan Kratochvil 2013-01-30 09:28:18 UTC
*** Bug 11171 has been marked as a duplicate of this bug. ***
Comment 4 Jan Kratochvil 2013-01-30 09:47:05 UTC
I have tried to reproduce it with F-17 libreoffice-3.5.7.2-9.fc17.x86_64 without luck.

Even if I remove whole /usr/lib/debug and keep there just:
  /usr/lib/debug/usr/lib64/libreoffice/program/libsfxlo.so.debug
which contains SfxFrame::Create I still get no warning:

(gdb) p i_rFrame
$1 = (const com::sun::star::uno::Reference<com::sun::star::frame::XFrame> &) @0x7fff78e2b490: {<com::sun::star::uno::BaseReference> = {_pInterface = 
    0x7ff01a582740}, <No data fields>}

/usr/share/gdb/auto-load/usr/lib64/libreoffice/ is present.
Comment 5 Andre' 2013-02-12 17:10:30 UTC
The following reproduces the issue for me:

    void unused(const void *first,...) { (void) first; }

    void breakHere() {}

    int main()
    {
        struct BaseClass { virtual ~BaseClass() {} };
        struct DerivedClass : BaseClass {};

        DerivedClass d;
        BaseClass *b1 = &d;
        BaseClass &b2 = d;
        unused(&b1, &b2);

        breakHere();
        return 0;
    }


Compile, start, do

   python print gdb.parse_and_eval("b1")
   python print gdb.parse_and_eval("b2")

The problem goes away if the struct definitions are moved out of main().

gcc (Ubuntu/Linaro 4.7.2-2ubuntu1) 4.7.2
GNU gdb (GDB) 7.5-ubuntu
Comment 6 Michael Meeks 2013-02-13 10:11:08 UTC
Wow thanks so much for creating a test case ! :-)
Comment 7 Tom Tromey 2013-02-13 21:02:04 UTC
(In reply to comment #5)

>    python print gdb.parse_and_eval("b1")
>    python print gdb.parse_and_eval("b2")

These work for me but plain "print" shows the problem:

(gdb) p b1
$1 = (warning: RTTI symbol not found for class 'main::DerivedClass'
warning: RTTI symbol not found for class 'main::DerivedClass'
BaseClass *) 0x7fffffffe340
(gdb) p b2
$2 = (warning: RTTI symbol not found for class 'main::DerivedClass'
warning: RTTI symbol not found for class 'main::DerivedClass'
BaseClass &) @0x7fffffffe340: warning: RTTI symbol not found for class 'main::DerivedClass'
{
  _vptr.BaseClass = 0x4008f0 <vtable for main::DerivedClass+16>
}


Thanks very much for the test case!
We've been wanting an easy reproducer for this for quite a while now.
Comment 8 Tom Tromey 2013-02-15 19:19:02 UTC
First, I wonder whether this reproducer is actually what
is seen in LibreOffice.

Michael, can you say?  The critical part of this reproducer
is that the classes are defined locally in a function.
But, based on the names in the messages in your example,
I would guess that this is not the case for you...


The local class name problem is noted in the source as bug#8570
(the source uses the pre-renumbering PR).  From gnu-v3-abi.c:

  /* Try to look up the class name as a type name.  */
  /* FIXME: chastain/2003-11-26: block=NULL is bogus.  See pr gdb/1465.  */
  run_time_type = cp_lookup_rtti_type (class_name, NULL);
  if (run_time_type == NULL)
    return NULL;

And, indeed, this is bogus.  In the example, a class named "DerivedClass"
is put into the symbol table in one of the blocks making up "main".
However, looking up the vtable symbol yields _ZTVZ4mainE12DerivedClass,
which demangles as "vtable for main::DerivedClass".

Aside from the long, huge project of fixing the symbol tables, one option
might be to notice this situation and enter a second, global symbol for
the type, named "main::DerivedClass".

It isn't completely clear to me that this would work.
For example, could there be 2 symbols with this name in different CUs?
One in a function and one in a namespace?
Comment 9 Tom Tromey 2013-02-15 21:26:08 UTC
(In reply to comment #8)

> It isn't completely clear to me that this would work.
> For example, could there be 2 symbols with this name in different CUs?
> One in a function and one in a namespace?

Due to name mangling differences it is possible to create a file like that.
This compiles and links just fine:


q1.cc:

namespace main {
  struct Z {
    virtual void x();
  };
};

void main::Z::x () { }

main::Z z;

int f() { return 0; }


q2.cc:

extern int f();

int main()
{
  struct Z { virtual ~Z() { } };

  Z z;
  return f();
}
Comment 10 Tom Tromey 2013-02-16 02:29:47 UTC
This also appears to be valid:

void f()
{
  {
    struct Z { virtual ~Z() { } };
    Z zz;
  }
  {
    struct Z { virtual ~Z() { } };
    Z zz;
  }
}

Yielding:

barimba. nm dt.o
00000000000000db T _Z1fv
0000000000000040 r _ZTIZ1fvE1Z
0000000000000050 r _ZTIZ1fvE1Z_0
000000000000006b r _ZTSZ1fvE1Z
0000000000000060 r _ZTSZ1fvE1Z_0
                 U _ZTVN10__cxxabiv117__class_type_infoE
0000000000000020 r _ZTVZ1fvE1Z
0000000000000000 r _ZTVZ1fvE1Z_0
00000000000000c6 t _ZZ1fvEN1ZC1E_0v
0000000000000058 t _ZZ1fvEN1ZC1Ev
00000000000000c6 t _ZZ1fvEN1ZC2E_0v
0000000000000058 t _ZZ1fvEN1ZC2Ev
00000000000000a0 t _ZZ1fvEN1ZD0E_0v
0000000000000032 t _ZZ1fvEN1ZD0Ev
000000000000006e t _ZZ1fvEN1ZD1E_0v
0000000000000000 t _ZZ1fvEN1ZD1Ev
000000000000006e t _ZZ1fvEN1ZD2E_0v
0000000000000000 t _ZZ1fvEN1ZD2Ev
                 U _ZdlPv


barimba. nm -C dt.o | grep vtable
                 U vtable for __cxxabiv1::__class_type_info
0000000000000020 r vtable for f()::Z
0000000000000000 r vtable for f()::Z

(Also, note the "()"s.  In the earlier example there was a
hidden trick: main is extern "C".)


Furthermore it seems to me that we can't rely on ever having
read debuginfo for the scope in which the class is defined.
We have to expand the CU holding the function first, then
find the type in the function.

A multi-step approach:

First, use the demangler to dissect the vtable's mangled name.
From this deduce whether a function scope must be read.

Then construct the name of the function and look up its symbol,
causing the desired CU expansion.

Then search all the blocks of that function looking for the
appropriate type.  This is tricky due to the example above.
In fact it isn't clear to me how it can reliably be done given
the debuginfo currently emitted.  I don't see a way to determine
which type to use based on just the name of its vtable.
(And if we added some ad hoc attribute I wonder how it would work
for partially constructed objects.)
Comment 11 hmb 2013-02-25 15:36:31 UTC
if i set demangle-style from auto to lucid or hp i does not get any warnings
Comment 12 hmb 2013-02-25 15:54:54 UTC
i used Andre Poenitz test case for it
Comment 13 Jan Kratochvil 2013-02-25 16:18:11 UTC
This way you break the demangling which on standard GNU/Linux OS is
"set demangle-style gnu-v3".  I did not check why it suppresses the warnings but this is not the fix.
Comment 14 Jackie Rosen 2014-02-16 19:20:28 UTC Comment hidden (spam)