断点:使用命中次数、调用堆栈函数和条件在 Visual Studio 调试器中您所需的时间和位置进行中断

为源行、程序集指令和调用堆栈函数设置断点。 指定条件、命中次数和执行位置。 打印跟踪点。 保存并导出断点。

内容

Create breakpoints that break when you want

Set a breakpoint at a source line, assembly instruction, or call stack function

Access the advanced functionality of breakpoints

Specify when a breakpoint breaks by hit count, expression evaluation, execution location, or data change

Print to the Output window with tracepoints

Manage breakpoints in the Breakpoints window

Troubleshoot breakpoints

Breakpoint Glyphs Reference

创建可在需要时中断的断点

标准断点是开发人员的工具箱中最重要的调试技术之一,它会在每次命中源文件位置时中断调试器执行。 Visual Studio 可帮助你超出标准断点,以便创建对执行断点的时间和位置的细化控制。

  • 你可设置当你的程序返回调用堆栈上的函数时暂停执行的运行时断点,并避免长序列的**“跳出”**命令。

  • 如果你怀疑在一定数量的迭代后代码中的循环开始产生错误行为,则可以设置断点,以在指定的命中数传入相关的代码行后停止执行,而不是强制重复按 F5“调试”“继续”)以达到迭代级别。

  • 通过使用代码表达式,你可以指定断点中断的具体条件。

你可使用**“断点”窗口来管理大量断点的状态和行为。 如果你已小心构造断点序列以诊断常见的或特别复杂的问题,则可以使用“断点”**窗口导入和导出命令来保存或共享这些断点。

警告

避免当正在调试混合模式(本机和托管)代码时在系统组件上设置断点。在混合模式调试期间,如果在系统组件上设置断点,则会导致公共语言运行时中断并使调试器停止响应。

在源行、程序集指令或调用堆栈函数处设置断点

  • Set a breakpoint in a source file • Set a breakpoint at a function return in the Call Stack window • Set a breakpoint at an assembly instruction in the Disassembly window

在源文件中设置断点

以下是在源窗口中设置标准断点的两种方法:

  • 在窗口的滚动条槽中双击你想中断的行。

    - 或 -

  • 选择该行并选择 F9

“调用堆栈”窗口中的断点

该断点图标将显示在滚动条槽中。

若要在执行代码期间直观地跟踪断点,请参阅在 Visual Studio 中调试时映射调用堆栈上的方法

返回页首 Set a breakpoint at a source line, assembly instruction, or call stack function

在“调用堆栈”窗口中的函数返回处设置断点

可通过在**“调用堆栈”**窗口中设置断点来中断调用函数返回到的指令或行处的执行。 调试器必须处于中断模式。

  • 打开**“调用堆栈”**窗口(快捷键:Ctrl + Alt + C),并选择要中断的调用函数。

  • 在上下文菜单中选择**“断点”“插入断点”**,或者仅使用快捷键:F9

断点符号出现在函数调用名称旁的左边距中。

“调用堆栈”窗口中的断点

如果打开**“断点”**窗口(快捷键:Ctrl+Alt+B),则该断点显示为一个地址断点,此地址断点具有一个与函数中下一个可执行指令相对应的内存位置。 调试器在指令处中断执行。

“断点”窗口中的调用堆栈断点

若要在执行代码期间直观地跟踪断点,请参阅在 Visual Studio 中调试时映射调用堆栈上的方法

在“反汇编”窗口中的程序集指令处设置断点

若要在程序集指令处设置断点,必须使调试器处于中断模式下。

  1. 打开**“反汇编”**窗口(快捷键:Ctrl + Alt + D)。

  2. 执行下列操作之一:

    1. 在窗口的滚动条槽中双击你想中断的行。

      - 或 -

    2. 选择该行并选择 F9

返回页首 Set a breakpoint at a source line, assembly instruction, or call stack function

访问断点的高级功能

断点上下文菜单

在源窗口、“调用堆栈”窗口或“反汇编”窗口中,打开断点的上下文菜单并选择属性。

在“断点”窗口中,选择断点行并打开上下文菜单。 也可在条件列中直接设置一些条件。

当断点被命中次数、表达式计算、执行位置或数据更改中断时进行指定

  • Specify a hit count at which the breakpoint executes • Specify a breakpoint condition using a code expression • Specify the devices, processes, or threads that a breakpoint executes on • Set a data change breakpoint (native C++ only)

指定断点执行的命中次数

“命中次数”跟踪断点的命中次数。 你设置值和条件,以使满足以下条件之一时执行断点:命中次数等于值、等于指定值的倍数或大于或等于值。 指定命中次数和条件:

  1. 打开“命中次数断点”对话框。

    1. 在源窗口、“反汇编”窗口或“调用堆栈”窗口中,选择包含断点的行,然后选择上下文菜单上的“断点”“命中次数”

      - 或 -

    2. 在**“断点”窗口中,选择一个断点行,然后选择上下文菜单上的“命中次数”**。

      “断点命中次数”对话框

  2. 选择条件并输入命中次数。

命中次数条件有助于在一定数量的迭代中中断循环。 如果你要对断点的命中次数进行计数,也可指定非常大的数量,但不要中断执行。

仅为调试会话保留指定的命中次数。 在调试会话结束时,命中次数将重置为零。

返回页首 Specify when a breakpoint breaks by hit count, expression evaluation, execution location, or data change

使用代码表达式指定断点条件

断点条件是一个到达断点时调试器将计算的表达式。 如果满足条件,调试器将中断执行。

条件可以是调试器能够识别的任何有效表达式。 例如,在一个银行业务程序中,你可以设置 balance < 0 等断点条件。 有关有效表达式的更多信息,请参见调试器中的表达式

指定断点条件

  1. 打开该断点的上下文菜单,然后选择**“条件”**。

  2. 在**“断点条件”对话框中,在“条件”**框中输入有效表达式。

  3. 如果想要在满足表达式时中断,请选择**“为 true”;如果想要在表达式的值已更改时中断,请选择“已更改”**。

直到第一次到达该断点后,调试器才会计算该表达式。 对于本机代码,如果选择**“已更改”,则调试器不会将条件的第一次计算当作一次更改,所以第一次计算时不会命中断点。 对于托管代码,如果选择“已更改”,则选择“已更改”**之后的第一次计算时便会命中断点。

如果在设置断点条件时使用了无效语法,将立即出现警告消息。 如果在指定断点条件时使用的语法有效但语义无效,则在第一次命中断点将出现警告消息。 在这两种情况下,当命中无效断点时,调试器都会中断执行。 只有当条件有效并且条件的计算结果为 false 时,才会跳过断点。

返回页首 Specify when a breakpoint breaks by hit count, expression evaluation, execution location, or data change

指定断点执行的设备、进程或线程

  1. 打开该断点的上下文菜单,然后选择**“筛选器”**。

    “断点筛选器”对话框

  2. 根据对话框说明指定筛选条件。

返回页首 Specify when a breakpoint breaks by hit count, expression evaluation, execution location, or data change

设置数据更改断点(仅限本机 C++)

数据断点可在写入存储在指定内存位置的值时中断执行。 如果只读取而不写入该值,则不会中断执行。 若要设置数据断点,必须使调试器处于中断模式下。

  1. 在**“调试”菜单上,选择“新建断点”“新建数据断点”**。

    - 或 -

    在**“断点”窗口菜单中,选择“新建”“新建数据断点”**。

    数据断点窗口

  2. 在**“地址”**框中,键入内存地址或计算结果为内存地址的表达式。

    例如,键入 &avar,则当变量 avar 的内容更改时中断。

  3. 在**“字节计数”**框中,键入希望调试器监视的字节数。

    例如,如果键入 4,调试器将监视从 &myFunction 开始的四个字节,并在其中有任何字节的值发生更改时中断。

若要设置数据断点,必须使调试器处于中断模式下。

数据断点在下列情况下无效:

  • 如果将未经调试的进程写入内存位置

  • 如果在两个或两个以上的进程间共享该内存位置。

  • 如果该内存位置在内核内进行了更新。 例如,如果将内存传递给 32 位的 Windows ReadFile 函数,则会在内核模式下更新此内存,且调试器不会在执行内存写入操作时中断。

当从一个调试会话转到下一个会话时,变量地址会更改。 因此,数据断点在每个调试会话结束时将被自动禁用。

如果在本地变量上设置数据断点,则在函数结束后,数据断点仍保持启用状态。 但是,设置断点的内存地址将不再具有相同的含义。 因此,此类断点的结果是不可预知的。 如果在局部变量上设置了数据断点,最佳做法是在函数结束前移除或禁用断点。

Visual Studio 支持最多为每个解决方案设置四个数据断点。

返回页首 Specify when a breakpoint breaks by hit count, expression evaluation, execution location, or data change

打印到具有跟踪点的“输出”窗口

“跟踪点”是另一种使用断点的方法。 跟踪点是将消息打印到**“输出”**窗口中的断点。 跟踪点的作用像这种编程语言中的一个临时跟踪语句。

若要打印现有断点处的消息,请打开该断点的上下文菜单并选择**“命中条件”**。

你指定要在**“命中断点时”**对话框中打印的消息。

“命中断点时”对话框

指定消息

使用 DebuggerDisplayAttribute 语法可以在消息中包括编程信息(请参阅 DebuggerDisplayAttribute)。 以下为若干示例:

  • In function '{$FUNC}', on thread '{$TID}'

  • Used variable: {varName}, function name: {functionName($FUNC)}

你可以使用在**“命中断点时”**对话框中描述的任何关键字。 此外,你可以使用未在对话框中显示的其他两个关键字:

  1. $TICK 插入当前 CPU 滴答计数

  2. $FILEPOS 插入当前文件位置

指定跟踪点行为

若要在命中跟踪点时中断执行,请清除**“继续执行”复选框。 选中“继续执行”**时,不会暂停执行。 在这两种情况下,都将打印消息。

禁用跟踪点

若要暂时禁用跟踪点,请清除**“打印消息”**复选框。

在“断点”窗口中管理断点

  • Export and import breakpoints • Label breakpoints

几乎所有设置、配置和管理**“断点”窗口的断点的功能都可以在源窗口、“调用堆栈”窗口和“反汇编”窗口中的单个断点位置处使用。 但“断点”窗口提供了一个中心位置以让你管理全部断点,这在断点非常关键的大型解决方案或复杂的调试方案中特别有用。 如果需要保存或共享一组断点的状态和位置,可以仅从“断点”**窗口保存并导入断点文件。

返回页首 Manage breakpoints in the Breakpoints window

标记断点

断点标签仅用于在**“断点”窗口中对断点列表进行排序和筛选。 若要将标签添加到断点中,请选择断点行,然后在上下文菜单中选择“标签”**。

断点疑难解答

  • The debugger can't determine the source file for a breakpoint • The debugger can't locate the correct version of the source file for a breakpoint • Breakpoints don't work in a DLL

调试器无法确定断点的源文件

如果项目中的两个或更多个源文件具有相同的名称,则调试器在确定在哪个文件中设置断点时可能会遇到问题。 如果所创建的模块与要链接到的调试库的组件名称相同,通常会出现此情况。

若要解决此问题,请选择源窗口中的断点,然后在上下文菜单中选择**“位置”**。

“文件断点”对话框

在**“文件”**框中输入到达正确文件的完整路径

返回页首 Troubleshoot breakpoints

调试器无法找到断点源文件的正确版本

如果源文件已更改,且源与正在调试的代码不再匹配,即使存在源文件,调试器也将查找对应于断点的源文件。

  1. 如果想让 Visual Studio 显示与正在调试的版本不匹配的源代码,请选择**“调试”“选项和设置”。 在“调试”/“常规”页上,清除“仅使用精确匹配原始版本的源代码”**选项。

  2. 你也可将断点绑定到源文件。 选择断点并在上下文菜单中选择**“位置”。 选中“文件断点”对话框中的“允许源代码与原始版本不同”**。

返回页首 Troubleshoot breakpoints

断点在 DLL 中不起作用

当调试器尚未为代码所在的模块加载调试信息时,不能在源文件中设置断点。 征兆可能包括类似**“无法设置断点”**这样的消息。 警告断点标志符号出现在断点位置。 但是,当加载代码时,这些警告断点将成为实际的断点。

返回页首 Troubleshoot breakpoints

断点标志符号引用

源窗口和**“反汇编”**窗口在左侧空白中显示称为标志符号的符号,以此来显示断点位置。 下表描述了这些标志符号。

如果将鼠标光标停在断点标志符号上,将显示可给出断点更多信息的断点提示。 此信息对于错误断点和警告断点来说特别有用。

标志符号

描述

调试标志符号 1

普通断点。 实心的标志符号指示断点已启用。 空心的标志符号指示断点已禁用。

调试标志符号 2

高级断点。 活动/已禁用。 “+”符号指示断点至少有一个附加到它的高级功能(例如条件、命中次数或筛选器)。

调试标志符号 3

映射断点。 活动/已禁用。 断点在 ASP/ASP.NET 代码中设置并映射到对应 HTML 页面中的断点,或者在服务器端脚本文件中设置并映射到对应的客户端脚本文件。

调试标志符号 4

跟踪点。 活动/已禁用。 命中此点则执行指定的操作,但不中断程序的执行。

调试标志符号 5

高级跟踪点。 活动/已禁用。 “+”符号指示跟踪点至少有一个附加到它的高级功能(例如条件、命中次数或筛选器)。

调试标志符号 6

映射跟踪点。 活动/已禁用。 这种跟踪点在 ASP/ASP.NET 代码中设置,它映射到相应 HTML 页中的跟踪点。

调试标志符号 7

断点错误或跟踪点错误。 “X”指示由于错误情况而未能设置断点或跟踪点。

调试标志符号 8

断点警告或跟踪点警告。 感叹号指示由于临时情况而未能设置断点或跟踪点。 通常情况下,这意味着还没有加载断点或跟踪点位置处的代码。 如果附加到某个进程但未加载该进程的符号,也会看到感叹号。 加载代码或符号后,将启用断点,标志符号也将更改。

请参见

概念

在 Visual Studio 中启动、中断、单步执行、通过代码运行和停止调试