3

查看 Visual C++ 调试器会话的屏幕截图:


(来源:lviv.ua

执行点现在位于虚函数内部。“mDb”是对该类成员的对象的引用。“mDb”的类型为CDbBackend&。只有一个线程。红色矩形中的值应该相等,......但它们不是。这怎么可能?

正在调试的代码已使用 BoundsChecker(内存调试器和分析器)进行了检测。这种差异导致后来的崩溃。非插桩代码不会导致任何这些影响。我认为现在责怪 BoundsChecker 还为时过早——它很可能是 BoundsChecker 揭示的我的程序中的一个隐藏错误,这就是为什么我非常倾向于了解这种情况的原因。

为“b = &mDb”语句生成的程序集如下,以防相关。在此处捕获了通过此程序集的步骤,并显示了监视和寄存器(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 
4

2 回答 2

1
  1. 请重建并再次测试。(我知道这听起来很愚蠢:)

  2. 代码是在调试模式下编译的,没有任何优化,对吧?大概吧。但是,在反汇编中,没有显示任何符号信息。我只能看到[ebp - offset];这应该表示为一些符号名称,例如b. 确保在反汇编视图中打开“显示符号名称”。

  3. 我不确定您粘贴的反汇编代码是b = &mDb. 它看起来像[ebp-10h][ebp-70h]将会是b,但mDb似乎不在这里。这里的所有代码只是调用检测函数。你能用它们周围的源代码提供更多的反汇编吗?

  4. 我有过错误生成调试信息的经验,因此符号调试给出了不正确的值。我的解决方法是更改​​成员变量布局并在本地堆栈中放置一些填充。但是,我不确定这真的是编译器的错误。我正在使用英特尔 C/C++ 编译器开发 Visual Studio 2008,该项目非常复杂。

信息有些不足以解决这个问题。多拆解就更好了。

于 2009-11-07T03:42:09.950 回答
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 指针与下面的第二个输出相匹配,我不会感到惊讶。

于 2009-11-06T16:08:03.543 回答