3.7 — 使用集成调试器:运行和断点

虽然单步执行(在课程 3.6 -- 使用集成调试器:单步执行 中介绍)对于单独检查代码中的每一行很有用,但在大型程序中,即使只是为了到达您想要更详细检查的点,单步执行代码也可能需要很长时间。

幸运的是,现代调试器提供了更多工具来帮助我们高效地调试程序。在本课程中,我们将介绍一些调试器功能,这些功能可以让我们更快地导航代码。

运行到光标处

第一个有用的命令通常称为运行到光标处。此**运行到光标处**命令执行程序,直到执行到达光标选定的语句。然后它将控制权返回给您,以便您可以从该点开始调试。这提供了一种有效的方式来在代码中的特定点开始调试,或者如果已经在调试,则直接移动到您想要进一步检查的某个位置。

对于 Visual Studio 用户

在 Visual Studio 中,可以通过右键单击代码中的语句并从上下文菜单中选择运行到光标处,或者按 Ctrl-F10 键盘组合来访问运行到光标处命令。

对于 Code::Blocks 用户

在 Code::Blocks 中,可以通过右键单击代码中的语句并从上下文菜单中选择运行到光标处,或者选择调试菜单 > 运行到光标处,或者按 F4 快捷键来访问运行到光标处命令。

对于 VS Code 用户

在 VS Code 中,在程序已处于调试状态时,可以通过右键单击代码中的语句并从上下文菜单中选择运行到光标处来访问运行到光标处命令。

让我们使用我们一直在使用的同一个程序来尝试一下

#include <iostream>

void printValue(int value)
{
    std::cout << value << '\n';
}

int main()
{
    printValue(5);

    return 0;
}

只需右键单击第 5 行的任意位置,然后选择“运行到光标处”。

您会注意到程序开始运行,并且执行标记移动到您刚刚选择的行。您的程序已执行到此点,现在正在等待您的进一步调试命令。从这里,您可以单步执行程序,运行到光标处到不同的位置,等等……

如果您运行到光标处到未执行的位置,运行到光标处将简单地运行您的程序直到终止。

继续

一旦您处于调试会话的中间,您可能只想从该点开始继续运行程序。最简单的方法是使用继续命令。**继续**调试命令只是正常继续运行程序,直到程序终止,或者直到有东西触发控制权再次返回给您(例如断点,我们将在本课程后面介绍)。

对于 Visual Studio 用户

在 Visual Studio 中,在程序已处于调试状态时,可以通过调试菜单 > 继续,或者按 F5 快捷键来访问继续命令。

对于 Code::Blocks 用户

在 Code::Blocks 中,在程序已处于调试状态时,可以通过调试菜单 > 启动 / 继续,或者按 F8 快捷键来访问继续命令。

对于 VS Code 用户

在 VS Code 中,在程序已处于调试状态时,可以通过运行菜单 > 继续,或者按F5快捷键来访问继续命令。

让我们测试一下继续命令。如果您的执行标记尚未在第 5 行,请运行到光标处到第 5 行。然后从此处选择继续。您的程序将完成执行然后终止。

启动

继续命令有一个孪生兄弟,名为启动启动命令执行与继续相同的操作,只是从程序的开头开始。它只能在未处于调试会话时调用。

对于 Visual Studio 用户

在 Visual Studio 中,在程序未处于调试状态时,可以通过调试菜单 > 启动调试,或者按 F5 快捷键来访问启动命令。

对于 Code::Blocks 用户

在 Code::Blocks 中,在程序未处于调试状态时,可以通过调试菜单 > 启动 / 继续,或者按 F8 快捷键来访问启动命令。

对于 VS Code 用户

在 VS Code 中,在程序未处于调试状态时,可以通过运行菜单 > 启动调试,或者按F5快捷键来访问启动命令。

如果您在上述示例程序中使用启动命令,它将一直运行而不会中断(除了在VS Code上,因为我们在上一课中设置了stopAtEntry: true)。虽然这可能看起来平淡无奇,但这只是因为我们没有告诉调试器中断程序。我们将在下一节中更好地使用此命令。

断点

本节我们要讨论的最后一个主题是断点。**断点**是一种特殊标记,它告诉调试器在调试模式下运行时在断点处停止程序执行。

对于 Visual Studio 用户

在 Visual Studio 中,您可以通过调试菜单 > 切换断点,或者右键单击语句并从上下文菜单中选择切换断点,或者按 F9 快捷键,或者单击行号左侧(浅灰色区域)来设置或删除断点。

对于 Code::Blocks 用户

在 Code::Blocks 中,您可以通过调试菜单 > 切换断点,或者右键单击语句并从上下文菜单中选择切换断点,或者按 F5 快捷键,或者单击行号右侧来设置或删除断点。

对于 VS Code 用户

在 VS Code 中,您可以通过运行菜单 > 切换断点,或者按F9快捷键,或者单击行号左侧来设置或删除断点。

设置断点时,您将看到出现一种新类型的图标。Visual Studio 使用红色圆圈,Code::Blocks 使用红色八边形(像停止标志)

继续在第 5 行设置一个断点,如上图所示。

现在,选择启动命令让调试器运行您的代码,让我们看看断点是如何工作的。您会注意到,调试器不会一直运行到程序结束,而是在断点处停止(执行标记位于断点图标的顶部)

这就像您已经运行到光标处到此点一样。

断点比运行到光标处有几个优点。首先,断点会使调试器在每次遇到时都将控制权返回给您(与运行到光标处不同,后者每次调用时只运行到光标一次)。其次,您可以设置断点,它将一直存在直到您将其删除,而使用运行到光标处,您每次调用命令时都必须找到要运行到的位置。

请注意,放置在不在执行路径中的行上的断点不会导致调试器暂停代码执行。

让我们看一个略微修改的程序,它更好地说明了断点和运行到光标处之间的区别

#include <iostream>

void printValue(int value)
{
    std::cout << value << '\n';
}

int main()
{
    printValue(5);
    printValue(6);
    printValue(7);

    return 0;
}

首先,启动一个新的调试会话,然后运行到光标处到第 5 行。现在选择继续。程序将继续到结束(它不会再次在第 5 行停止,即使第 5 行再次执行了两次)。

接下来,在第 5 行放置一个断点,然后选择启动。程序将在第 5 行停止。现在选择继续。程序将在第 5 行第二次停止。再次选择继续,它将第三次停止。再按一次继续,程序将终止。您可以看到断点导致程序停止的次数与该行执行的次数相同。

设置下一条语句

还有一个调试命令不常用,但至少值得了解,即使您不会经常使用它。**设置下一条语句**命令允许我们将执行点更改为其他语句(有时非正式地称为跳转)。这可以用于向前跳转执行点并跳过一些否则会执行的代码,或者向后跳转并让已经执行过的东西再次运行。

对于 Visual Studio 用户

在 Visual Studio 中,您可以通过右键单击语句并从上下文菜单中选择设置下一条语句,或者按 Ctrl-Shift-F10 快捷组合来跳转执行点。此选项是上下文相关的,仅在程序已处于调试状态时才出现。

对于 Code::Blocks 用户

在 Code::Blocks 中,您可以通过调试菜单 > 设置下一条语句,或者右键单击语句并从上下文菜单中选择设置下一条语句来跳转执行点。Code::Blocks 没有此命令的键盘快捷方式。

对于 VS Code 用户

在 VS Code 中,您可以通过右键单击语句并从上下文菜单中选择跳转到光标处来跳转执行点。此选项是上下文相关的,仅在程序已处于调试状态时才出现。

让我们看看向前跳转的实际操作

#include <iostream>

void printValue(int value)
{
    std::cout << value << '\n';
}

int main()
{
    printValue(5);
    printValue(6);
    printValue(7);

    return 0;
}

首先,运行到光标处到第 11 行。此时,您应该在控制台输出窗口中看到值5

现在,右键单击第 12 行,然后选择设置下一条语句。这会导致跳过第 11 行而不执行。然后选择继续以完成程序执行。

您的程序输出应如下所示

5
7

我们可以看到printValue(6)被跳过了。

此功能在多种情况下都很有用。

在我们探索基本调试技术时,我们讨论了注释掉函数作为确定该函数是否导致问题的方法。这需要修改我们的代码,并记住稍后取消注释该函数。在调试器中,没有直接的方法可以跳过函数,因此如果您决定这样做,使用设置下一条语句来跳过函数调用是最简单的方法。

向后跳转也很有用,如果我们想观察刚刚执行的函数再次运行,以便我们可以看到它正在做什么。

使用上面的相同代码,运行到光标处到第 12 行。然后设置下一条语句到第 11 行,并继续。程序的输出应该为

5
6
6
7

警告

设置下一条语句命令将更改执行点,但不会更改程序状态。您的变量将保留跳转之前的值。因此,跳转可能会导致您的程序产生与否则不同的值、结果或行为。请谨慎使用此功能(尤其是向后跳转)。

警告

您不应使用设置下一条语句将执行点更改为不同的函数。这可能导致未定义行为,并且很可能导致崩溃。

“单步返回”与通过“设置下一条语句”向后跳转

“单步返回”会回溯所有状态,就像您从未越过该点一样。对变量值或其他程序状态的任何更改都将被撤销。这本质上是单步执行的“撤销”命令。

“设置下一条语句”用于向后跳转时,只改变执行点。对变量值或其他程序状态的任何更改都不会被撤销。

总结

您现在已经了解了使用集成调试器监视和控制程序执行的主要方式。虽然这些命令对于诊断代码流问题(例如,确定是否调用了某些函数)很有用,但它们只是集成调试器带来好处的一部分。在下一课中,我们将开始探索检查程序状态的其他方式,为此您需要这些命令作为先决条件。开始吧!

guest
您的电子邮箱地址将不会被显示
发现错误?请在上方留言!
与勘误相关的评论在处理后将被删除,以帮助减少混乱。感谢您帮助使网站对每个人都更好!
来自 https://gravatar.com/ 的头像与您提供的电子邮箱地址相关联。
有回复时通知我:  
127 评论
最新
最早 最多投票
内联反馈
查看所有评论