【问题标题】:Eclipse conditional breakpoint - only after other breakpointEclipse 条件断点 - 仅在其他断点之后
【发布时间】:2015-08-23 20:53:23
【问题描述】:

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

但是,在我的主循环中,我只想在几条语句之后开始调试方法 A。

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();
}

我想开始闯入methodA 只有在 methodB 被调用之后。我真的不想更改我的代码(例如,插入一个boolean 值并使断点以boolean 为条件)。

在 Eclipse 中这样的事情可能吗?还是有更好的选择?

【问题讨论】:

    标签: java eclipse debugging breakpoints


    【解决方案1】:

    【讨论】:

    • 然后我需要修改我的代码以便能够使用具有值的变量。我不想这样做(如我的问题所述),我正在寻找其他选择(如果有的话)
    • 如果您的 methodB() 没有更改任何变量,则此解决方案不起作用。
    【解决方案2】:

    只需在methodA 上放置一个断点,当您遇到该断点时,将您的第二个断点添加到methodB 并继续执行。

    【讨论】:

    • 这就是我现在所做的,而且效率低下,因为我需要找到断点、启用它们、禁用它们等等。
    • @RobAu 如果您每次执行只转换一次,那并不费力。如果您多次这样做,您如何期望 Eclipse 知道何时“恢复”到 pre-methodB 状态?
    【解决方案3】:

    怎么样?

    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?
    }
    

    【讨论】:

      【解决方案4】:

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

      只有在 for 循环中的 methodA 不在某些条件下才有效。

      B) 使用条件

      将断点放在methodA中的第一条语句处。参考图片

      [这里 methodA == 测试,我在第 14 行设置断点]

      右键单击断点并选择Breakpoint properties选项并添加以下条件。

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

      这里的 9 表示第二次调用 methodA(或测试)的行号。在您的代码中找出相同的并更改它。

      检查StackTraceElement 的javadoc,你也可以使用方法名来代替行号。也就是说,只有在从函数 xyz 调用时才能中断。

      C) 等待 eclipse Oxygen (4.7)

      在 eclipse 的下一个版本中,JDT 将在断点上提供触发点。所以你可以说命中断点 y 仅当断点 x 之前被命中。

      有了这个,你只能在给定的方法流 [stacktrace] 上的断点处暂停。

      例如:您只能在调用流程为时在断点处停止:

      methodA() --&gt; methodB() --&gt; methodC() --&gt; methodD() 未开启

      methodA() --&gt; methodC() --&gt; methodD()

      请参阅此bug 了解更多详情。将您的 cmets/建议添加到此错误中。

      【讨论】:

      • 非常聪明的方法B!谢谢:D
      • @RobAu 编辑了我的答案并添加了另一种方法。请检查。
      • 谢谢@Chandrayya,我很期待
      • 该功能在 Eclipse Oxygen 中称为“触发点”,它的功能与此处描述的完全相同。感谢您的提示!
      【解决方案5】:

      我使用系统属性来实现这一点。

      例子

      假设我们有这个类:

      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:

      检查属性的断点

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

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

      然后,我们将其解析为布尔值并返回:

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

      (注意默认值为"false",所以如果没有设置属性,断点不会暂停。)

      在下面的 GIF 中检查这一步:

      跑步

      现在,如果我们在调试模式下运行这个类,methodA() 的书签只会在调用methodB() 后暂停:

      再次禁用断点

      如果在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();
      

      当然,这只是一个简单的例子——天空是这个技巧的极限。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-05-02
        • 2011-11-09
        • 2023-04-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-03
        相关资源
        最近更新 更多