我目前正在一个相当大(和老,叹)代码库,最近升级到VS2005(SP1)。我和我的团队正在改变/更新/替换此代码中的模块,但我们偶尔会遇到vtables似乎破裂的问题。我不是vtables的专家,但这些确定似乎已被打破。错误表现与此错误:VS2005 C++破vtables
Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.
当然可以有很多其他原因造成的错误,但调试(调试版本)时,其实我可以确认为对象的虚函数表我想上一下运行奇怪:
引用每个vtable的堆栈和堆看起来很好,并且指向vtable的指针与映射文件完全匹配。这表明这不是内存覆盖错误或类似的问题,因为那样会影响堆栈和堆,而不是存储vtables的位置。 (它们被存储在只读区域中吗?)无论如何,目前所有这些看起来都不错。但是当查看vtable的内存时,我发现所有的值,如果我将它们解释为指针,尽管它们在相同的范围内(例如,0x00f203db 0x00f0f9be 0x00ecdda7 0x00f171e1)与映射文件中的任何条目都不匹配,并且其中很多甚至没有对齐到4个字节。我不知道VS2005如何构建vtables的所有细节,但这看起来不对。如果这是正确的行为,也许有人可以向我解释这一点?
我想我的问题归结为什么会导致这种行为?例如,当太复杂的类层次结构时,链接器中是否有任何已知的错误?有没有人见过类似的东西?目前,我们可以通过将受影响的类的函数移至内联(可怕的东西!)来解决我们的崩溃问题,但显然这不是一个可行的长期解决方案。
感谢您的任何见解!
更新:我被问到关于该项目的更多细节,当然我会提供这个。但首先,问题并不完全与ESP值不被保存错误相关。我最感兴趣的是为什么我在vtable中看到奇怪的值。这就是说,这里有一些额外的信息:解决方案依赖于几个外部和内部项目,但这些都没有改变很长一段时间,所有使用相同的调用约定。它似乎打破的代码都在解决方案的一个非常标准的C++“主”项目中。所有代码都使用相同的编译器构建。该解决方案还没有使用任何DLL,但是用大量静态库的链接:
SHFolder.lib,python25.lib,DXGUID.LIB,d3d9.lib,d3dx9.lib,dinput8.lib,ddraw.lib,dxerr9 .lib ws2_32.lib mss32.lib Winmm.lib vtuneapi.lib vttriggers.lib DbgHelp.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib ,shell32.lib,ole32.lib,oleaut32.lib,uuid.lib,odbc32.lib,odbccp32.lib
嗨,谢谢!上面的问题增加了一些更多的信息。 – Dan 2009-02-24 09:32:04
bwah ...我很难过,因为你的构建环境看起来很健全。让我考虑一下这个问题,并回来一些新的建议/问题。 – 2009-02-24 14:06:38
呵呵,是的,我在这里也画了一个空白,除了我看到的奇怪的vtable。感谢您提出任何想法:) – Dan 2009-02-25 03:52:13