在为变量分配某个值时中断

Dan*_*iel 38 java eclipse debugging jdb

我希望jdb(我通过Eclipse调试器使用)在为变量赋值时中断.我不想在某个特定的行设置断点,而是更普遍.

例如,每次x == null时中断.

这样的事情可以实现吗?

Din*_*nuk 36

是 - 您需要设置的是"条件断点" - 这使您能够在达到应用程序的某个状态时停止程序执行并逐步调试调试器.

因此,假设您希望在满足特定条件时跳转到执行中的特定点(根据附加的图像),您可以按如下方式执行此操作:

  1. 打开调试器透视图并选择"BreakPoints"选项卡

  2. 在代码文件中添加一个新的BreakPoint - 在您希望观察程序执行的适当位置

  3. 然后返回"断点"选项卡,右键单击新添加的条目,然后选择"断点属性"

  4. 设置应激活它的条件

替代文字

  • 嗨Diunk,您的建议是否取决于特定行号满足的条件?我想要一个更通用的解决方案,无需识别行号.我只是想知道何时为"x"分配了一些东西,而不管分配的方法如何. (7认同)
  • 嗨Diunk,我实际上是试图调试一个不是我的库中的问题.变量受到保护,并且存在一个相当大的类型层次结构,扩展了定义它的基类.访问可能在很多地方,这就是我想要一个无上下文断点的原因.似乎thSoft和DigitalRoss在他们的建议中是正确的. (5认同)

Old*_*Pro 9

你可以与Field Modification观察点非常接近.它们仅限于放置在对象的字段(不是局部变量,参数或表达式)上,并且只要字段被写入就会触发它们,但它是最接近Eclipse的所需内容.


Bri*_*ian 9

编辑:我在此答案中链接的票证已标记为已验证/已修复.它已被集成到最新的Oxygen版本中,详见发行说明.我将在下面留下我原来的答案,因为它有很多关于JDI和JDT如何在Eclipse中协同工作的有用信息.


我将从你的问题的最终答案开始,所以如果你不想,你不必阅读细节.基本上,这是有可能的,但有很多问题必须首先回答.如果你想跳过它并直接去机票,你可以去,但我建议你继续阅读.

Eclipse使用JDI(该页面的最底部)向JVM注册观察点.这是通过EventRequestManager创建观察点的方法(由JVM本身而不是Eclipse提供的实现)完成的,即EventRequstManager.createModificationWatchpointRequest.这些方法唯一接受的是Field(注意这不是反射Field类).简而言之,Eclipse不能直接通过Java来实现.永远不要害怕,Java也不会处理条件断点.这些也是通过Eclipse直接实现的,而不是依赖于Java.但是,有一些警告使条件观察点比条件断点更难实现.

让我们考虑简单的条件断点.为了使它们起作用,您需要一个可以执行代码片段的上下文.如果没有代码的执行上下文,我们无法评估代码段中的表达式/语句,因为我们无法解析变量,值,类型等.这是使用AST解析器完成的,该解析器将Java代码处理为实际指令.请记住,您可以在条件中键入多个语句,而不仅仅是单个表达式.然后,求值程序IJavaStackFrame在解析表达式之后使用上下文(特别是a )来计算表达式本身.

现在考虑一个条件观察点,因为最后一点非常重要.什么是观察点的执行环境?变量访问不仅可以在同一个类中发生,也可以在其他类(思考protected和包成员)中发生,也可以在内部类中发生(通过MyClass.this.myField).这意味着:

  1. 局部变量永远不会一致,因为可以从多个方法访问该字段,
  2. 调用访问的类的成员变量永远不会一致,因为可以从多个类访问该字段,
  3. 执行上下文中可用的导入类永远不会出于与(2)和/ 2相同的原因
  4. 字段本身的访问永远不会一致,因为它可能需要使用实例,类名super或类似的内容MyClass.this.myField(对于内部类访问)进行限定.

这种功能的可行性有限.你很难真正评估一个观察点的不变条件语句,因为执行上下文中的任何内容都不会保持一致.这意味着无法轻松地解析和解释代码,而无需对代码片段应用特殊含义,例如:

myField始终与this.myFieldor super.myFieldMyClass.myFieldor 相同MyClass.this.myField,具体取决于访问字段的位置.

这使事情变得非常复杂,特别是在已经相对复杂的系统中.可以在此处找到条件断点代码的示例(getEvaluationEngine使用Ctrl + F 搜索).现在接下来,根据一组关于我们所处位置和场所在位置的规则对表达式添加预处理,并且做事情况会变得复杂.

AFAIK,你不能做类似的事情,"如果旧的/新的值是这个,暂停",因为这些信息根据你可以从堆栈框架中获得的信息(因而来自调试器)无法获得.分配给该值的表达式已在命中观察点的时间内进行评估,但其结果对调试器不可用,因此观察点本身的评估程序无法使用它.必须首先执行步骤才能执行赋值,然后必须在步骤之后计算表达式.它会非常混乱,老实说,相当狡猾.

在任何情况下,如果您想表达对此功能的支持,您可以使用此Eclipse票证.然而,它自2005年以来一直存在(截至目前为8年),并且得到了社区的有限支持.TBH,我认为它没有走得太远,特别是没有更多地澄清这种功能请求背后的期望,并且没有首先考虑它的一些主要设计考虑因素.


Dig*_*oss 5

是的,这些被称为观察点,观察点可以有观察表达.

根据版本等,您可以通过在"大纲"视图中选择一个变量并右键单击它,或在"变量"视图中控制/单击它来执行此操作.

上下文菜单将包含Add Watch ExpressionEdit Watch Expression的选项.