Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to watch the vtable in gdb in a C++ program?

I have an interesting problem in one of my C++ programs. Apperantly the vtable of one of my classes is/becomes messed up during program execution. In a gdb session I found out that if I call a method of the object directly it succeeds, but if I use a pointer or reference I end up in the destructor of a completely unrelated class which isn't going to be instantiated anytime soon. Without the this-Pointer changing of course.

Assuming my observations are correct, how do I watch the vtable of an object in gdb? I'm on Linux using gcc, my gdb version is GNU gdb (Ubuntu/Linaro 7.3-0ubuntu2) 7.3-2011.08.

like image 920
Raphael R. Avatar asked Oct 09 '22 20:10

Raphael R.


1 Answers

You can use the -fdump-class-hierarchy option of gcc which will give you the vtable information, however the output can be very verbose and hard to read.

For instance, given the following trivial classes:

class Base {                                                                            
    public:                                                                             
        virtual int method() = 0;                                                       
};                                                                                      

class Derived : public Base {                                                           
    public:                                                                             
        int method() {                                                                  
            return 10;                                                                  
        }                                                                               
};  

the relevant output is

Vtable for Base
Base::_ZTV4Base: 3u entries
0     (int (*)(...))0
8     (int (*)(...))(& _ZTI4Base)
16    (int (*)(...))__cxa_pure_virtual

Class Base
   size=8 align=8
   base size=8 base align=8
Base (0x7f14c308ccc0) 0 nearly-empty
    vptr=((& Base::_ZTV4Base) + 16u)

Vtable for Derived
Derived::_ZTV7Derived: 3u entries
0     (int (*)(...))0
8     (int (*)(...))(& _ZTI7Derived)
16    (int (*)(...))Derived::method

Class Derived
   size=8 align=8
   base size=8 base align=8
Derived (0x7f14c2ee7208) 0 nearly-empty
    vptr=((& Derived::_ZTV7Derived) + 16u)
  Base (0x7f14c308cd20) 0 nearly-empty
      primary-for Derived (0x7f14c2ee7208)

This should give you an idea which address ranges to expect during debuggng etc.

like image 166
bbtrb Avatar answered Oct 12 '22 10:10

bbtrb