在Visual Studio调试器中使用断点

断点是开发人员工具箱中最重要的调试技术之一。您可以在要暂停调试器执行的任何位置设置断点。例如,您可能希望查看代码变量的状态或查看某个断点处的调用堆栈。如果您试图在使用断点时解决警告或问题,请参阅Visual Studio调试器中的断点疑难解答.

注释

如果您知道要解决的任务或问题,但需要知道要使用哪种断点,请参阅常见问题解答-查找调试功能.

在源代码中设置断点

您可以在任何一行可执行代码上设置断点。例如,在下面的C#代码中,可以使用变量赋值在代码行上设置断点(int testInt=1),的对于循环中的任何代码对于循环。如果没有赋值和getter/setter,则不能在方法签名、命名空间或类的声明或变量声明上设置断点。

要在源代码中设置断点,请执行以下操作:

  • 单击代码行旁边的最左边距。您也可以选择行并按九楼,选择调试>切换断点,或单击鼠标右键并选择断点>插入断点。断点在左边空白处显示为一个红点。

对于包括C#在内的大多数语言,断点和当前执行行都会自动突出显示。对于C++代码,可以通过选择工具(或调试) >选项>调试>突出显示断点和当前语句的整个源行(仅限于C++).

设置断点

设置断点

调试时,在执行该行上的代码之前,执行会在断点处暂停。断点符号显示黄色箭头。

在以下示例中的断点处测试Int仍然是3。因此,自从变量初始化(设置为值3)以来,该值没有改变,因为黄色的语句尚未执行。

断点执行已停止

在以下示例中的断点处测试Int仍然是1。因此,自从变量初始化(设置为值1)以来,该值没有改变,因为黄色的语句尚未执行。

断点执行已停止

当调试器在断点处停止时,您可以查看应用程序的当前状态,包括可变值调用堆栈.

下面是一些使用断点的一般说明。

  • 断点是一个开关。你可以点击它,按九楼,或使用调试>切换断点删除或重新插入。

  • 要禁用断点而不删除它,请将鼠标悬停在断点上或右键单击它,然后选择禁用断点。禁用的断点在左边距中显示为空点或断点窗口。要重新启用断点,请将鼠标悬停在断点上或右键单击它,然后选择启用断点.

  • 通过右键单击断点并选择适当的命令,或将鼠标悬停在断点上并选择设置偶像。

断点操作和跟踪点

A类追踪点是将消息打印到输出窗口。跟踪点的作用类似于编程语言中的临时跟踪语句,不会暂停代码的执行。通过在断点设置窗口。有关详细说明,请参阅在Visual Studio调试器中使用跟踪点.

断点条件

您可以通过设置条件来控制断点的执行时间和位置。条件可以是调试器识别的任何有效表达式。有关有效表达式的详细信息,请参见调试器中的表达式.

要设置断点条件,请执行以下操作:

  1. 右键单击断点符号并选择条件(或按中高音+九楼,C). 或者将鼠标悬停在断点符号上,选择设置图标,然后选择条件在中断点设置窗口。

    您还可以右键单击代码行旁边的最左边距并选择插入条件断点从上下文菜单设置新的条件断点。

    您还可以在断点窗口右击断点并选择设置,然后选择条件

    断点设置

    断点设置

  2. 在下拉列表中,选择条件表达式,命中次数,或过滤器,并相应地设置该值。

  3. 选择关闭或按Ctrl键+输入关闭断点设置窗口。或者,从断点窗口,选择好 啊关闭对话框。

带有条件集的断点显示为+源代码中的符号和断点窗户。

创建条件表达式

当您选择条件表达式,您可以在两个条件之间进行选择:是真的更改时。选择是真的当表达式满足时中断,或更改时当表达式的值更改时中断。

在下面的示例中,只有当测试Int4:

断点条件为真

断点条件为true

在下面的示例中,只有当测试Int变化:

断点更改时

断点更改时

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

注释

对于更改时字段中,调试器不会将条件的第一次求值视为更改,因此不会在第一次求价时命中断点。

在条件表达式中使用对象ID(仅限C#和F#)

有时需要观察特定对象的行为。例如,您可能想找出对象多次插入集合的原因。在C#和F#中,可以为的特定实例创建对象ID引用类型,并在断点条件下使用它们。对象ID由公共语言运行库(CLR)调试服务生成,并与对象关联。

要创建对象ID,请执行以下操作:

  1. 在创建对象后的某个位置在代码中设置断点。

  2. 开始调试,当执行在断点处暂停时,选择调试>窗户>当地人(或按Ctrl键+中高音+V(V),L(左))打开当地人窗口。

    在中查找特定对象实例当地人窗口,右键单击它,然后选择生成对象ID.

    你应该看到$在中加上一个数字当地人窗口。这是对象ID。

  3. 在要调查的点上添加一个新断点;例如,当要将对象添加到集合中时。右键单击断点并选择条件.

  4. 在中使用对象ID条件表达式字段。例如,如果变量项目是要添加到集合中的对象,请选择是真的和类型项目==$,其中<n>是对象ID编号。

    在将该对象添加到集合时,执行将中断。

    要删除对象ID,请右键单击当地人窗口并选择删除对象ID.

注释

对象ID创建弱引用,并且不会阻止对象被垃圾收集。它们仅对当前调试会话有效。

设置命中次数条件

如果您怀疑代码中的循环在经过一定次数的迭代后开始表现异常,可以设置断点以在达到该次数后停止执行,而不必反复按五楼以达到该迭代。

低于条件在中断点设置窗口,选择命中次数,然后指定迭代次数。在以下示例中,断点设置为每隔一次迭代命中一次:

断点命中计数

断点命中计数

设置过滤条件

您可以将断点限制为仅在指定的设备上或在指定的进程和线程中触发。

低于条件在中断点设置窗口,选择过滤器,然后输入以下一个或多个表达式:

  • MachineName=“名称”
  • ProcessId=值
  • ProcessName=“name”
  • ThreadId=值
  • ThreadName=“name”

将字符串值括在双引号中。可以使用组合子句&(和),||(或),!(NOT)和括号。

设置函数断点

调用函数时可以中断执行。例如,当您知道函数名称但不知道它的位置时,这很有用。如果您有同名的函数,并且希望中断所有这些函数(例如重载函数或不同项目中的函数),那么它也很有用。

设置函数断点:

  1. 选择调试>新断点>功能断点,或按Ctrl键+K(K),B类.

    您还可以选择新建>功能断点在中断点窗口。

  2. 新功能断点对话框中,在函数名称框。

    缩小功能规范范围:

    • 使用完全限定的函数名。

      例子:命名空间1.X类。方法A()

    • 添加重载函数的参数类型。

      例子:方法A(int,string)

    • 使用“!”符号来指定模块。

      例子:App1.dll!方法A

    • 在本机C++中使用上下文运算符。

      {函数,[module]}[+<从方法开始的行偏移量>]

      例子:{方法A,App1.dll}+2

  3. 语言下拉列表中,选择函数的语言。

  4. 选择好 啊.

使用内存地址设置函数断点(仅限本机C++)

可以使用对象的地址在类的特定实例调用的方法上设置函数断点。例如,给定类型的可寻址对象我的类(_C),可以在我的方法(_M)实例调用的方法。

  1. 在类的实例实例化后的某处设置断点。

  2. 查找实例的地址(例如,0xcccccccc).

  3. 选择调试>新断点>功能断点,或按Ctrl键+K(K),B类.

  4. 将以下内容添加到函数名称框中,然后选择C类++语言。

    (((my_class*)0xccccccc)->我的方法

设置数据断点(.NET Core 3.x或.NET 5+)

当特定对象的属性更改时,数据断点会中断执行。

设置数据断点:

  1. 在一个。NET核心或。NET5+项目,启动调试,并等待到达断点。

  2. 汽车,手表,或当地人窗口中,右键单击属性并选择值更改时中断在上下文菜单中。

    托管数据断点

的数据断点。NET核心和。NET 5+不适用于:

  • 在工具提示、“局部变量”、“自动”或“监视”窗口中不可展开的特性
  • 静态变量
  • 具有DebuggerTypeProxy属性的类
  • 结构内部的字段

有关可以设置的最大数目,请参阅数据断点硬件限制.

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

当存储在指定内存地址的值发生更改时,数据断点会中断执行。如果值已读取但未更改,则执行不会中断。

设置数据断点:

  1. 在C++项目中,启动调试,并等待到达断点。调试菜单,选择新断点>数据断点.

    您还可以选择新建>数据断点在中断点窗口或右键单击汽车,手表,或当地人窗口并选择值更改时中断在上下文菜单中。

  2. 地址框中,键入内存地址或计算为内存地址的表达式。例如,键入&阿瓦尔当变量的内容阿瓦尔变化。

  3. 字节计数下拉列表中,选择您希望调试器监视的字节数。例如,如果您选择4,调试器将监视从开始的四个字节&阿瓦尔如果这些字节中的任何一个改变了值,则中断。

数据断点在以下情况下不起作用:

  • 未被调试的进程写入内存位置。
  • 内存位置在两个或多个进程之间共享。
  • 内存位置在内核中更新。例如,如果内存传递给32位Windows读取文件函数,内存将从内核模式更新,因此调试器在更新时不会中断。
  • 其中,监视表达式在32位硬件上大于4个字节,在64位硬件上超过8个字节。这是x86体系结构的一个限制。

注释

  • 数据断点取决于特定的内存地址。变量的地址会从一个调试会话更改到下一个,因此在每个调试会话结束时都会自动禁用数据断点。

  • 如果在局部变量上设置数据断点,则在函数结束时该断点仍处于启用状态,但内存地址不再适用,因此断点的行为是不可预测的。如果在局部变量上设置数据断点,则应在函数结束之前删除或禁用断点。

数据断点硬件限制

设置数据断点时,Windows内核和底层硬件具有以下限制。限制是指可以设置的最大数据断点数。

处理器体系结构 数据断点限制
x64和x86 4
ARM64型 2
1

设置依赖断点

依赖断点仅在第一次命中另一个断点时中断执行。因此,在调试多线程应用程序等复杂场景中,可以在首次命中另一个断点后配置其他断点。这可以使调试游戏循环或实用程序API等常见路径中的代码变得更加容易,因为这些函数中的断点可以配置为仅在从应用程序的特定部分调用函数时启用。

要设置依赖断点,请执行以下操作:

  1. 将鼠标悬停在断点符号上,选择设置图标,然后选择仅在命中以下断点时启用在“断点设置”窗口中。

  2. 在下拉列表中,选择希望当前断点依赖的前提断点。

选择关闭或按Ctrl+Enter键以关闭“断点设置”窗口。或者,从“断点”窗口中选择好 啊关闭对话框。相关断点

您还可以使用右键单击上下文菜单设置依赖断点。

  1. 右键单击代码行旁边的最左边距并选择插入从属断点从上下文菜单中选择。

    依赖断点上下文

  • 如果应用程序中只有一个断点,则依赖断点不起作用。
  • 如果先决断点被删除,则相关断点将转换为普通行断点。

设置临时断点

此断点只允许中断代码一次。调试时,VisualStudio调试器只会针对此断点暂停一次正在运行的应用程序,然后在命中断点后立即将其删除。

要设置临时断点,请执行以下操作:

  1. 将鼠标悬停在断点符号上,选择设置图标,然后选择点击后删除断点在“断点设置”窗口中。

  2. 选择关闭或按Ctrl+Enter键以关闭“断点设置”窗口。或者,从“断点”窗口中选择好 啊关闭对话框。

    临时断点

您还可以使用右键单击上下文菜单设置临时断点。

  1. 右键单击代码行旁边的最左边距并选择插入临时断点从上下文菜单中选择。

    临时断点上下文

或者,只需使用快捷方式F9+Shift+Alt,T键并在所需的行上设置临时断点。

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

您可以使用断点窗口查看和管理解决方案中的所有断点。这种集中的位置在大型解决方案中特别有用,或者在断点至关重要的复杂调试场景中特别有用。

断点窗口中,您可以搜索、排序、筛选、启用/禁用或删除断点。您还可以设置条件和操作,或添加新的函数或数据断点。

打开断点窗口,选择调试>窗户>断点,或按Ctrl键+中高音+B类.

断点窗口

断点窗口

选择要在中显示的列断点窗口,选择显示列。选择列标题以按该列对断点列表进行排序。

断点标签

可以使用标签对断点窗口。

  1. 要向断点添加标签,请右键单击源代码中的断点或断点窗口,然后选择编辑标签。添加新标签或选择现有标签,然后选择好 啊.
  2. 对中的断点列表进行排序断点窗口,方法是选择标签,条件,或其他列标题。您可以通过选择来选择要显示的列显示列在工具栏中。

导出和导入断点

要保存或共享断点的状态和位置,可以导出或导入它们。

  • 要将单个断点导出到XML文件,请右键单击源代码中的断点或断点窗口,然后选择导出导出选定的。选择导出位置,然后选择保存。默认位置是解决方案文件夹。
  • 要导出多个断点,请在断点窗口中,选择断点旁边的框,或在搜索字段。选择导出与当前搜索条件匹配的所有断点图标,然后保存文件。
  • 要导出所有断点,请取消选择所有框并保留搜索字段空白。选择导出与当前搜索条件匹配的所有断点图标,然后保存文件。
  • 要导入断点,请在断点窗口中,选择从文件导入断点图标,导航到XML文件位置,然后选择正常开放.

从调试器窗口设置断点

还可以从调用堆栈拆卸调试器窗口。

在“调用堆栈”窗口中设置断点

要在调用函数返回的指令或行处中断,可以在调用堆栈窗口。

要在“调用堆栈”窗口中设置断点,请执行以下操作:

  1. 要打开调用堆栈窗口中,调试期间必须暂停。选择调试>窗户>调用堆栈,或按Ctrl键+中高音+C.

  2. 调用堆栈窗口中,右键单击调用函数并选择断点>插入断点,或按九楼.

    在调用堆栈的左边距中,函数调用名称旁边会出现一个断点符号。

调用堆栈断点出现在断点窗口作为地址,其内存位置对应于函数中的下一条可执行指令。

调试器在指令处中断。

有关调用堆栈的更多信息,请参阅如何:使用“调用堆栈”窗口.

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

在“反汇编”窗口中设置断点

  1. 要打开拆卸窗口中,调试期间必须暂停。选择调试>窗户>拆卸,或按Ctrl键+中高音+D类.

  2. 拆卸窗口中,单击要中断的指令的左边距。您也可以选择它并按九楼,或右键单击并选择断点>插入断点.