Eclipse条件断点 - 仅在其他断点后触发

7

我正在调试一个大量调用方法的应用程序。例如,我想调试 methodA,它被调用了1000次。

但是,在我的主循环中,我只想在执行几个语句后开始调试 methodA。

public void methodA()
{
    //does something nasty that I want to debug
}
public static void main( String[] args )
{
    for (int i=0; i<1000; i++)
    {
        methodA();
    }
    methodB();
    methodA();
}

当且仅当调用methodB后,我想开始进入methodA。我并不想改变我的代码(比如插入一个布尔值并使断点取决于该布尔值)。

在Eclipse中是否有类似的选项?或者还有更好的选择吗?

5个回答

8

A) 只需将点击次数设置为1000。

只有当for循环内的methodA方法不在某个条件下时,此方法才有效。

B) 使用条件

将断点放在methodA方法内的第一条语句处。参见图片。

[这里methodA == test,我在第14行放置了断点]

enter image description here

右键单击断点,选择断点属性选项并添加以下条件。

StackTraceElement[] stacktrace = Thread.currentThread().getStackTrace();
StackTraceElement e = stacktrace[2];
return (e.getLineNumber() == 9);

这里的9表示第二次调用methodA(或test)的行号。在您的代码中找到相同的内容并进行更改。

查看StackTraceElement的javadoc,您也可以使用方法名称而不是行号。也就是说,只有在从函数xyz调用时才能中断。

enter image description here

C) 等待eclipse Oxygen(4.7)

在eclipse JDT的下一个版本中,将提供断点触发点。因此,您可以说仅当先前命中断点x时才会命中断点y

通过这种方式,您可以仅在给定方法流程[堆栈跟踪]上暂停断点。

例如:只有在调用流程为:

methodA() --> methodB() --> methodC() --> methodD()时才能停止断点,而不能在

methodA() --> methodC() --> methodD()等情况下停止。

请参见此bug以获取更多详细信息。向此bug添加您的评论/建议。


非常聪明的方法 B!谢谢 :D - Rob Audenaerde
@RobAu 我编辑了我的答案并添加了一个方法。请检查。 - Chandrayya G K
谢谢@Chandrayya,我期待着。 - Rob Audenaerde
在Eclipse Oxygen中,该功能被称为“触发点”,它确切地实现了这里所描述的功能。感谢您的提示! - Martin Häusler

4
我将使用系统属性来实现这个。

示例

假设我们有这个类:

public class Main {

    public static void main(String[] args) {
        for (int i = 0; i < 1000; i++) {
            methodA();
        }
        methodB();
        methodA();
    }

    private static void methodA() {
        System.out.println("A");
    }

    private static void methodB() {
        System.out.println("B");
    }

}

我们想在methodA()内添加一个断点,但只有在调用methodB()后才停在它上面,但不能向代码中添加额外变量或使用计数器。

一个设置属性的断点

首先,在methodB()内添加一个断点并将其设置为条件断点。在其条件中,我们将设置系统属性为true。我们不想在methodB()内暂停,因此条件将返回false

System.setProperty("enable.methodA.breakpoint", "true");
return false;

请参见下面的GIF:

Adding first condition to <code>methodB()</code>

检查属性的断点

现在,我们向 methodA() 添加一个带有条件的断点。在条件中,我们首先获取设置的系统属性的值:

String p = System.getProperty("enable.methodA.breakpoint", "false");

然后,我们将其解析为布尔值并返回:
return Boolean.valueOf(p).booleanValue();

(请注意,默认值为"false",因此如果未设置该属性,则断点不会暂停。)
请查看下面的GIF中的该步骤:

Add bookmark that checks system property.

运行

现在,如果我们以调试模式运行这个类,在methodB()被调用之后,位于methodA()的书签才会暂停:

<code>methodA()</code> is only paused after <code>methodB()</code>

禁用断点

如果在调用methodB()之后,methodA()被多次调用,但我们只想检查一次,那么可以最终取消该属性。例如,假设现在我们的main()方法像下面这样:

public static void main(String[] args) {
    for (int i = 0; i < 1000; i++) {
        methodA();
    }
    methodB();
    methodA();
    for (int i = 0; i < 1000; i++) {
        methodA();
    }
}

我们可以使用这个条件,将属性设置为false,以避免再次在此断点停止:
String p =
    System.getProperty("enable.methodA.breakpoint", "false");

System.setProperty("enable.methodA.breakpoint", "false");

return Boolean.valueOf(p).booleanValue();

当然,这只是一个简单的例子 - 这个技巧的应用范围是非常广泛的。

1

然后我需要修改我的代码以便能够使用一个带有值的变量。我不想这样做(正如我在问题中所述),我正在寻找其他选项(如果有的话)。 - Rob Audenaerde
如果你的methodB()没有改变任何变量,那么这个解决方案是不起作用的。 - ibrahimbayer

0
怎么样?
public void methodA()
{
    //does something nasty that I want to debug
}
public static void main( String[] args )
{
    for (int i=0; i<1000; i++)
    {
        methodA();
    }
    methodB(); //first breakpoint here? 
    methodA(); //2nd breakpoint here?
}

0

methodA上设置一个断点,当你触发该断点时,在methodB中添加第二个断点并继续执行。


这就是我现在所做的事情,而且效率低下,因为我需要找到断点、启用它们、关闭它们等等。 - Rob Audenaerde
@RobAu 如果你只在每次执行中进行一次过渡,那么这并不需要太多的努力。但如果你要多次进行过渡,你如何期望Eclipse知道何时“恢复”到pre-methodB状态呢? - shmosel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接