如何在Visual Studio中调试错误的调用堆栈

时间:2014-03-12 09:50:09

标签: c++ visual-studio-2010 visual-studio-debugging dynamic-dispatch

我正在与第三层图书馆的大班级合作,这里有相关内容的摘录:

class SomeClass {
    // ...
public:
    // ...
    virtual int SetTableSize(unsigned int uiTableID, int iSize);
    // ...
protected:
    // ...
    virtual int Set_0xB0_0x23_IsoTableData(unsigned char* ucData, int iLen);
    // ...
};

我的应用程序因内存访问冲突而中断。调用堆栈中最上面的项是Set_0xB0_0x23_IsoTableData实现中的代码行,第二项是这样的代码行:

someClassInstance.SetTableSize(2, 400);

在调试视图中,ucData的值为0x00000002,所以它实际上看起来不是调用SetTableSize的实现,而是根据代码调用Set_0xB0_0x23_IsoTableData SomeClass使用指定的参数调用 - 这显然会导致错误,因为指针不是有效的。

我已经花了很多时间弄清楚这里发生了什么。我在Linux上使用GCC在不同的应用程序中编译相同的代码,它在那里工作。这是Visual Studio编译器的错误吗?编译此代码时,我没有收到任何警告。

不可能构建一个最小的工作示例来重现错误 - 至少在找出发生这种情况的原因之前。 #ifdef标头中确实有一些SomeClass,所以我首先想到的是,编译包含{{1}}的模块时预处理器定义与编译调用代码时不同。但是,我仔细检查过,定义是一样的。

所以我想问的基本上是:

  • 在什么条件下,对虚方法的调用可以调用另一个虚方法的实现? (这不是关于继承 - 这两个方法在同一个类中定义,甚至不共享其签名并具有不同的可见性)
  • 如何调试此类错误?是否可以在Visual Studio中查看类实例的调度向量?

1 个答案:

答案 0 :(得分:0)

我对这些问题的标准答案:重建所有问题。在某些情况下,它就像那样简单/愚蠢(至少对于Visual Studio来说)。

如果错误仍然存​​在,那么我要做的就是调试:尽可能地运行代码"它现在不能发生"。然后逐行调试,仔细观察调用堆栈。

不,这不好玩。