现在我正在调试一个大型项目,它有一个堆栈损坏:应用程序失败。
我想知道如何使用Visual Studio 2010查找(调试)此类堆栈损坏代码?
以下是一些导致堆栈问题的代码示例,如何找到此类腐败的不太明显的案例?
void foo()
{
int i = 10;
int *p = &i;
p[-2] = 100;
}
请注意,这只是一个例子。我需要在当前项目中找到这样糟糕的代码。
答案 0 :(得分:5)
有一种技术可以对这些类型的错误非常有效,但它只适用于具有一些特征的一部分:
请注意,乍一看似乎不太可能出现第二种情况,因为根据运行时操作,堆栈可以以多种不同的方式使用。但是,堆栈使用通常非常确定。问题是特定的堆栈位置可以用于许多不同的事情,问题实际上是第3项。
无论如何,如果你的bug有这些特性,你应该识别出被破坏的堆栈地址(或者其中一个),然后设置一个内存断点来写入该地址,条件是只有当它被破坏时写的价值是腐败价值。在Visual Studio中,您可以通过在“断点”窗口中创建“新数据断点...”然后右键单击断点来设置条件来完成此操作。
如果最终得到太多的误报,可能有助于缩小断点的范围,方法是将其禁用,直到执行路径中的某个点更接近错误(如果您可以识别这样的时间),或者将命中数设置得足够高,以消除大多数误报。
另一个复杂因素是堆栈的地址可能会在运行之间发生变化 - 在这种情况下,您必须注意在每次运行时设置断点(地址的低位应该相同)。
答案 1 :(得分:2)
我相信你的问题引用了一个堆栈损坏的例子,你问的问题不是它崩溃的原因。
如果是这样,它会崩溃,因为它会创建未定义的行为,因为索引-2
指向未知的内存位置。
回答关于剖析申请的问题:
您可以使用 Rational Purify Plus 来查看内存过载和访问错误。
答案 2 :(得分:-1)
这是UB:p[-2] = 100;
您可以使用此operator[]
方式p[i]
访问p,但在这种情况下,i
是无效值。因此p[-2]
指向无效的内存位置并导致未定义的行为。
要找到它,你应该调试你的应用程序并找到它崩溃的地方,并且希望它会出现在某个地方出现问题的地方。