阅读本主题,了解 Visual Studio 调试器的一些生产力提示和技巧。 有关调试器的基本功能,请参阅 “首先查看调试器”。 在本主题中,我们将介绍功能导览中未包含的某些区域。
键盘快捷方式
有关与调试相关的最常见键盘快捷方式的列表,请参阅键盘快捷方式中的 “调试 ”部分。
固定数据提示
如果您在调试时经常将鼠标悬停在数据提示框上,那么您可能需要固定变量的数据提示框,以便快速访问。 即使在重启后,变量仍保持固定状态。 若要固定数据提示,请将鼠标悬停在数据提示上时,单击固定图标。 可以固定多个变量。
还可以通过多种其他方式自定义数据提示,例如保持数据提示展开( 粘滞数据提示),或使数据提示透明。 有关详细信息,请参阅 代码编辑器中的数据提示中的“查看数据值”。
编辑代码并继续调试(C#、VB、C++)
在 Visual Studio 支持的大多数语言中,可以在调试会话中编辑代码并继续调试。 若要使用此功能,请在调试器暂停时将光标点击到代码中,进行编辑,然后按 F5、F10或 F11 继续调试。
有关使用功能和功能限制的详细信息,请参阅 “编辑并继续”。
编辑 XAML 代码并继续调试
若要在调试会话期间修改 XAML 代码,请参阅 使用 XAML 热重载编写和调试正在运行的 XAML 代码。
难以重现的调试问题
如果在应用中重新创建特定状态比较困难或耗时,请考虑使用条件断点是否有帮助。 可以使用 条件断点 和筛选断点来避免中断应用代码,直到应用进入所需状态(例如变量存储不良数据的状态)。 可以使用表达式、筛选器、命中计数等设置条件。
创建条件断点
右键单击断点图标(红色球体),然后选择 “条件”。
在 “断点设置” 窗口中,键入表达式。
如果对其他类型的条件感兴趣,请在“断点设置”对话框中选择“筛选器”而不是“条件表达式”,然后按照筛选器提示进行作。
配置数据以在调试器中显示
对于 C#、Visual Basic 和 C++(仅限 C++/CLI 代码),可以告知调试器使用 DebuggerDisplay 属性显示的信息。 对于 C++ 代码,可以使用 Natvis 可视化执行相同的操作。
重复连接到同一应用程序
使用 附加到进程 功能时,可以通过选择 “调试>重新附加到进程 ”(Shift+Alt+P)来快速重新附加到以前附加到的进程。 选择此命令时,调试器将立即尝试附加到之前附加过的最后一个进程,首先尝试匹配之前的进程 ID,如果失败,则匹配之前的进程名称。 如果未找到匹配项,或者如果多个进程具有相同的名称,则会打开 “附加到进程 ”对话框,以便你可以选择正确的进程。
跟踪范围外对象(C#、Visual Basic)
使用调试器窗口(如 “监视 ”窗口)查看变量很容易。 但是,当变量在 “监视”窗口中超出作用域时,你可能会注意到它变为灰色。在某些应用场景中,即使变量超出作用域,变量的值也可能更改,并且你可能希望仔细观察它(例如,变量可能会被垃圾回收)。 可以通过在 “监视 ”窗口中为其创建对象 ID 来跟踪变量。
创建对象 ID
在要跟踪的变量附近设置断点。
启动调试器 (F5)并在断点处停止。
在 “局部变量 ”窗口中找到变量(调试 > Windows > 局部变量),右键单击该变量,然后选择“ 创建对象 ID”。
应该会在“局部变量” $ 窗口中看到 $ 窗口中设置断点来中断调用函数返回到的指令或行处的执行。 此变量是对象 ID。
右键单击对象 ID 变量,然后选择 “添加监视”。
有关详细信息,请参阅 创建对象 ID。
查看函数的返回值
若要查看函数的返回值,请在单步执行代码时查看 自动 窗口中显示的函数。 若要查看函数的返回值,请确保你感兴趣的函数已执行(如果当前在函数调用上停止,请按 F10 一次)。 如果窗口已关闭,请使用“调试 Windows > 自动”>打开“自动”窗口。
此外,还可以在 “即时 ”窗口中输入函数以查看返回值。 (用 调试 > Windows > 即时打开它。)
还可以在“监视”和“即时”窗口中使用伪变量,例如$ReturnValue
。
检查可视化工具中的字符串
使用字符串时,查看整个格式化字符串会很有帮助。 若要查看纯文本、XML、HTML 或 JSON 字符串,请单击放大镜图标,同时将鼠标悬停在包含字符串值的变量上。
字符串可视化工具可以帮助你根据字符串类型确定字符串的格式是否不正确。 例如,空白 值 字段指示可视化工具类型无法识别字符串。 有关详细信息,请参阅 “字符串可视化工具”对话框。
对于在调试器窗口中显示的其他几种类型(例如 DataSet 和 DataTable 对象),还可以打开内置可视化工具。
分析内存使用情况
可以拍摄和比较堆的快照、优化内存使用情况,以及使用内存使用情况工具查找内存泄漏。 有关详细信息,请参阅 “选择内存分析工具”。
创建转储文件
转储文件是一个快照,显示正在执行的进程,以及某个时间点为应用加载的模块。 包含堆信息的转储还包含该应用程序内存的快照。 内存转储主要用于调试开发人员无权访问的机器上的故障。
如果需要保存转储文件,请选择调试 > 另存为转储文件。
若要分析转储文件,请在 Visual Studio 中选择 “文件 > 打开 ”。 若要开始使用转储文件进行调试,请选择“仅托管代码调试”、“仅本机代码调试”、“使用混合代码进行调试”或“托管内存代码调试”。
有关详细信息,请参阅 转储文件。
在处理异常时闯入代码
调试器在遇到未处理的异常时暂停代码执行。 但是,已处理的异常(例如在 try/catch
块中发生的异常)也可能是 bug 的源头,你可能想要调查这些异常发生的时间。 可以通过在“异常设置”对话框中配置选项,将调试器配置为在处理异常时中断程序执行。 通过选择 “调试 > Windows > 异常设置”打开此对话框。
“ 异常设置” 对话框允许你告知调试器在特定异常上中断代码。 在下图中,调试器每当发生 System.NullReferenceException
时就会中断你的代码。 有关详细信息,请参阅 管理异常。
更改执行流
让调试器暂停在某行代码上,用鼠标抓住左侧的黄色箭头指针。 将黄色箭头指针移动到代码执行路径中的不同点。 然后使用 F5 或步骤命令继续运行应用。
通过更改执行流,可以执行诸如测试不同代码执行路径或重新运行代码之类的操作,而无需重启调试器。 有关详细信息,请参阅 移动执行指针。
警告
通常,需要注意此功能,并在工具提示中看到警告。 也可能看到其他警告。 移动指针无法将应用还原到以前的应用程序状态。
调试死锁和竞争条件
如果需要调试多线程应用常见的问题类型,它通常有助于在调试时查看线程的位置。 可以轻松使用源中显示线程按钮来完成此操作。
若要在源代码中显示线程,
调试时,单击“在源中显示线程”按钮,在“调试”工具栏
中显示线程”。
查看窗口左侧的槽。 在此行中,您将看到一个 线程标记 图标
,其外形类似于两条布线。 线程标记指示线程在此位置停止。
请注意,线程标记可能部分被断点隐藏。
将指针悬停在线程标记上。 此时会显示一个 DataTip。 DataTip 告知每个已停止线程的名称和线程 ID 号。
还可以在 “并行堆栈”窗口中查看线程的位置。
使自己更熟悉调试器如何连接到您的应用程序(C#、C++、Visual Basic、F#)
若要附加到你正在调试的应用程序,调试器将加载为该应用的相同版本生成的符号文件(.pdb)。 在某些情况下,对符号文件的了解可能有所帮助。 可以使用 “模块” 窗口检查 Visual Studio 如何加载符号文件。
调试时,通过选择“调试 > Windows > 模块”来打开“模块”窗口。 “模块”窗口可以显示调试器将哪些模块视为用户代码或“我的代码”,以及符号加载的状态。 在大多数情况下,调试器会自动查找用户代码的符号文件,但如果想要单步执行 (或调试) .NET 代码、系统代码或第三方库代码,则需要执行额外的步骤才能获取正确的符号文件。
可以通过右键单击并选择“加载符号”,直接从“模块”窗口中加载符号信息。
有时,应用开发人员会交付没有匹配符号文件的应用(以减少占用空间),但保留生成的匹配符号文件的副本,以便他们可以稍后调试已发布的版本。
若要了解调试器如何将代码分类为用户代码,请参阅 “仅我的代码”。 若要了解有关符号文件的详细信息,请参阅 Visual Studio 调试器中的指定符号(.pdb)和源文件。
了解详细信息
有关其他提示和技巧以及更多详细信息,请参阅以下博客文章: