0

特定のメソッドが null を返すかどうかをプログラムで検出する必要があります。

チェッカー フレームワークはこれを実行できるようですが、注釈付きのソース コードでのみ可能です。バイトコードで必要です。具体的には、次のような主張を検証する必要があります。

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

クラス xyZ のバイトコードしかない場所

それをサポートするツールを知っていますか?

これは一般的なケースでも可能ですか?私が見る限り、プログラムの正確なパスを把握する必要がないため、これは停止問題と同等ではありません。たとえば、

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

分析ツールは を気にする必要はありませんcond。考えられるすべてのパスの少なくとも 1 つでnullが返されることに注意するだけで十分です。

cond注: 誤検知を受け入れます。たとえば、false分析ツールは、bar() が null を返す可能性があると主張する可能性があります (これは、真でなければならない一般的なケースで証明できないと言っているのと同じcondです)。

4

2 に答える 2

2

これを行うツールは知りませんが、誤検知が許容される場合、これは可能だと思います.

メソッドから返される値は、最終的に次のいずれかから取得されます。

  • メソッド内の定数
  • 提供されたパラメーター
  • フィールド
  • 別の Java メソッド呼び出しの結果
  • ネイティブ呼び出しの結果
  • コンストラクター呼び出し
  • 忘れていたソース

いずれかのフィールドまたはパラメーターが null である可能性があり、ネイティブ呼び出しが null を返す可能性があると想定する場合、各メソッドは次の場合に null を返す可能性があるとマークできます。

  • メソッドのフローは null 定数を返すことができます
  • メソッドのフローはフィールドを返すことができます
  • メソッドのフローはパラメーター値を返すことができます
  • メソッドのフローは、ネイティブ呼び出しの結果を返すことができます
  • メソッドのフローは、それ自体が null を返すことができるメソッドから値を返すことができます

ただし、誤検知の割合が高くなる可能性が高いため、おそらく役に立ちません (許容できる最大パーセンテージが必要です。そうでない場合は、単純に true を返すメソッドで要件を満たすことができます)。

ヒューリスティックを追加して、null と見なされるフィールド/パラメーター/メソッドの数を減らすことができる場合があります。

ASM ツリー API は、フロー分析を含め、これを試して実装するために必要なすべてのビルディング ブロックを提供します。

于 2013-08-09T14:39:31.570 に答える
1

次の 2 つの可能性が考えられます。

  • findbugs を使用します。NP で始まるバグ パターンは、そのことを確認します。たとえば、次のようになります。
    • NP_LOAD_OF_KNOWN_NULL_VALUE
    • NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE
    • NP_NULL_ON_SOME_PATH_MIGHT_BE_INFEASIBLE

あるいは、それをチェックする独自のバグパターンを作成することもできます...

  • 日食チェッカーでビルドを使用します。Preferences\Java\Compiler\Errors/Warnings に移動すると、専用のセクション全体 (Null 分析) があります。これらの設定を警告またはエラーに変更できます...

[アップデート]

プログラムで実行したい場合は、(findbugs のように) 実行でき、バイト コード ライブラリを使用して実行できます。

私が読んだり聞いたりしたことから、ASM は良い選択のようです。そして、私の記憶が正しければ、findbugs も ASM に切り替えました (ただし、内部にはまだ bcel がいくつかありますか?)。ゼロから始めないために、検出器で findbugs を使用し、それをライブラリとして使用することができます。したがって、バグ検出関数を呼び出してプログラムで開始し、戻り値を分析します。詳細については、findbugs メーリング リストでお尋ねします。

[更新 2] このはまさにあなたが必要とすることをしている可能性があります。そのため、彼に連絡する必要があります...

于 2013-08-12T07:40:00.950 に答える