Visual Studio 2008-vftable指针不正确?调试模式崩溃,发布即可
Visual Studio 2008 - vftable pointer incorrect? Debug mode crashes, Release is fine
我当前面临VS08的问题。我得到了以下(简化的)类结构:
class CBase
{
public:
virtual void Func() = 0;
};
class CDerived : public CBase
{
public:
void Func();
};
这段代码在发布模式下运行良好,但当我尝试运行调试构建时,它会在new CDerived
上立即崩溃。
进一步的分析使我找到了坠机地点。它在CBase::CBase(编译器生成的构造函数)上崩溃。更确切地说,它在04AE46C6 mov dword ptr [eax],offset CBase::
vftable"(505C2CCh)"处崩溃。
有线索吗?发布模式很好,但我不能用它正确调试。
释放模式良好
没有,看起来很好。我的猜测是,在调试中,内存被某种方式覆盖了。由于无法仅从您发布的代码中判断,以下是您可以做的。
我假设你在某个地方创建了一个对象:
CBase* p = new CDerived;
或类似的。在调试模式下,在p
的位置设置内存断点。您可以将其设置为监视4个字节。Visual C++(像大多数编译器一样)将把vfptr作为类中的第一件事,因此这个断点将跟踪该位置是否被覆盖。如果在调用崩溃的函数之前遇到了断点,那么这就是问题所在(调用堆栈将显示它被覆盖的原因)。
这可能有很多原因——你可能会占用一些内存并覆盖对象(正如Erik所建议的)——发布版本可能会直接解析调用,以防止动态调度的开销,这也解释了为什么它没有崩溃。
也可能是您在对象上调用delete
,而调试版本实际上会将内存清零,而发布版本则不会。没有办法从中辨别。
Necro在这里发布了一些帖子,但我想为未来的访客指出一点。。。
正如其他人所说,这可能是内存损坏或免费+重用问题。您不应该仅仅因为能够通过更改编译器设置或重新排列代码来消除崩溃就认为这是一个编译器错误。如果这是一个损坏错误,您可能会将损坏移到一些不会导致程序崩溃的内存中——而不是在您当前的构建中,在您当前OS&无论如何,架构。
简单地达到不崩溃的地步可能已经足够满足你的即时需求了,但与此同时,你没有学会避免最初导致你编写错误的任何练习。工程师中有一句由来已久的谚语,可能还有相当多的其他学科:
"自行消失的东西可以自行回来。"
这可能是任何形式的工程中最真实、最重要的谚语之一。如果你没有亲眼看到虫子死去,你应该一直为此感到焦虑。它会深深地困扰你。这个bug可能仍然存在,等待你下一个里程碑的夜晚,然后再重新抬头。
Luchian Grigore就找到内存断点的真正问题给出了很好的建议。
- LoadLibrary:在发布模式下崩溃
- 在发布模式下崩溃,但如果可调试为 true - 不是..什么是可能的问题
- boost :: container :: flat_multimap在OSX/Appleclang上以发行模式崩溃
- MSVC 编译器在调试模式下构建 Qt 5.10 时崩溃
- 一般来说,使用Qt Creator,是什么导致程序在调试模式下编译时正确运行,但在发布模式下崩溃
- 在发行模式下开放的软崩溃(调试工作正常)
- MFC 结束对话框崩溃时模式对话框没有焦点
- GCC 在调试模式下崩溃,在发布模式下运行良好
- 在发布模式下崩溃,在调试模式下遇到错误
- C++: __try..__除了;在发布模式下隐藏崩溃
- 通过在 C++ 中使用发布模式二进制文件获取崩溃原因
- cd库:在推送自定义类型的派生类型时(仅在发布模式下),michael_deque会导致崩溃
- wglCreateContextAttribsARB在x64平台下的调试模式下崩溃
- 当结构具有默认构造函数时,为什么我的C++程序在发布模式下崩溃
- boost::any_range<gsl::string_span<>> 在发布模式下崩溃
- 释放模式下的boost线程崩溃
- OCCI应用程序在Visual Studio 2005的调试模式下运行时会崩溃
- c++全系统崩溃,仅发布模式
- Directshow渲染过滤器只在发布模式下崩溃
- 使用DirectXMath中的XMVECTOR作为类成员只会在发布模式下导致崩溃