检查暂停的程序
最后修改时间:2023 年 10 月 30 日调试工具窗口:查看 | 工具窗口 | 调试或Alt05
调试器会话启动后,将出现调试工具窗口,程序将正常运行,直到发生以下情况之一:
之后,程序被挂起,允许您检查其当前状态,控制其进一步执行,并在运行时测试各种场景。
检查帧
程序的状态由帧表示。当程序挂起时,当前帧堆栈将显示在“调试”工具窗口的“帧”选项卡上。
帧对应于活动的方法或函数调用。它存储被调用方法或函数的局部变量、其参数以及启用表达式求值的代码上下文。
为了更好地理解帧的概念,让我们看看程序运行时会发生什么。程序的执行从该main
方法开始,依次调用其他方法。这些方法中的每一个都可能执行更多的方法调用。每个方法调用的局部变量和参数集由一个框架表示。每次调用方法时,都会将一个新帧添加到堆栈顶部。当方法执行完成时,相应的帧将从堆栈中删除(以后进先出的方式)。
提示
当您选择一个框架时,相应的文件将在预览选项卡中打开,这意味着当您离开该框架时它将关闭。要在常规选项卡中打开文件,请双击该框架。要更改此行为,请单击“调试”工具窗口工具栏上的“显示选项菜单” ,然后选择“在预览选项卡中打开文件”。
检查帧可以帮助您了解为什么将特定参数传递给方法以及调用者在调用时的状态。
每个线程附近的图标指示线程相对于当前调试会话的状态。
图标 | 描述 |
---|---|
当前线程处于挂起状态。 | |
活动线程。 | |
已到达当前断点的线程。 | |
一个挂起的线程。当线程被调试器暂停时,线程被标记为暂停。 | |
冻结的线程。当线程被手动暂停时,它们被标记为冻结。 |
隐藏库中的框架
如果您的程序使用外部库,并且您想要省略在库类中进行的调用,请单击“框架”窗格右上角的“隐藏库中的框架”按钮。
将堆栈复制到剪贴板
要复制当前线程的调用堆栈,请右键单击“框架”选项卡上的任意位置,然后选择“复制堆栈”。
导出线程
如果您需要获取包含每个线程的状态及其堆栈跟踪的报告,请使用“导出线程”选项。当您需要以文本格式共享有关线程的信息时,这非常有用。
右键单击“框架”窗格上的任意位置,然后从菜单中选择“导出线程” 。
要将报告另存为文本文件,请在“导出线程”对话框中指定文件路径,然后单击“保存”,或单击“复制”将其复制到剪贴板。
检查/更新变量
变量选项卡显示所选框架/线程中的变量列表。检查变量可以帮助您理解程序为何以某种方式运行。
提示
请注意变量的范围和生命周期。如果列表中不存在变量,则意味着该变量超出了当前执行点的当前帧的范围。
每个变量左侧的图标指示其类型。
引脚字段
如果某个对象有多个字段,您可以固定其中一些字段,以便它们始终显示在列表顶部。相同的优先级将适用于此类的其他实例。
在“变量”窗格中,单击指示变量类型的图标。
固定字段后,蓝色旗帜会取代原始图标。要取消固定该字段,请单击此标志。
复制变量
检查变量时,您可能需要复制变量名称或值以将其粘贴到其他位置或将其与另一个变量进行比较。
要复制变量所保存的值,请右键单击该变量并选择“复制值” 。对于 以外的类型,将复制表示形式。Ctrl0C
String
toString
要复制变量的名称,请右键单击该变量并选择复制名称。
与剪贴板比较变量
当您需要将变量值与其他值进行比较时,请使用“与剪贴板比较值”选项。例如,当变量包含长字符串并且您需要将其与另一个长字符串进行比较时,这很有用。
复制要比较的内容(例如,从文本文件)。
在“变量”选项卡中,右键单击要比较的变量,然后选择“与剪贴板比较值”。
检查打开的差异查看器中的差异。有关有效使用差异查看器的更多信息,请参阅比较文件和文件夹主题。
在专用对话框中查看变量
IntelliJ IDEA 允许您在专用对话框中检查变量。当您需要跟踪某些变量(或其引用的对象)并同时能够在帧和线程之间导航时,这非常有用。
右键单击变量或监视并选择“检查”。
将变量视为数组
在“调试”工具窗口的“变量”选项卡中,选择一个数组或一个 DataFrame。
单击右侧的链接“View as Array/View as DataFrame” 。
或者,您可以从上下文菜单中选择“查看为数组”或“查看为数据帧” 。
出现数据视图工具窗口。
设置变量值
如果您想测试程序在某些条件下的行为或在运行时修复其当前行为,您可以通过设置/更改变量值来实现。
选择一个变量并按。或者,从上下文菜单中选择设置值。F2
输入变量的值并按。Enter
笔记
由于 GDB/LLDB 限制,您无法为
std::string
变量设置值。
导航至源代码
如果您需要查看声明某些变量或类的源代码,您可以直接从“变量”窗格移至那里。
要导航到声明该变量的代码,请右键单击该变量并选择“跳转到源” 。F4
要导航到变量类型的类声明,请右键单击该变量并选择跳转到类型源 。ShiftF4
要从堆栈跟踪元素导航到方法主体,请单击“变量”窗格上堆栈跟踪元素附近的“导航”。
检查对象引用
IntelliJ IDEA 为您提供有关当前现有对象的信息,这些对象保存对“变量”选项卡上的对象的引用。该功能还可以检测间接引用,例如使用外部变量的匿名类中的引用。
要查看引用对象的列表,请右键单击“变量”选项卡上的变量,然后选择“显示引用对象”。
“引用对象”对话框打开,允许您检查对选定对象的引用以及对引用对象本身的引用。
当您需要某种类型的所有现有对象的摘要时,可以使用“调试”工具窗口的“内存”选项卡获取它。
此外,您还可以配置不同类型的显示方式。例如,您可以使用“toString”表示形式或创建自定义渲染器。
评估表达式
IntelliJ IDEA 允许您在调试会话期间评估表达式,以获得有关程序状态的更多详细信息或在运行时测试各种场景。
笔记
计算表达式时,请注意变量范围和生命周期。所有表达式都在当前执行点的上下文中进行计算。
在编辑器中评估简单表达式
要快速计算表达式,请在编辑器中指向它。请注意,方法调用不能以这种方式进行评估。
指向要计算的表达式。表达式的结果出现在工具提示中。
要查看结果对象的子元素,请单击或按。CtrlF1
如果您发现价值工具提示分散了您的注意力,您可以增加延迟或完全禁用它们。为此,请在“设置”对话框 ( ) 中,转到“构建、执行、部署”| 调试器| 数据视图并根据需要设置显示值工具提示和值工具提示延迟选项。CtrlAlt0S
在编辑器中计算复杂表达式
如果您想要计算涉及方法调用的代码中的表达式,或者想要具体了解要计算表达式的哪一部分,请使用“快速计算表达式”选项。
笔记
仅当程序在遇到断点后暂停(不是手动暂停)时,此选项才可用。
将插入符号放在表达式上(以计算最接近的匹配表达式)或选择其中的一部分(如果您想具体了解要计算复杂表达式的哪一部分)。
单击运行 | 调试操作| 快速评估表达 。或者,按住并单击所选内容。CtrlAltF8Alt
笔记
如果从表达式调用的方法内有断点,它们将被忽略。
提示
调用方法时,请确保您了解它们可能的副作用(例如,更改外部变量),因为它们可能会改变程序流程或结果。
int hasSideEffects() { // returns the number of entries in the list someVariable++; return list.size(); }
在示例中, 的值
someVariable
将随着每一步递增,这可能会影响程序的行为。
您可以将快速评估配置为只需选择一段代码即可对其进行操作(无需使用菜单/快捷方式)。请小心使用此选项,因为启用它时您可能会意外调用方法。
要配置代码选择的快速评估,请转至设置| 构建、执行、部署 | 调试器| 数据视图并将“在代码选择选项上显示值工具提示”设置为首选。
计算任意表达式
计算任意表达式是最灵活的计算选项。它允许您评估任何代码,只要它位于当前帧的上下文中即可。使用它,您可以计算声明、方法调用、开关表达式、匿名类、lambda、循环等。
使用此功能可以获得有关程序当前状态的附加信息,并在同一调试会话中测试各种场景。通过减少必须运行的会话数量,可以节省大量时间。
笔记
仅当程序在遇到断点后暂停(不是手动暂停)时,此选项才可用。
计算任意表达式的最快方法是将其输入到“变量”窗格的表达式字段中,然后按Enter
结果显示在正下方。您还可以通过单击表达式字段的右侧部分将表达式添加到监视中。
如果您想评估长代码块,您可能需要使用专用对话框:
在专用对话框中评估表达式
如果您想从当前位于您面前的某个表达式或变量开始(例如,在编辑器中或“变量”窗格中),请选择它。
单击运行 | 调试操作| 评估表达 。该快捷方式可能在 Ubuntu 上不起作用(为了正确操作,请调整快捷方式配置)。AltF8
在“评估”对话框中,修改选定的表达式或在“表达式”字段中输入新表达式。单击展开 以修改多行代码片段。ShiftEnter
笔记
请记住,在表达式求值后,表达式主体中声明的任何变量都会超出范围。
单击评估(对于多线模式)。表达式结果出现在结果字段中。CtrlEnter
表达式的结果取自 return 语句。当没有 return 语句时,结果取自最后一行代码(它甚至不必是表达式:单个文字也可以)。当没有有效行可从中获取值时,结果为
undefined
。如果无法计算指定的表达式,结果字段会指示原因。
笔记
如果从表达式调用的方法内有断点,它们将被忽略。
提示
调用方法时,请确保您了解它们可能的副作用(例如,更改外部变量),因为它们可能会改变程序流程或结果。
int hasSideEffects() { // returns the number of entries in the list someVariable++; return list.size(); }
在示例中, 的值
someVariable
将随着每一步递增,这可能会影响程序的行为。
“评估”对话框是非模式的,因此您可以将焦点切换回编辑器以复制其他变量和表达式。如有必要,您还可以打开多个评估对话框。
查看内联值
IntelliJ IDEA 在变量的用法旁边显示变量的值。
变量值更改后,内联视图将使用新值进行更新并更改其颜色。
如果一行包含对对象的引用,您可以直接在编辑器中检查其字段。从此弹出窗口中,您还可以更改变量值并添加内联监视。
提示
您可以使用自定义类型渲染器更改特定类的文本表示形式。
默认情况下启用内联视图。要关闭它,请在“设置”对话框 ( ) 中,转到“构建、执行、部署”| 调试器| 数据视图并禁用显示内联值选项。CtrlAlt0S
添加内联手表
如果您希望某个表达式的结果出现在特定行上,您可以为此设置内联监视。内联监视是持久的,并在会话重新启动后保持活动状态。
单击引用您要跟踪其字段的对象的内联提示。
在弹出窗口中,选择该字段并单击“添加为内联观察”。
如果需要,微调手表。您可以使用任何有效的 Java 表达式作为监视。
您在编辑器中设置的内联监视也会显示在 “调试”工具窗口的“变量”选项卡中的“内联监视”下。
要删除内联手表,请将鼠标悬停在手表上并单击其附近的十字。
DFA 辅助调试
IntelliJ IDEA 还提供了有关稍后执行的代码段中将发生的情况的提示。此分析包括异常、布尔表达式结果和代码路径:
笔记
只能针对本地调试会话分析未来的条件/异常。
要禁用进一步执行的分析,请转至构建、执行、部署| 调试器| 数据视图 | Java并清除根据数据流分析预测条件值和异常复选框。
手表
提示
如果您正在寻找有关现场观察点的信息,请参阅断点主题。
如果您想跟踪某个变量或更复杂表达式的结果,请为此变量或表达式设置监视。当您需要评估不定期显示在变量列表中的内容时,这非常有用。
笔记
仅当程序在遇到断点后暂停(不是手动暂停)时,此选项才可用。
提示
调用方法时,请确保您了解它们可能的副作用(例如,更改外部变量),因为它们可能会改变程序流程或结果。
int hasSideEffects() { // returns the number of entries in the list someVariable++; return list.size(); }
在示例中, 的值
someVariable
将随着每一步递增,这可能会影响程序的行为。
监视是在所选帧的上下文中进行评估的。当手表脱离上下文或无法编译时,无法对其进行评估。如果是这种情况,手表会标有错误图标。
默认情况下,监视与变量一起显示在“变量”窗格中。要隐藏/显示“监视”窗格,请使用“布局设置”菜单中的“单独监视”选项。
添加手表
对于在各处求值的常规监视,请在“变量”窗格的顶部输入表达式,然后单击“添加到监视”。
如果您只想在检查特定类型的对象时显示监视,请在“变量”窗格中右键单击该对象,然后选择“新建类级别监视”。
提示
如果要跟踪的变量或表达式已经在您面前(例如,在代码编辑器中),您可以选择它并将其拖动到“变量”窗格。对于当前上下文中的变量,您还可以在“变量”窗格中右键单击它们,然后选择“添加到监视”。
将变量/表达式添加到Watches后,它会保留在那里并针对每个步骤进行评估,为您提供当前上下文中的结果。
编辑手表
右键单击所需的手表并选择编辑。
删除手表
要删除单个手表,请右键单击它并选择“删除手表”。或者,选择手表并按。Delete
要删除所有监视,请右键单击“变量/监视”窗格上的任意位置,然后选择“删除所有监视”。
监视允许执行与变量相同的操作。例如,您可以在专用对话框中查看它们或使用它们导航到源代码。
手表是您项目的一部分。这意味着您可以停止并重新运行调试会话,而不会丢失它们。
标签
在调试过程中,有时标记某些实例很有用,以便在任何上下文中都可以轻松识别它。为此,您可以添加标签。一旦贴上标签,标签就会伴随该对象的整个生命周期。
这在使用条件或表达式时特别有用 - 您可以通过标签引用该对象,而不是搜索对此对象的引用。
如果您想要跟踪某个实例而不考虑上下文,请为此标签创建一个监视。使用这种类型的手表,无论当前帧和线程如何,对象始终位于手边。
添加标签
在“变量”选项卡上,右键单击当前引用您要跟踪的对象的变量或监视。从菜单中选择“标记对象” 。F11
输入标签的名称。您还可以选择显示颜色。为此,请单击并选择颜色。完成配置后,单击“确定”。
去除标签
右键单击要删除的标签,然后从菜单中选择取消标记对象。 F11
返回当前执行点
检查程序状态涉及在代码中导航,并且您经常需要返回到程序暂停的位置。
执行以下操作之一:
转到“运行”| 调试操作| 显示执行点。
按。AltF10
单击 调试工具窗口的步进工具栏上的。
当前执行点用蓝线表示。该行的代码尚未执行。
感谢您的反馈意见!