断点是开发人员的工具箱中最重要的调试技术之一。 若要暂停调试程序执行所需的位置设置断点。 例如,你可能想要查看代码变量的状态或查看调用堆栈的某些断点。

01 在源代码中设置断点

可以在任意可执行代码行上设置断点。 例如,在以下 C# 代码,可以设置断点在变量声明for循环中或内的任何代码for循环。 命名空间或类声明或方法签名,无法设置断点。

若要在源代码中设置断点,请单击代码行旁边的最左侧边距中。 您还可以选择行,然后按F9,选择调试 > 切换断点,或右键单击并选择断点 > 插入断点。 断点显示为左边距中的一个红点。

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

当调试器在断点处停止时,您可以查看应用程序,包括变量值和调用堆栈的当前状态。 有关调用堆栈的详细信息,请参阅如何:使用调用堆栈窗口

  • 断点是一个触发器。 您可以单击它,请按F9,或使用调试 > 切换断点删除或重新插入。

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

  • 设置条件和操作、 添加和编辑标签,或将断点导出,右键单击该和选择合适的命令,或将鼠标悬停其上,然后选择设置图标。

02 调用堆栈窗口中设置断点

若要中断的指令或调用函数返回到的行处,可以设置断点调用堆栈窗口。

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

  1. 若要打开调用堆栈窗口中,您必须在调试期间暂停。 选择调试 > Windows > 调用堆栈,或按Ctrl + Alt+C。

  2. 在中调用堆栈窗口中,右键单击调用函数,然后选择断点 > 插入断点,或按F9.

    调用堆栈的左边距中的函数调用名称旁边会显示一个断点符号。

调用堆栈断点显示在断点窗口具有对应于在函数中的下一步可执行指令的内存位置的地址。

调试器在指令处中断。

03 在反汇编窗口中设置断点
  1. 若要打开反汇编窗口中,您必须在调试期间暂停。 选择调试 > Windows > 反汇编,或按Alt + 8。

  2. 在中反汇编窗口中,单击想要中断的指令的左边距中。 此外可以选择它,然后按F9,或右键单击并选择断点 > 插入断点。

04 设置函数断点

当调用函数,可以中断执行。

若要设置函数断点:

  1. 选择调试 > 新断点 > 函数断点,或按Alt +F9 > Ctrl+B。

    您还可以选择新建 > 函数断点中断点窗口。

  2. 在中新函数断点对话框中,输入中的函数名称函数名称框。

    若要缩小范围的函数规范:

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

      示例:Namespace1.ClassX.MethodA()

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

      示例:MethodA(int, string)

    • 使用 ! 符号指定模块。

      示例:App1.dll!MethodA

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

      {function, , [module]} [+<line offset from start of method>]

      示例:{MethodA, , App1.dll}+2

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

  4. 选择 确定。查看编辑器,所有 Draw() 方法处都以自动插入了断点。

05 设置数据断点 (.NET Core 3.0 或更高版本)

为特定对象的属性发生更改时,数据断点中断执行。

若要设置数据断点

  1. 在.NET Core 项目中,开始调试,并等待,直到到达一个断点。

  2. 在自动,监视,或局部变量窗口中,右键单击一个属性,然后选择值更改时中断的上下文菜单中。

在.NET Core 中的数据断点不适用于:

  • 不是可扩展的工具提示中,局部变量,自动或监视窗口属性
  • 静态变量
  • 使用 DebuggerTypeProxy 特性类
  • 在结构内的字段
06 在“断点”窗口中管理断点

可以使用断点窗口来查看和管理你的解决方案中的所有断点。 此集中的位置是在大型解决方案中,或对于复杂断点非常关键的调试方案尤其有用。

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

若要打开断点窗口中,选择调试 > Windows > 断点,或按Alt+F9或Ctrl+Alt+B。

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

断点标签

可以使用标签进行排序和筛选列表中的断点断点窗口。

1、若要将标签添加到断点中,右键单击该断点的源代码中或断点窗口中,并选择编辑标签。 添加新标签或选择一个现有证书,然后选择确定。

2、对在断点列表进行排序断点通过选择窗口标签,条件,或其他列标题。 可以选择要通过选择显示的列显示列工具栏中。

07 断点条件

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

若要设置断点条件:

  1. 右键单击断点符号,然后选择条件。 或悬停在断点符号,选择设置图标,并选择条件中断点设置窗口。

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

  1. 在下拉列表中,选择条件表达式,命中计数,或筛选器,并相应地设置值。

  2. 选择关闭或按Ctrl+Enter关闭断点设置窗口。 或者,从断点窗口中,选择确定关闭对话框。

条件表达式

当选择条件表达式,可以选择两个条件:为 true或发生更改时。 选择如此时,满足表达式时中断或发生更改时表达式的值已更改时中断。

1、示例1,设置条件表达式为 true, index == 1

按下F5,启动调试,由于第一次 index 等于0,所以37行断点没有命中,直接走到43行的正常断点处。

第一次循环结束后,index的值增加了1,等于1。进入到第二次循环时,按下F5,由于 index = 1,满足设置的表达式,所以命中了37行的断点。

第二次循环结束后,index的值增加了1,等于2。进入到第三次循环时,按下F5,由于 index = 2,不满足设置的表达式,所以没有命中37行的断点,直接走到43行的正常断点处。

2、示例2:设置条件表达式为 更改时, index

按下F5,启动调试,由于第一次 index 等于0,第一次进入循环,结束前 index的值未改变仍然为0,没有改变,所以37行断点没有命中,直接走到43行的正常断点处。

第一次循环结束后,index的值增加了1,等于1。进入到第二次循环时,按下F5,由于 index = 1,值更改了,满足设置的条件,所以命中了37行的断点。

第二次循环结束后,index的值增加了1,等于2。进入到第三次循环时,按下F5,由于 index = 2,值更改了,满足设置的条件,所以命中了37行的断点。

如果使用无效语法设置断点条件,则会显示警告消息。 如果在指定断点条件时使用的语法有效但语义无效,则在第一次命中断点将出现警告消息。 在任一情况下,调试器将中断时它会命中断点无效。 仅在条件有效且计算结果为 false时才会跳过断点。

不同编程语言的“更改时”字段的行为不同 :

对于本机代码,调试器不会考虑更改,因此不会命中第一次计算断点条件的第一次计算。

对于托管代码,调试器命中断点后第一次计算发生更改时处于选中状态。

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

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

创建对象 ID

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

2、开始调试,并在断点处暂停执行,选择调试 > Windows > 局部变量Alt+ 4以打开局部变量窗口。

查找特定对象实例在局部变量窗口中,右键单击它,然后选择创建对象 ID

应该会在“局部变量” $ 窗口中看到, 窗口中设置断点来中断调用函数返回到的指令或行处的执行。 这就是对象 ID。

展开名称,看到 $1 与 tri 对象完全相同

以同样的方式给 rec、cir、shapes 对象分别创建对象ID,分别对应 $2  $3  $4

3、在该对象添加到集合处, 右键单击该断点并选择“条件” 。

4、在“条件表达式”字段中使用对象 ID 。 例如,如果变量item是要添加到集合中,选择的对象为 true并键入item == $<n > ,其中<n > 的对象 ID 号.

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

tri 对象添加到集合处,设置条件为 tri == $1

rec 对象添加到集合处,设置条件为 rec == $2

cir 对象添加到集合处,设置条件为 rec == $3

按下F5继续运行,

代码走到61行时,断点变成黄色箭头,鼠标悬浮在黄色箭头上,提示如下,条件表达式计算结果为 true。所以命中61行的断点。

按下F5继续运行,

代码走到62行时,断点变成黄色箭头,鼠标悬浮在黄色箭头上,提示如下,条件表达式计算结果为 true。所以命中62行的断点。

按下F5继续运行,

代码走到63行时,断点变成黄色箭头,鼠标悬浮在黄色箭头上,提示如下,条件表达式计算结果为 true。所以命中63行的断点。

如果将61行的条件设置为 tri == $2。根据上述的生成的对象ID,该表达式返回false。

再次F5,运行到61行时,提示报错。因为 tri 是 Triangle 类的对象,$2 是 Rectangle 类的对象创建的ID,所以无法进行 == 运算符的比较。调试器报错。

但是按下F5,仍然可以继续运行。

如果把61行的条件表达式修改为 tri.Equals($2),再次调试时,由于该表达式返回false,所以没有命中61行的断点。直接跳到62行。

若要删除对象 ID,请右键单击中的变量局部变量窗口,然后选择删除对象 ID。

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

命中次数

如果你怀疑你的代码中的循环开始产生错误行为在一定数量的迭代后,可以设置一个断点以停止执行的命中数,而无需重复按该数后F5来访问该迭代。

下列条件中断点设置窗口中,选择命中计数,然后指定迭代数。 在以下示例中,断点设置为其他每次迭代命中:

F5调试,第一次 i = 0,不是 testInt 的2倍整数,所以没有命中74行的断点,直接跳到76行。

当 testInt的值为 2、4、16、22、46时,都能命中74行的断点。

筛选器

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

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

  • MachineName = "name"
  • ProcessId = value
  • ProcessName = "name"
  • ThreadId = value
  • ThreadName = "name"

将字符串值放在双引号内。 可以使用 & (AND)、 || (OR)、 ! (NOT) 和括号合并子句。

提醒:断点条件 模式下进行调试,不能按F10,只能按F5进行调试才能看到实际效果。

08 断点操作和跟踪点

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

若要设置跟踪点:

  1. 右键单击断点并选择操作。 或者,在断点设置窗口中,悬停在所需断点,选择设置图标,,然后选择操作。

  2. 输入中的消息将消息记录到输出窗口字段。 消息可以包含通用文本字符串,值的变量或表达式括在大括号和格式说明符 (C#C++) 的值。

    此外可以在消息中使用以下特殊关键字:

    • $ADDRESS -当前指令
    • $CALLER -调用函数名
    • $CALLSTACK -调用堆栈
    • $FUNCTION -当前函数名
    • $PID -进程 id
    • $PNAME -进程名称
    • $TID -线程 id
    • $TNAME -线程名称
    • $TICK -选中计数 (从 Windows GetTickCount)
  3. 若要打印到的消息输出但不会中断,选择窗口继续执行复选框。 若要打印在跟踪点的消息和中断执行,请清除该复选框。

跟踪点显示为红色方块中的源代码的左边距和断点windows。

按下F5,运行结束后,查看【输出】窗口

09 断点警告

断点在调试时,有两个可能的可视状态: 一个实心的红色圆和 (白色填充) 空心圆。 如果调试器能够成功在目标进程中设置断点,它将保持一个实心的红色圆。 如果断点是空心圆,禁用断点,或尝试设置断点时出现警告。 若要确定的不同,断点上悬停并查看是否存在一条警告。

以下两个部分介绍重要警告以及如何解决这些问题。

“尚未为此文档加载任何符号”

转到模块窗口 (调试 > Windows > 模块) 并检查是否为你的模块加载。

  • 如果加载你的模块,则检查符号状态列,以查看是否已加载符号。

    • 如果还未加载符号,检查符号状态来诊断问题。 从上下文菜单中的模块上模块窗口中,单击符号加载信息... 若要查看其中调试器尝试并加载符号。 有关加载符号的详细信息,请参阅指定符号 (.pdb) 和源文件
    • 如果已加载符号,PDB 不包含有关源文件的信息。 以下是几个可能的原因:
      • 如果最近添加的源文件,确认正在加载的模块的最新版本。
      • 可以创建使用去除的 Pdb /PDBSTRIPPED链接器选项。 去除的 Pdb 不包含源文件信息。 确认你正在使用完整 PDB 和不去除的 PDB。
      • PDB 文件部分已损坏。 删除文件,并执行干净的生成的模块来尝试解决此问题。
  • 如果你的模块未加载,请检查以下内容来查找原因:

    • 确认您正在调试的正确过程。
    • 请检查你正在调试的代码正确的类型。 您可以了解哪种代码将调试器配置为在调试进程窗口 (调试 > Windows > 进程)。 如果想要调试 C# 代码,例如,确认是否为适当类型的.NET Framework 配置您的调试器 (例如,托管 (v4*) 与托管 (v2*/v3*) 与托管 (CoreCLR))。

"… 当前源代码是从...中内置的版本不同"

如果源文件已更改,并且源与正在调试的代码不再匹配,调试器不会设置断点在代码中默认情况下。 通常情况下,此问题发生时更改源文件,但不重新生成的源代码。 若要解决此问题,重新生成项目。 如果生成系统认为该项目已经是最新但没有,可以强制项目系统在重新生成通过再次保存源文件或通过清除项目的生成输出生成前。

在极少数情况下,你可能想要调试而无需匹配的源代码。 调试没有匹配的源代码可以令人混淆的潜在顾客调试体验,因此请确保这是你想要继续操作。

若要禁用这些安全检查,请执行以下操作:

  • 若要修改单个断点,请将鼠标悬停在编辑器中的断点图标,然后单击设置 (齿轮) 图标。 查看窗口添加到在编辑器中。 在查看窗口顶部,没有指示的断点的位置的超链接。 单击超链接,以允许修改的断点位置,然后检查允许源代码与原始不同。
  • 若要修改此设置对所有断点,请转到调试 > 选项和设置。 在 “调试”/“常规” 页上,清除 “要求源文件与原始版本完全匹配” 选项。 请务必重新启用此选项,在完成时调试。

10 断点已成功设置 (无警告),但未命中

本部分提供信息以对问题进行故障排除时调试器未显示任何警告 – 断点是一个实心的红色圆时主动进行调试,但未命中断点。

下面是要检查的几个事项:

  1. 如果在多个进程或多台计算机运行你的代码,请确保你正在调试的正确的进程或计算机。
  2. 确认你的代码正在运行。 若要测试你的代码运行,将调用添加到System.Diagnostics.Debugger.Break(C#/VB) 或__debugbreak(C++) 到在您尝试设置了断点,然后重新生成你的项目的代码行。
  3. 如果你正在调试优化的代码,请确保在其中设置断点的函数不被内联到另一个函数。Debugger.Break如何工作的上一个检查中所述的测试,测试以及此问题。
11 删除了断点,但在再次启动调试时继续命中该断点
如果在调试时删除了断点,可能在下一步启动调试的时再次命中该断点。 要停止命中此断点,请确保从 “断点” 窗口删除该断点的所有实例。

Visual Studio 调试系列3 断点的更多相关文章

  1. Visual Studio 调试系列6 监视变量(使用监视窗口和快速监视窗口)

    系列目录     [已更新最新开发文章,点击查看详细] 当你进行调试时,可以使用 监视窗口 和 快速监视窗口 来监视变量和表达式. 仅在调试会话期间,这两个窗口才可用. 监视窗口可以在调试时一次显示多 ...

  2. Visual Studio 调试 ---- 系列文章

    调试是软件开发过程中非常重要的一个部分,它具挑战性,但是也有一定的方法和技巧. Visual Studio 调试程序有助于你观察程序的运行时行为并发现问题. 该调试器可用于所有 Visual Stud ...

  3. Visual Studio 调试系列12 远程调试部署在远程计算机IIS上的ASP.NET应用程序

    系列目录     [已更新最新开发文章,点击查看详细] 要调试已部署到IIS的ASP.NET应用程序,请在部署应用程序的计算机上安装并运行远程工具,然后从Visual Studio附加到正在运行的应用 ...

  4. Visual Studio 调试系列10 附加到正在运行的进程

    系列目录     [已更新最新开发文章,点击查看详细] 可将 Visual Studio 调试器附加到本地或远程计算机上正在运行的进程. 进程运行后,在 Visual Studio 中选择“调试” & ...

  5. Visual Studio 调试系列9 调试器提示和技巧

    系列目录     [已更新最新开发文章,点击查看详细] 01 固定数据提示 如果你在调试时,经常将鼠标悬停在数据提示上,就可能想固定变量的数据提示,方便自己随时查看. 即使在重新启动后,固定的变量也能 ...

  6. Visual Studio 调试系列1 Debug 与 Release 模式

    系列目录     [已更新最新开发文章,点击查看详细] Debug 模式 Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序. 在Debug模式下调试,可以在断点处看到 ...

  7. Visual Studio 调试系列2 基本调试方法

    系列目录     [已更新最新开发文章,点击查看详细] 在 Visual Studio 上下文中,当调试应用时,这通常意味着你在附加了调试器的情况下(即在调试器模式下)运行应用程序. 执行此操作时,调 ...

  8. Visual Studio 调试系列4 单步后退来检查旧应用状态(使用使用 IntelliTrace 窗口)

    系列目录     [已更新最新开发文章,点击查看详细] IntelliTrace 后退会在每个断点处及调试器步骤事件发生时自动拍摄应用程序的快照. 凭借记录的快照便可以返回到上一个断点或步骤,并查看当 ...

  9. Visual Studio 调试系列11 远程调试

    系列目录     [已更新最新开发文章,点击查看详细] 你可以调试已部署在另一台计算机的 Visual Studio 应用程序. 要进行此操作,可使用 Visual Studio 远程调试器. 01 ...

随机推荐

  1. 截图自动添加水印图片工具 pickpick设置中文语言

    推荐一款截图工具,主要是可以截图自动带水印,效果不错 最近发现我的不少文章被转载的到处都是.乱七八糟,这个功能后续准备做个水印用起来,感觉不错 主角介绍 首先介绍下主角 PickPick

  2. C# 爬虫相关的、可供参考的开源项目

    1. Abots https://github.com/sjdirect/abot/ 2. DotnetSpider https://github.com/dotnetcore/DotnetSpide ...

  3. vsdbg 下载方法 使用下载工具下载后手动安装

    vsdbg国内下载太慢了,这里提供一个使用下载工具下载后,手动安装的处理方法 查看vs build控制台输出: 1>C:\WINDOWS\System32\WindowsPowerShell\v ...

  4. Laravel应用 -- 脚本任务

    大多数项目在业务发展过程中,都需要修复历史数据和定时任务来完成一些业务逻辑,这部分通常都需要通过脚本来完成,一般的框架爱也都提供这部分的功能,学习并使用是工作中的基本要求. 基本流程 commands ...

  5. 高性能TcpServer(C#) - 1.网络通信协议

    高性能TcpServer(C#) - 1.网络通信协议 高性能TcpServer(C#) - 2.创建高性能Socket服务器SocketAsyncEventArgs的实现(IOCP) 高性能TcpS ...

  6. 使用jqPrint.js调用浏览器打印界面,打印网页中的某一部分该部分含有ECharts图表

    1.准备好js文件(我用的是谷歌浏览器) 这个文件是为了防止你的jQuery版本过高而不适配的问题 这是调用浏览器打印的js插件 2.引入js文件 <script src="js/jq ...

  7. Arduino+esp8266-01+舵机 制作基于局域网的遥控门禁

    这个最终的效果呢,就是可以通过手机连接上esp8266创建的wifi,然后连接其创建的服务器,发送特定指令就可实现遥控开门 (做工比较粗糙还请不要见笑...) 一.原理 其实这个一看就会明白,非常简单 ...

  8. leetcode - 使用栈实现队列的特性

    使用栈实现队列的特性 使用栈实现队列的下列操作: push(x) -- 将一个元素放入队列的尾部. pop() -- 从队列首部移除元素. peek() -- 返回队列首部的元素. empty() - ...

  9. Visual Studio Code 远程开发探秘

    摘要: IDE新时代! 作者:SHUHARI 的博客 原文:Visual Studio Code 远程开发探秘 Fundebug按照原文要求转载,版权归原作者所有. 在以前的文章 有趣的项目 - 在浏 ...

  10. centos7 升级php7 添加配置epel源 报错:Cannot retrieve metalink for repository: epel. Please verify its path and try again

    文章来自:循序渐渐linux:基础知识 一书 7.3章LAMP服务器搭建 日常故障 centos上好多软件升级需要配置epel源 其中有一点小插曲 需要手动更改 1.很多时候,对PHP环境要求较新的版 ...