Как посмотреть vtable в gdb в программе на C ++? - PullRequest
5 голосов
/ 06 октября 2011

У меня есть интересная проблема в одной из моих программ на C ++. Возможно, vtable одного из моих классов испортился во время выполнения программы. В сеансе GDB я обнаружил, что если я вызываю метод объекта напрямую, это успешно, но если я использую указатель или ссылку, я оказываюсь в деструкторе полностью несвязанного класса, который не будет создан в ближайшее время. Без this -Изменения указателя курса.

Предполагая, что мои наблюдения верны, как мне посмотреть vtable объекта в gdb? Я использую gcc для Linux, моя версия GDB GNU gdb (Ubuntu/Linaro 7.3-0ubuntu2) 7.3-2011.08.

Ответы [ 2 ]

4 голосов
/ 06 октября 2011

Вы можете использовать опцию -fdump-class-hierarchy в gcc, которая даст вам информацию vtable, однако вывод может быть очень многословным и трудным для чтения.

Например, с учетом следующих тривиальных классов:

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

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

соответствующий вывод

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)

Это должно дать вам представление о том, какие диапазоны адресов следует ожидать во время отладки и т. Д.

0 голосов
/ 06 октября 2011

Если вы не взломали, я сомневаюсь, что ваш vtable испорчен.Вы вызываете виртуальную функцию из конструктора?

Возможно также, что отладчик связывается с вами.Компилируя с оптимизацией, вы можете получить тот же адрес для функций, которые делают то же самое, чтобы не иметь дублированного кода.Я столкнулся с этим под Windows, где Visual Studio также использовала различные функции, которые фактически делали то же самое.Попробуйте вывести что-то вместо того, чтобы пройтись по коду с помощью отладчика ... Это может быть .

...