3

需要 root 帮助导致 vtable 损坏问题(不确定是否发生了这种情况)。这是代码的非常简化的版本。

class CBase
{
public:
    CBase()
    virtual ~CBase()
    virtual void base_virtual_fn1() = 0;
    virtual void base_virtual_fn2();
private:
    CData   _data;
};

class CDerived : public CBase
{
public:
    CDerived();
    virtual ~CDerived()
    virtual void base_virtual_fn1();
    virtual void base_virtual_fn2();
    virtual void derived_virtual_fn1();
    virtual void derived_virtual_fn2();
private:
    // Contains vectors , maps, integers, bools. 
};

当我创建 CDerived 的一个实例并调用派生类虚拟函数时,派生_virtual_fn2 另一个函数被称为派生_virtual_fn1。

调用 base_virtual_fnx 没有问题。

这只发生在堆上创建的对象而不是本地对象。

这些类位于共享库中。我在 Linux (SLES 10) 上使用 gcc 3.4.2。此代码中没有 pragma pack 指令,并且混合了 C 和 C++ 代码(使用了 extern c)。这里可能是什么问题?

我忘了提到还有很多其他代码(可执行文件,库)

4

5 回答 5

3

这是我犯的一个令人讨厌的错误,我花了很长时间才找到。编译器/调试器/valgrind 没有让我了解发生了什么。应该有某种方式来调试这些类型的错误:

基类在定义了“SOME_PACKAGE”的库中编译:

class interface {
    virtual int function1(int);
#ifdef SOME_PACKAGE
    virtual int function2(int);
#endif
    virtual int function3(int);
}

class base : public interface {
    int function1(int);
    int function2(int);
    int function3(int);
}

派生类后来在没有定义 SOME_PACKAGE 的情况下编译

class derived : public base {
    int function1(int);
    int function3(int);
}

对 function3 的调用导致跳转到 function2,我最终能够通过调试器找出原因,但我花了很长时间才找到原因。

于 2016-07-13T11:11:58.250 回答
1

如果只发生在堆上创建的对象,最可能的解释是堆损坏,这可能与您提到的两个类无关。检查您的分配/解除分配!检查您是否正确使用 delete [] 删除数组等。也许也使用 valgrind 或类似的。

于 2010-12-21T01:54:49.727 回答
1

很抱歉死灵了这个线程,但是在调试类似的问题时,我终于找到了一个尚未在此处列出的可能答案,并且我相信这对其他遇到此类问题的人会有所帮助。

答案(在我的情况下)是,仍然安装了部分代码,但是我们的构建系统无法确保测试实际上链接到新的和正确编译的版本。相反,加载的动态库期望与调用它们的代码不同的 vtable 布局。

当然,可能的症状是执行了错误的函数,或者对虚拟函数的调用因分段错误而失败。这实际上取决于两个版本之间的 vtable 布局如何变化。

如果这是您的问题背后的原因,make uninstall应该解决它。

于 2013-10-01T14:07:22.963 回答
0

这几乎总是陈旧的对象。清理或尝试在链接器路径中找到陈旧的目标文件。

于 2013-10-01T14:20:58.757 回答
0

你向我们展示的几乎没有什么令人震惊的;-)

当我碰巧对内存损坏一无所知时,我习惯于打开实用程序gflags。在引发不合逻辑的噩梦之前,一个小小的应用程序和检测许多犯罪事件是非常明智的。然而,它使事情变得非常缓慢。

尝试理解 gflags 尖叫的大部分步骤。

于 2010-12-23T17:46:06.740 回答