2013-04-24 148 views
3

我碰到this错误来了,我看到itspopular周围的变量C++堆栈被损坏

这个问题是相当混乱。我试图找出哪个变量没有被正确返回。将一个VC6项目移植到VS 2012时发现了此问题。这里发生的是从数据库中取出记录集并将其转入XML。

CGenAction GenAct(lUserId, O_ALARM, A_GET_TREE, ppALResult) 
{ 
    try 
    { 
     if (GenAct.BeginAction()) 
     { 
      checkuserPremission(info); 

      Result Res; 
      Dynaset DynaSet; 

      if (type.GetRecordSet(UserId, DynaSet, Res)) { 
       turnToXml(DynaSet,Res.m_bstrXMLString); 
      } 

      returnToUI(Res); 
     } 
    } 
} 

之前我就知道这种类型的bug我试图做这样的事情将ResDynaSet堆而不是堆栈内:

static Result * ResPtr = NULL; 

if(ResPtr != NULL) 
{ 
    delete ResPtr;   
} 

ResPtr = new Result(); 

这并没有帮出来的问题。围绕以下变量的堆栈已损坏:Res,DynaSet我会尽量缩小范围,并且会尽快更新问题。

+2

我没有看到任何可能导致此代码中堆栈损坏的内容,您是否可以缩小范围并发布该代码? – 2013-04-24 08:49:43

+1

堆栈_which_变量?你的代码中有很多,所以很难说没有看到这些类的代码。此外,这些“开始/结束宏”评论是什么?这是一些宏的一部分吗? '试图找出哪个变量没有被正确返回是相当混淆的 - 错误确切地说明哪个变量被损坏了,你能显示完整的错误信息吗? – 2013-04-24 09:35:58

回答

3

这是一个非常可靠诊断,VC6没有它。虚假警告的可能性为零。在移植之前,请注意,您的代码库中可能存在此问题。它警告的错误非常严重,通常在没有帮助的情况下诊断非常困难。然而,它不一定是一个致命的问题,它可以长时间潜伏在代码中。只是突然冒出来,并看到一个非常无辜的代码更改肆虐。只需使用发布版本设置来重建程序就足够了,这使得诊断问题变得更加困难。

你的代码片段太不透明,不能提出一个原因,未记录的函数可能会导致它。我只会描述诊断工作的方式,以便您能够调试它。

/RTC调试选项会导致编译器在堆栈帧中分配局部变量,以便它们之间有空间。它会生成一个表格来标识这些空间。在函数入口处,这些空间填充值0xcc。在函数退出时,它会运行一个调试函数,该函数遍历表并检查这些空间是否仍包含0xcc。如果没有,你会得到一个非常可靠的指示,表明代码正在写入它绝不应该触及的堆栈帧位置。堆栈缓冲区溢出是一种可能性,还有其他的。

调试它的方法是使用Debug + Windows + Memory + Memory 1窗口。在函数的第一个语句中设置一个断点。当它命中时,将EBP放入地址栏并打开页面(注意堆栈增长下降)。您现在正在查看堆栈帧中的字节,切换到4字节视图通常是最好的。尝试将本地变量与您所看到的值相匹配。您还应该看到填充变量之间空格的0xcc值。现在使用调试器的StepOver命令开始步进。堆栈帧中更改的值以红色着色。尝试找到一个红色的,并包含0xcc之前。

你现在有一个字节的地址被重击。重新启动并使用数据断点来让调试器停止在重复该字节的语句处。