查看Visual C ++调试器会话的屏幕截图:
(来源:lviv.ua)
执行点现在位于虚函数内。 “mDb”是对作为该类成员的对象的引用。 “mDb”的类型为 CDbBackend& 。只有一个主题。红色矩形中的值应该相等,但是它们不是。怎么可能呢?
正在调试的代码已经使用BoundsChecker(内存调试器和分析器)进行了检测。这种差异导致以后崩溃。非检测代码不会导致任何这些影响。我认为归咎于BoundsChecker还为时过早 - 它很可能是BoundsChecker揭示的程序中隐藏的错误,这就是为什么我非常倾向于理解这种情况。
为“b =& mDb”语句生成的程序集如下所示,如果相关的话。通过此组件步进,手表和寄存器可见,被捕获here(500kb avi文件)。
007AB7B0 push 4
007AB7B2 push 80000643h
007AB7B7 push 4
007AB7B9 push 0C0002643h
007AB7BE lea eax,[ebp-10h]
007AB7C1 push eax
007AB7C2 call dword ptr [_numega_finalcheck_C_110456 (8FA8A8h)]
007AB7C8 mov eax,dword ptr [eax]
007AB7CA add eax,1CCh
007AB7CF push eax
007AB7D0 call dword ptr [_numega_finalcheck_C_110456 (8FA8A8h)]
007AB7D6 mov dword ptr [ebp-70h],eax
007AB7D9 push dword ptr [ebp-70h]
007AB7DC push 4
007AB7DE push 50000643h
007AB7E3 lea eax,[ebp-20h]
007AB7E6 push eax
007AB7E7 call dword ptr [_numega_finalcheck_Y_110456 (8FA8ECh)]
007AB7ED mov ecx,dword ptr [ebp-70h]
007AB7F0 mov ecx,dword ptr [ecx]
007AB7F2 mov dword ptr [eax],ecx
答案 0 :(得分:1)
请重建并再次测试。 (我知道这听起来很愚蠢:)
代码是在调试模式下编译的,没有任何optmizations,对吗?大概吧。但是,在反汇编中,没有呈现符号信息。我只能看到[ebp - offset]
;这应该表示为一些符号名称,例如b
。请务必在反汇编视图中启用“显示符号名称”。
我不确定您粘贴的反汇编代码是b = &mDb
的代码。看起来[ebp-10h]
或[ebp-70h]
似乎是b
,但mDb
似乎不在这里。这里的所有代码都是调用检测函数。你能用它们的源代码进行更多的反汇编吗?
我有一种错误生成调试信息的经验,因此符号调试的值不正确。我的解决方法是更改成员变量布局并在本地堆栈中放置一些填充。但是,我不确定这是一个真正的编译器错误。我正在使用英特尔C / C ++编译器处理Visual Studio 2008,该项目非常复杂。
此信息不足以解决此问题。如果你提供更多的反汇编会更好。
答案 1 :(得分:0)
mDb是否也是CDbBackend类型?如果没有,那么差异就是由于投射。
假设:
class A
{
// Stuff
};
class B : public A
{
// More stuff
};
B *b = new B;
A *a = (A *)&b;
然后b和a可能会或可能不会相等,具体取决于“Stuff”和“More Stuff”究竟是什么。将改变指针转换的最大的事情是虚拟和多重继承。如果在您的示例中就是这种情况,则调试器的输出是正确且正常的行为。如果展开mDb的类视图,如果你发现其中包含的CDbBackend指针与下面的第二个输出相匹配,我不会感到惊讶。