c++ - 调试堆栈损坏

标签 c++ visual-studio debugging stack-corruption

现在我正在调试一个有堆栈损坏的大型项目:应用程序失败。

我想知道如何使用 Visual Studio 2010 查找(调试)此类堆栈损坏代码?

这是一些导致堆栈问题的代码示例,我如何才能找到此类损坏的不太明显的案例?

void foo()
{
    int i = 10;
    int *p = &i;
    p[-2] = 100;
}

更新

请注意,这只是一个示例。我需要在当前项目中找到这样糟糕的代码。

最佳答案

有一种技术可以非常有效地解决这些类型的错误,但它只适用于具有以下几个特征的部分错误:

  • 破坏值必须是稳定的(即,在您的示例中,当发生破坏时,它始终为 100),或者至少是可以在简单表达式中轻松识别的值
  • 损坏必须发生在堆栈上的特定地址
  • 损坏的值非常不寻常,您不会遇到大量误报

请注意,第二个条件乍一看似乎不太可能,因为堆栈可以根据运行时操作以多种不同方式使用。然而,堆栈的使用通常是非常确定的。问题是一个特定的堆栈位置可以用于很多不同的东西,所以问题实际上是第 3 项。

无论如何,如果您的 bug 具有这些特征,您应该确定被损坏的堆栈地址(或其中之一),然后设置一个内存断点以写入该地址,并且只有在以下情况下才会中断写入的值是损坏的值。在 visual Studio 中,您可以通过在“断点”窗口中创建“新数据断点...”然后右键单击断点来设置条件来完成此操作。

如果你最终得到太多的误报,它可能有助于缩小断点的范围,方法是将它禁用直到执行路径中更接近错误的某个点(如果你可以识别这样的时间),或者将命中计数设置得足够高以消除大部分误报。

另一个复杂的问题是堆栈的地址可能会在每次运行时发生变化 - 在这种情况下,您必须注意在每次运行时设置断点(地址的低位应该相同)。

关于c++ - 调试堆栈损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7294294/

相关文章:

c++ - 在我看来,[basic.lookup.argdep]/3 中的示例中有两个候选函数用于调用 g(parm, 1)

visual-studio - 如果我安装 Visual Studio 2008,Visual Studio 6.0 是否可以工作?

c# - Windows Phone 更新 ListView

c# - 集成语言服务 (MPF) 和编辑器扩展 (MEF)

debugging - 漏洞搜寻策略?

c++ - 如何克隆载体?

C++如何处理for_each循环中使用的lambda表达式的返回值?

c++ - 如何在 C++ (Unicode) 中将 std::string 转换为 LPCWSTR

visual-studio - 在 Visual Studio 中记录调用堆栈

debugging - 谷歌图表-类别过滤器代码