我在我的一个C++程序中遇到了一个有趣的问题。很明显,我的一个类的vtable在程序执行期间变得一团糟。在gdb会话中,我发现如果我直接调用对象的方法,它会成功,但如果我使用指针或引用,我会在一个完全不相关的类的析构函数中结束,这个类在短期内不会被实例化。当然,不需要更改this-Pointer。
假设我的观察是正确的,我如何在gdb中查看对象的vtable?我在Linux上使用的是gcc,我的gdb版本是GNU gdb (Ubuntu/Linaro 7.3-0ubuntu2) 7.3-2011.08。
发布于 2011-10-07 01:55:55
您可以使用gcc的-fdump-class-hierarchy选项,该选项将为您提供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)这应该会让你知道在debuggng等过程中需要哪些地址范围。
发布于 2011-10-07 01:58:07
除非你是黑客,否则我怀疑你的vtable是不是搞砸了。是否从构造器中调用虚函数?
也可能是调试器在干扰您。通过优化编译,你可能会得到做同样事情的函数的相同地址,因为不会有重复的代码。我在Windows下遇到了这种情况,在Windows中,Visual Studio也跳入了不同的函数,这些函数实际上做了同样的事情。尝试输出一些东西,而不是使用调试器遍历代码...此可能是原因。
https://stackoverflow.com/questions/7678303
复制相似问题