【问题标题】:Wrong breakpoint being hit错误的断点被击中
【发布时间】:2014-11-23 09:25:53
【问题描述】:

很抱歉,如果这个问题已经得到回答,但我没有找到任何相关信息。当调试器错误地命中断点时,我在 Visual Studio 2013 C++ Win32 应用程序中遇到了一个奇怪的问题。这是一个示例代码:

#include "stdafx.h"


int _tmain(int argc, _TCHAR* argv[])
{
    int a = 3;
    int b = 1;
    for (int i = 3; i >= 1; i--)
        if (i % 2)
            a = a*a;
    b++;
    return b;
}

我在b++ 行设置断点。我熟悉调试 c# 代码时的调试和断点(并且在 c++ 中非常初学者),根据我的经验,只有在 for 循环结束时才应该命中 b++ 行上的断点。然而,每次循环迭代都会命中,但代码(增量)不会执行。 这是带有相关信息的VS的屏幕截图

【问题讨论】:

  • 您是否正在运行发布配置?您的某些行可能已被优化掉并且您的 PDB 中的行号不匹配,这只是一个猜测。出于这个原因,我们经常使用 Noopt 构建,它与 Release 基本相同,但禁用了优化(当然,假设我们不想使用完整的 Debug 配置)。
  • 尝试清理并检查您是否有发布版本。
  • 1) 不,我正在调试模式下运行。 2) result in locals 是正确的,但是此时断点不应该被命中。
  • 我清理了整个解决方案,但没有任何改变,该行上的断点会命中每个循环迭代。当切换到释放模式时——VS 在 return 语句中遇到了不存在的断点。

标签: c++ debugging visual-studio-2013 console-application breakpoints


【解决方案1】:

实际上,这段代码没问题,应该可以按您的预期工作。 VS 允许您在执行块的末尾放置一个断点(在这种情况下,for 循环内的if 语句)。

由于您没有用花括号将if 语句包装起来(如上图所示),VS 假定您在b++ 语句中放置的断点指的是for 执行块的结尾,因此中断,不执行b++ 语句。

【讨论】:

  • 我是否理解正确,如果执行块(循环、if 语句等)没有大括号,那么执行块后的断点意味着该块的结束而不是实际行?
  • 其实是两者的意思,即程序将在该语句处停止,因为它是语句块的结尾,或者您完成了循环并因此到达了该语句。
  • 顺便说一句,根据经验,我建议您始终使用大括号,即使这些不是必需的。这提高了可读性,还可以防止在 for/if 语句下方添加其他语句并期望这些语句成为各自执行块的一部分的愚蠢错误。
  • 谢谢。在 C# 中,我总是使用大括号,但我得到了这个例子。
  • 如果你看一下没有大括号的程序的反汇编(Ctrl-Alt-D),你会看到b++的断点在jmp:而不是mov指令上。如果您再查看带大括号的那个,您会发现 b++ 的断点在 mov 指令上。您可以在反汇编版本中设置断点,使其在循环外停止。
猜你喜欢
  • 1970-01-01
  • 2012-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-25
相关资源
最近更新 更多