eclipse 为变量赋值时中断
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2278447/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Break when a variable is assigned some value
提问by Daniel
I want jdb (which I'm using via the Eclipse debugger) to break when a variable is assigned some value. I'm not interested in setting a breakpoint at some specific line but rather more generally.
我希望 jdb(我通过 Eclipse 调试器使用它)在为变量分配某个值时中断。我对在某些特定行设置断点不感兴趣,但更一般。
For example, break every time x == null.
例如,每次 x == null 时中断。
Is such a thing achievable?
这样的事情可以实现吗?
回答by Dinuk
Yes - What you need to setup is a 'Conditional Breakpoint'- this gives you the ability to stop the program execution and step through the debugger when a certain state of the application is reached.
是的 - 您需要设置的是“条件断点”- 这使您能够在达到应用程序的特定状态时停止程序执行并逐步调试调试器。
So, let's say you want to jump into a particular point in the execution when a certain condition is fulfilled (as per the image attached), you can do this as follows:
因此,假设您想在满足特定条件时跳转到执行中的特定点(根据所附图像),您可以按如下方式执行此操作:
Open your debugger perspective and select the 'BreakPoints'tab
Add a new BreakPoint in the code file - at the appropriate place where you would like to observe the program execution
Then go back to the 'Breakpoints'tab, right-click on the newly added entry, and select 'Breakpoint Properties'
Set the condition upon which it should be activated
打开您的调试器透视图并选择“BreakPoints”选项卡
在代码文件中添加一个新的 BreakPoint - 在您希望观察程序执行的适当位置
然后返回“断点”选项卡,右键单击新添加的条目,然后选择“断点属性”
设置激活条件
回答by Old Pro
You can come pretty close with Field Modification Watchpoints. They are limited to being placed on fields of objects (not local variables, parameters, or expressions) and they are triggered whenever the field is written to, but it's the closest Eclipse has to what you want.
您可以非常接近Field Modification Watchpoints。它们仅限于放置在对象的字段上(不是局部变量、参数或表达式),并且在写入字段时触发它们,但它是 Eclipse 最接近您想要的。
回答by Brian
Edit: The ticket I've linked in this answerhas been marked verified/fixed. It has been integrated into the latest Oxygen release, as detailed in the release notes. I'll leave my original answer below since it has a lot of useful information regarding how JDI and JDT work together in Eclipse.
编辑:我在此答案中链接的票证已标记为已验证/已修复。它已集成到最新的 Oxygen 版本中,详情请参见发行说明。我将在下面留下我的原始答案,因为它有很多关于 JDI 和 JDT 如何在 Eclipse 中协同工作的有用信息。
I'm going to start with the final answer to your question so you don't have to read the details if you don't want to. Basically, this is kind of possible but with a lot of questions that have to be answered first. If you want to skip that and go straight to the ticket, here you go, but I recommend you read on.
我将从你问题的最终答案开始,这样你就不必阅读细节,如果你不想的话。基本上,这是可能的,但有很多问题需要先回答。如果你想跳过那个直接去买票,给你,但我建议你继续阅读。
Eclipse uses JDI(very bottom of that page) to register watchpoints with the JVM. This is done through the EventRequestManager
methods (the implementation is provided by the JVM itself, not Eclipse) that create watchpoints, i.e. EventRequstManager.createModificationWatchpointRequest
. The only thing that these methods accept is a Field
(note that this isn't the reflective Field
class). So in short, Eclipse can't do it directly through Java. Never fear, Java doesn't handle conditional breakpoints either. Those are also implemented through Eclipse directly instead of relying on Java. There are, however, some caveats that make conditional watchpoints much more difficult to implement than conditional breakpoints.
Eclipse 使用JDI(该页面的最底部)向 JVM 注册观察点。这是通过EventRequestManager
创建观察点的方法(实现由 JVM 本身提供,而不是 Eclipse)来完成的,即EventRequstManager.createModificationWatchpointRequest
. 这些方法唯一接受的是 a Field
(注意这不是反射Field
类)。所以简而言之,Eclipse不能直接通过Java来做。不用担心,Java 也不处理条件断点。这些也是直接通过 Eclipse 实现的,而不是依赖 Java。但是,有一些注意事项使条件观察点比条件断点更难实现。
Let's consider plain, conditional breakpoints. In order for them to work, you need a context in which you can execute the code snippet. Without an execution context for the code, we can't evaluate the expression/statements in the snippet since we have no way of resolving variables, values, types, etc. This is done using an ASTparser that processes the Java code into actual instructions. Remember that you can type a number of statements into a condition, not just a single expression. The evaluator then uses a context (specifically, an IJavaStackFrame
) to evaluate the expression itself after parsing it.
让我们考虑简单的条件断点。为了让它们工作,您需要一个可以在其中执行代码片段的上下文。如果没有代码的执行上下文,我们就无法评估代码片段中的表达式/语句,因为我们无法解析变量、值、类型等。这是使用将 Java 代码处理为实际指令的AST解析器完成的. 请记住,您可以在条件中键入多个语句,而不仅仅是单个表达式。然后,评估器IJavaStackFrame
在解析表达式后使用上下文(特别是 an )来评估表达式本身。
Now think about a conditional watchpoint, because that last point is very important. What is a watchpoint's execution context? Variable access can happen not only within the same class, but also in other classes (think protected
and package members), and in inner classes as well (via MyClass.this.myField
). This means that:
现在考虑一个条件观察点,因为最后一点非常重要。什么是观察点的执行上下文?变量访问不仅可以发生在同一个类中,还可以发生在其他类(思考protected
和包成员)以及内部类中(通过MyClass.this.myField
)。这意味着:
- the local variables are never consistent since the field can be accessed from multiple methods,
- the member variables of the class from which access is invoked are never consistent since the field can be accessed from multiple classes,
- the imported classes that are available in the execution context are never consistent for the same reason as (2), and
- the access of the field itself is never consistent since it may require qualification with an instance, class name,
super
or with something likeMyClass.this.myField
(for inner class access).
- 局部变量永远不会一致,因为可以通过多种方法访问该字段,
- 调用访问的类的成员变量永远不会一致,因为可以从多个类访问该字段,
- 由于与 (2) 相同的原因,在执行上下文中可用的导入类永远不会一致,并且
- 字段本身的访问从来都不是一致的,因为它可能需要使用实例、类名
super
或类似的东西MyClass.this.myField
(用于内部类访问)进行限定。
The feasibility of such a feature is kind of limited. You'd be hard-pressed to actually evaluate a non-changing conditional statement for a watchpoint since absolutely nothing in the execution context is going to be consistent. This means that the code cannot be easily parsed and interpreted without special meaning applied to pieces of the code, such as:
这种功能的可行性是有限的。您将很难实际评估观察点的不变条件语句,因为执行上下文中绝对没有任何内容是一致的。这意味着如果不对代码段应用特殊含义,则无法轻松解析和解释代码,例如:
myField
is always the same asthis.myField
orsuper.myField
orMyClass.myField
orMyClass.this.myField
, depending on where the field is being accessed.
myField
始终与this.myField
orsuper.myField
或MyClass.myField
or相同MyClass.this.myField
,具体取决于访问字段的位置。
This complicates things quite a bit, especially in a system that is already relatively complex. An example of the conditional breakpoint code can be found here(search for getEvaluationEngine
using Ctrl+F). Now take that and add in pre-processing on the expression based on a set of rules about where we are and where the field is, and doing things can get complicated.
这使事情变得相当复杂,尤其是在一个已经相对复杂的系统中。可以在此处找到条件断点代码的示例(getEvaluationEngine
使用 Ctrl+F搜索)。现在,根据一组关于我们在哪里和字段在哪里的规则,在表达式上添加预处理,并且做事情会变得复杂。
AFAIK, you can't do something like, "if the old/new value is this, suspend", because that information simply isn't available from the information you can get in the stack frame (and thus from the debugger). The expression being assigned to the value has been evaluated by time the watchpoint is hit, but its result isn't available to the debugger, therefore it isn't available to an evaluator on the watchpoint itself. A step would have to be performed first to perform the assignment, then the expression would have to be evaluated after the step. It'd be horribly messy, and honestly, rather hacky at that.
AFAIK,你不能做这样的事情,“如果旧/新值是这个,暂停”,因为从你可以在堆栈帧中获得的信息(因此从调试器)中获得的信息根本不可用。分配给该值的表达式已在观察点被命中时进行评估,但其结果对调试器不可用,因此它对观察点本身的评估器不可用。必须首先执行一个步骤来执行赋值,然后必须在该步骤之后评估表达式。它会非常混乱,老实说,在这方面相当笨拙。
In any case, if you want to voice your support for this feature, you can use this Eclipse ticket. However, it's been around since 2005 (8 years as of now) and has limited support from the community. TBH, I don't see it going very far, especially without more clarification of the expectations behind this kind of a feature request and without some major design consideration put behind it first.
无论如何,如果您想表达您对此功能的支持,您可以使用此 Eclipse 票证。但是,它自 2005 年(到现在 8 年)就已经存在,并且社区的支持有限。TBH,我认为它不会走得太远,特别是没有更多地澄清这种功能请求背后的期望,也没有首先考虑一些主要的设计考虑。
回答by DigitalRoss
Yes, those are called watchpoints, and watchpoints can have watch expressions.
是的,那些被称为watchpoints,并且 watchpoints 可以有watch 表达式。
Depending on versions and such, you do this by selecting a variable in the Outline view and right-clicking on it, or in the Variables view, control/click on it.
根据版本等,您可以通过在大纲视图中选择一个变量并右键单击它来执行此操作,或者在变量视图中控制/单击它。
A context menu will have choices for Add Watch Expressionand Edit Watch Expression.
上下文菜单将提供Add Watch Expression和Edit Watch Expression 选项。
回答by mki
Sorry, but there is no way to do what you want in Eclipse. What you need is a watchpoints with the conditional expression of a breakpoint. It does not exist in Eclipse.
抱歉,在 Eclipse 中没有办法做你想做的事。您需要的是带有断点条件表达式的观察点。它在 Eclipse 中不存在。
Your problem is also specific debug a library. There are probably other ways to achieve what you need. Search over forum to see how developers do that.
你的问题也是具体调试一个库。可能还有其他方法可以实现您的需求。在论坛上搜索以了解开发人员是如何做到这一点的。