静态字节码分析工具,检测返回null的方法?

时间:2013-08-09 12:49:51

标签: java null bytecode static-analysis

我需要以编程方式检测,如果给定的方法可能会返回null,也可能不会返回null。

checker framework似乎能够做到这一点,但仅限于带注释的源代码。我需要字节码。具体来说,我需要验证如下声明:

Method x.y.Z#foo() cannot return null.

我只有x.y.Z类的字节码。

你知道任何支持它的工具吗?

在一般情况下,这是否可能?据我所知,它不等于暂停问题,因为人们不需要弄清楚程序的确切路径。例如在

Foo bar() {
    if (cond) { return null; } else { return new Foo(); }
}

分析工具不需要关心cond,只需注意在至少一个可能的路径中返回null,因此可以拒绝bar不能返回null的声明。

注意:我会接受误报,例如,cond可能只是false,分析工具仍然可以声称bar()可以返回null(这相当于说我们不能一般情况下,cond必须为真。

2 个答案:

答案 0 :(得分:2)

我不知道有任何工具可以做到这一点,但如果误报是可以接受的,那么我认为这是可能的。

从方法返回的值最终将来自

之一
  • 方法中的常量
  • 提供的参数
  • 字段
  • 另一个java方法调用的结果
  • 原生电话的结果
  • 构造函数调用
  • 我忘记的来源

如果您假设任何字段或参数可能为null,并且任何本机调用可能返回null,则每个方法都可以标记为可能返回null,如果

  • 方法的流程可以返回空常量
  • 该方法的流程可以返回一个字段
  • 方法流程可以返回参数值
  • 方法的流程可以返回本机​​调用的结果
  • 该方法的流程可以从一个本身可以返回null的方法返回一个值

然而,它可能没有用,因为它可能会产生很大比例的误报(你必须有一些可接受的最大百分比,否则你可以用一个简单返回true的方法来满足你的要求)。 / p>

您可以添加其他启发式方法,以减少被视为空的字段/参数/方法的数量。

ASM树api提供了您尝试实现此功能所需的所有构建块,包括流分析。

答案 1 :(得分:1)

有两种可能性浮现在脑海中:

  • 使用findbugs。以NP开头的错误模式检查,例如:
    • NP_LOAD_OF_KNOWN_NULL_VALUE
    • NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE
    • NP_NULL_ON_SOME_PATH_MIGHT_BE_INFEASIBLE

或者,您可以构建own bug pattern检查...

  • 使用eclipse检查器中的构建。如果您转到Preferences \ Java \ Compiler \ Errors / Warnings,则会有一整段(Null分析)专用于此。您可以将这些设置更改为警告或错误...

<强> [更新]

如果您想以编程方式执行此操作(例如findbugs)并使用字节代码库来执行此操作:

  • BCEL具有类似DOM的API
  • ASM使用类似SAX的API。可用的教程,用户指南和参考文档here

从我所读到和听到的ASM似乎是good choice。如果我没记错的话,findbugs也会切换到ASM(但内部仍有一些bcel?)。为了不从头开始,您可以将findbugs与您/他们的探测器一起使用,并将其用作库。因此,您调用其错误检测功能并以编程方式启动它,然后分析返回值。我会在findbugs邮件列表中询问更多细节。

<强> [UPDATE2] guy可能正在做你需要的 - 所以你应该联系他......