3

我正在研究表达式评估器。根据处理的表达式的复杂性,有一个evaluate()函数会被多次调用。

我需要打破并调查此方法何时返回 null。有许多路径和返回语句。

退出方法事件可能会中断,但我找不到如何设置有关返回值的条件。

4

3 回答 3

3

我也陷入了那种挫败感。可以检查(并编写条件)命名变量,但不能检查未命名的东西,如返回值。以下是一些想法(对于可能感兴趣的人):

  1. 可以evaluate() == null在断点的条件中包含类似的东西。执行的测试(Eclipse 4.4)表明,在这种情况下,将再次执行该函数以达到断点的目的,但这次是禁用断点。所以你至少会避免堆栈溢出的情况。这是否有用,取决于所考虑函数的性质——它会在断点时返回与运行时相同的值吗?(一些 s[a|i]mple 代码进行测试:)
class TestBreakpoint {
    int counter = 0;
    boolean eval() { /* <== breakpoint here, [x]on exit, [x]condition: eval()==false */
        System.out.println("Iteration " + ++counter);
        return true;
    }
    public static void main(String[] args) {
        TestBreakpoint app = new TestBreakpoint();
        System.out.println("STARTED");
        app.eval();
        System.out.println("STOPPED");
    }
}
// RESULTS:
// Normal run: shows 1 iteration of eval()
// Debug run: shows 2 iterations of eval(), no stack overflow, no stop on breakpoint
  1. 另一种使它更容易(将来可能进行调试)的方法是制定编码约定(或个人编码风格),要求一个人声明一个在函数内部设置的局部变量,并且在最后只返回一次。例如:
public MyType evaluate() {
    MyType result = null;
    if (conditionA) result = new MyType('A');
    else if (conditionB) result = new MyType ('B');
    return result;
}

然后,您至少可以使用类似的条件执行退出断点result == null。但是,我同意这对于简单的函数来说是不必要的冗长,与语言允许的流程有点相反,并且只能手动执行。(就个人而言,我有时确实将这种约定用于更复杂的功能(名称result“保留”只是为了这种用途),它可能会使事情更清楚,但不适用于简单的功能。但很难划清界限;就在今天早上单步执行一个简单的函数,看看 3 种可能的情况中的哪一种被触发了。对于当今的复杂系统,人们希望避免单步执行。)

  1. 除上述情况外,您需要逐个修改您的代码,如前一点一样,单个函数将您的返回值分配给您可以测试的某个变量。如果某些工作政策不允许您进行此类非功能性更改,那么您将陷入困境......当然,如果原始代码有点复杂,这样的重写也可能导致无意中解决错误,所以小心调试后恢复原来的,才发现bug又回来了。
于 2015-02-25T11:55:44.103 回答
2

您没有说您使用的是什么语言。如果是 Java 或 C++,您可以使用断点属性在方法(或函数)断点上设置条件。这是显示这两种情况的图像。在 Java 示例中,您将取消单击 Entry 并在 Exit 中打勾。

Java 方法断点属性对话框

Java 断点属性

C++ 函数断点属性对话框

C++ 断点属性

于 2013-10-16T21:25:39.947 回答
1

Eclipse 调试器尚不支持此功能,并将其作为增强请求添加。如果您投票支持,我将不胜感激。

https://bugs.eclipse.org/bugs/show_bug.cgi?id=425744

于 2014-01-17T20:50:39.097 回答