Visual c++ visualc&x2B+;调试器和BoundsChecker之谜 查看VisualC++调试程序的这个截图:

Visual c++ visualc&x2B+;调试器和BoundsChecker之谜 查看VisualC++调试程序的这个截图:,visual-c++,debugging,bounds-checker,Visual C++,Debugging,Bounds Checker,(来源:) 执行点现在位于虚拟函数内。“mDb”是对作为该类成员的对象的引用。“mDb”的类型为CDbBackend&。只有一根线。红色矩形中的值应相等。。。但事实并非如此。这怎么可能呢 正在调试的代码已使用BoundsChecker(内存调试器和探查器)进行检测。这种差异导致了后来的崩溃。未插入指令的代码不会导致任何这些影响。我认为现在指责BoundsChecker还为时过早——BoundsChecker已经揭示了我的程序中隐藏的一个bug,这就是为什么我非常倾向于理解这种情况 为“b=&mD


(来源:)

执行点现在位于虚拟函数内。“mDb”是对作为该类成员的对象的引用。“mDb”的类型为CDbBackend&。只有一根线。红色矩形中的值应相等。。。但事实并非如此。这怎么可能呢

正在调试的代码已使用BoundsChecker(内存调试器和探查器)进行检测。这种差异导致了后来的崩溃。未插入指令的代码不会导致任何这些影响。我认为现在指责BoundsChecker还为时过早——BoundsChecker已经揭示了我的程序中隐藏的一个bug,这就是为什么我非常倾向于理解这种情况

为“b=&mDb”语句生成的程序集如下所示(如果相关)。在监视和寄存器可见的情况下,通过此程序集的步进被捕获(500kb avi文件)


mDb是否也是CDbBackend类型?如果不是,则差异是由于铸造造成的

鉴于:

class A
{
  // Stuff
};

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

B *b = new B;
A *a = (A *)&b;
那么b和a可能相等,也可能不相等,这取决于“东西”和“更多东西”到底是什么。改变指针铸件的最大因素是虚拟和多重继承。如果您的示例中是这种情况,那么调试器的输出是正确和正常的。如果展开mDb的类视图,如果发现其中包含的CDbBackend指针与下面的第二个输出相匹配,我不会感到惊讶

  • 请重新生成并再次测试它。(我知道这听起来很愚蠢:)

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

  • 我不确定您粘贴的反汇编代码是否是
    b=&mDb
    的代码。看起来
    [ebp-10h]
    [ebp-70h]
    将是
    b
    ,但
    mDb
    似乎不在这里。这里的所有代码都只是调用插入指令的函数。你能提供更多的反汇编代码吗

  • 我有一次调试信息生成错误的经历,因此符号调试给出了错误的值。我的解决方法是更改成员变量布局,并在本地堆栈中添加一些填充。但是,我不确定这是否真的是编译器的错误。我当时正在使用英特尔C/C++编译器开发Visual Studio 2008,项目相当复杂


  • 信息不足以解决此问题。如果您能进行更多的拆卸,那就更好了。

    是的。它的类型为CDbBackend&并在基类中声明。我正在编辑这篇文章。无论如何,指针之间的差异是如此巨大,几乎不可能是继承布局相关的偏移量。1。听起来没那么愚蠢,但我已经试过很多次了,都没有用。2.是的,调试,没有优化。关于符号替换:这就是反汇编对我的看法。。。我不记得有任何调试器用符号替换寄存器和地址——这并不总是有意义的。“显示符号名称”处于启用状态。3.我相信这是正确的拆卸。请自己看一看:我拍摄了一段视频,演示了如何分解插入指令和未插入指令的代码。这些视频位于。谢谢
    class A
    {
      // Stuff
    };
    
    class B : public A
    {
      // More stuff
    };
    
    B *b = new B;
    A *a = (A *)&b;