2009-11-06 99 views
3

看这个屏幕截图Visual C++调试会话:现在Visual C++调试和神秘的BoundsChecker

http://yp.lviv.ua/philez/wtf.PNG

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

被调试的代码已经仪表用的BoundsChecker(存储器调试器和分析器)。这种差异导致之后的崩溃。非检测代码不会导致任何这些影响。我认为这是太早指责的BoundsChecker - 它很可能是在我的程序隐藏的错误,这错误的BoundsChecker透露,这就是为什么我很倾向于了解情况。

为“B = & MDB”语句生成的组件是如下,在情况下,它是相关的。步进thhrough该组件中,以手表和寄存器可见,被捕获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

是MDB还型CDbBackend的?如果不是,则差异是由于铸造造成的。

考虑:

class A 
{ 
    // Stuff 
}; 

class B : public A 
{ 
    // More stuff 
}; 

B *b = new B; 
A *a = (A *)&b; 

那么B和A可能还是取决于究竟是什么“东西”和“更多的东西”都可能不等价的。最大的改变指针铸件的事情是虚拟和多重继承。如果在你的例子中是这种情况,那么你的调试器的输出是正确和正常的行为。如果您展开MDB类的看法,我也不会,如果你发现其中包含的一个CDbBackend指针,你的第二输出匹配以下惊讶。

+0

是。它具有CDbBackend类型,并且在基类中声明。我正在编辑帖子。 无论如何,指针之间的差异是如此巨大,它几乎不可能是继承布局相关的偏移量。 – user38329 2009-11-06 16:13:31

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

  2. 的代码在调试模式下编译的W/O任何optmizations,对不对?我猜是这样。但是,在反汇编中,没有提供象征性信息。我只能看到[ebp - offset];这应该表示为一些象征性名称,如b。确保在反汇编视图中打开“显示符号名称”。

  3. 我不知道你粘贴的反汇编代码是b = &mDb代码。它看起来像[ebp-10h][ebp-70h]b,但mDb似乎并不在这里。这里的所有代码只是调用instrumented函数。你可以给他们更多的源代码反汇编?

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

这些信息有点不足以解决此问题。如果你提供更多的反汇编会更好。

+0

1.听起来不那么愚蠢,但我已经尝试了很多次,但都无济于事。 2.是的,调试和没有优化。关于符号替换:这就是反汇编总是寻找我的方式......我不记得任何调试器替代寄存器和地址符号 - 它并不总是有道理的。 “显示符号名称”已打开。 3.我确定这是正确的反汇编。请自己看一下:我捕获了一个视频,通过反编译代码和未代码的代码。这些视频位于http://yp.lviv.ua/tmp。谢谢! – user38329 2009-11-07 10:19:03