1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Inferを試してみる

Posted at

Inferは、Facebook社が開発を続けている静的解析ツールです。
元々はMonoidics社で開発が続けられていましたが、2013年にFacebook社に買収をされ、その後2015年にオープンソースとなりました。
JavaやC、C++、Objective-Cといった言語のバグの可能性のあるコードを検出でき、JavaであればNullポインタの参照や、リソースリークなどが検出できます。

公式サイト
https://fbinfer.com/
GitHub
https://github.com/facebook/infer

現在のプロジェクトでもSpotBugsなどの静的解析ツールは導入しているのですが、他のツールを探していたところ見つけたツールで、本記事はこちらを試してみた記事になります。

実行環境

今回は以下の環境で実行した結果になります。

  • OS: macOS
  • 対象言語: Java

インストール

macであればbrewコマンドでインストールできます。

brew install infer

LinuxやWindowsでのインストール方法は公式サイトにその方法が記載されているので、参考にして下さい。

Inferの試用

オープンソースで公開されているInferのリポジトリには、サンプルとして使用できるコードも含まれています。

今回はまずこちらをダウンロードして試してみました。
ダウンロード後はexampleディレクトリに移動します。ここにはHello.javaやhello.cといった単一のソースコードファイルや、複数のソースコードをリンクしてコンパイルするファイルが格納されたjava_helloやc_helloといったディレクトリが存在します。

Hello.javaの内容は以下のような内容になっています。

/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

class Hello {
  int test() {
    String s = null;
    return s.length();
  }
}

オブジェクトにnullを代入して、それを参照しています。

このファイルに対してinferを使って解析を行います。
inferを実行するときは、--の後ろに、その言語のコンパイルコマンドを繋げて実行します。

infer -- javac Hello.java

これを実行すると、以下のような結果が出力されます。

Capturing in javac mode...
Found 1 source file to analyze in <ダウンロードしたディレクトリ>/infer/examples/infer-out


Analysis finished in 1.24ss

Found 1 issue

Hello.java:11: error: NULL_DEREFERENCE
  object `s` last assigned on line 10 could be null and is dereferenced at line 11.
  9.     int test() {
  10.       String s = null;
  11. >     return s.length();
  12.     }
  13.   }


Summary of the reports

  NULL_DEREFERENCE: 1

画面にはNULLを参照しているバグを検出した結果が出力されます。
解析結果は、コマンドを実行したディレクトリにinfer-outというディレクトリが作成され、その下のbugs.txtやreport.jsonといったファイルにも出力されています。

サンプルの中にあるjava_hello下でinferを実行した場合は、以下のような結果が出力されます。

infer -- javac Pointers.java Resources.java Hello.java

実行結果

Capturing in javac mode...
Found 3 source files to analyze in <ダウンロードしたディレクトリ>/infer/examples/java_hello/infer-out


Analysis finished in 1.366ss

Found 3 issues

Hello.java:28: error: NULL_DEREFERENCE
  object `a` last assigned on line 26 could be null and is dereferenced at line 28.
  26.       Pointers.A a = Pointers.mayReturnNull(rng.nextInt());
  27.       // FIXME: should check for null before calling method()
  28. >     a.method();
  29.     }
  30.

Hello.java:38: error: RESOURCE_LEAK
  resource of type `java.io.FileOutputStream` acquired by call to `allocateResource()` at line 32 is not released after line 38.
  36.
  37.       try {
  38. >       stream.write(12);
  39.       } finally {
  40.         // FIXME: should close the stream

Hello.java:63: error: RESOURCE_LEAK
  resource of type `java.io.FileOutputStream` acquired to `fos` by call to `FileOutputStream(...)` at line 53 is not released after line 63.
**Note**: potential exception at line 57
  61.         }
  62.       }
  63. >   }
  64.   }


Summary of the reports

     RESOURCE_LEAK: 2
  NULL_DEREFERENCE: 1

こちらではリソースリークなども検出しています。

inferはjavacでコンパイルする以外でも、mavenやgradleで構成されたプロジェクトでも使用できます。
その場合は、以下のように--の後にmvnコマンドやgradleコマンドを繋げる形になります。

Gradle

infer run -- gradle <gradle task, e.g. "build">
infer run -- ./gradlew <gradle task, e.g. "build">

Maven

infer run -- mvn <maven target>

プロジェクト単位で実行した場合は、タスクの終了後に解析が実行されます。ファイル数によってはかなり時間がかかるので注意して下さい。
解析結果は先と同様にinfer-outの下に出力されます。

また、Mavenプロジェクトで実行をした際はpom.xmlに一部設定の追加が行われて実行がされていました。(実行後は元に戻ります。)
解析中は他のmvnコマンドは実行しない方が良さそうです。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?