为什么'这个'踩过代码时指针会改变它的值吗?

时间:2016-08-23 15:48:05

标签: c++ debugging windbg

我正在调试崩溃,我注意到作为调试器的一步,this指针改变了它的值,经过3步后它最终得到值0x00000001并且应用程序崩溃。

现在0x00000001值显然是错误的,但是当我逐步调试调试器时,我真的希望this值改变吗?

下面是我正在调试崩溃的构造函数。我已经在每个步骤的注释中包含了this指针的值,你可以看到它跳了很多。

CADOCommand::CADOCommand(CADODatabase* pAdoDatabase, CString strCommandText, int nCommandType)
{
    m_pCommand = NULL;
    m_pCommand.CreateInstance(__uuidof(Command)); // this = 0x515f9d10
    m_strCommandText = strCommandText; // this = 0x2c0c0ee8
    m_pCommand->CommandText = m_strCommandText.AllocSysString(); // this = 0x515f9d20
    m_nCommandType = nCommandType; // this = 0x70847a55
    m_pCommand->CommandType = (CommandTypeEnum)m_nCommandType; // this = 0x00000001
    m_pCommand->ActiveConnection = pAdoDatabase->GetActiveConnection(); 
    m_nRecordsAffected = 0;
}

在我们单步执行给定成员函数中的代码时,是否存在this的值可能或应该更改的情况?

更新

我必须添加记录并回应几条评论,我正在调试发布版本,但是当我在调试版本中调试相同的函数时,this的值毕竟没有改变。

那么这是什么意思,只有在发布版本中才存在问题?

@drescherjm的评论是赞成的in release mode the this pointer is not correct because of optimization,但这恰恰意味着什么?不正确'?我们不能在发布版本中信任这个指针(是假的)或指针值是否正确但是由于优化而导致版本构建被破坏?

2 个答案:

答案 0 :(得分:6)

根据调试程序的不同,在点击该功能和输入之间看到this的值发生变化可能是正常的。

this==0xcccccccc before entering the function

点击S::f()

this has a valid address after entering the function

输入S::f()

但是,一旦您输入了该函数,this的值不应更改 1 。如果是这样,可能意味着你有某种缓冲区溢出并覆盖你的堆栈。

找出问题可能很棘手。您可以尝试在this上放置内存断点,以查看它何时更改或注释掉代码,直到问题消失。这应该可以帮助你缩小范围。请注意,罪魁祸首可能甚至不在那个特定的功能中:内存损坏因在不相关的地方造成破坏而臭名昭着。

您似乎也在使用优化版本来查看此内容。在使用优化时要非常谨慎地依赖调试器:变量可能会从代码中消失,从而让人觉得它们的值是错误的。如果您可以重现该问题,我会尝试在某处记录this,而不是通过调试器查看它。整件事实际上可能是红鲱鱼。

1 但是,当您在层次结构中调用另一个成员函数时,this 可以更改,尤其是涉及虚拟基础时。 / SUP>

答案 1 :(得分:0)

由于您的示例首先是从使用GUID获得的__uuidof创建实例,因此有一个因素也可能导致发布与<<1>}完全不同em> debug 代码:根据文档,__uuidof在运行时在 debug 构建中重新获得,并且已编译为发布构建。对于前者,最坏的情况是模块加载/绑定顺序可能会受到影响。

  

<强> __uuidof Operator

     

https://msdn.microsoft.com/en-us/library/zaah6a61.aspx

           

注意:

     

在调试版本中, __ uuidof 始终动态初始化对象(在运行时)。在发布版本中, __ uuidof 可以静态地(在编译时)初始化对象。

当版本控制出现问题时,运行时值也可能与静态绑定结果不同,这意味着您可能在发布与调试方案中调试不同的对象。