A note to our readers: As per your request we have developed a set of features that allow you to reduce the noise, while not losing sight of anything that is important. Get email and web notifications by choosing the topics you are interested in.
フェイスブックのオープンソースの静的解析ツールであるInferが、RacerDによるJavaコード競合状態検出を追加して公開された。RacerDはロックまたは@ThreadSafe
を使うクラスにあるメソッド間の競合状態を見つける。
フェイスブックはこの1年間自身の製品のコードに対してRacerDを使ってきており、1000以上のマルチスレッドの問題を見つけた。すべて本番リリース前にだ。このInferを使ってJavaコードのバグを検知しているJava開発者は並列処理のチェック機能を利用できる。
競合状態は並列処理のエラーもしくはバグの一種であり、2つのスレッドが適切な同期をせずに同じオブジェクトに対して操作すると、お互いの実行が重なり合ってしまい発生する。少なくとも1つは書き込みアクセスである。並列処理の問題はデバッグが困難で、発生した後に再現することさえ難しい。
RacerDは大規模でもすばやくそして有益な並列処理解析ができる。RacerDは並列処理の問題に対してコードベース全体をチェックしようとはしないので早い。並列に実行されると思われるコードを検査するだけである。
RacerDは明示的に@ThreadSafe
アノテーションを付与されている、もしくはsynchronized
キーワードでロックを作るクラスやメソッド、インタフェースを調べて並列に実行できるコードを見つける。 クラスもしくはインタフェースが@ThreadSafe
を付与されているとき、そのクラス/インタフェースの全サブクラスも検査する。RacerDでのコードカバレッジを増やす際には、オプションのアノテーションを追加するとよい。@ThreadConfined
や@Functional
、@ReturnsOwnership
、@VisibleForTesting
だ。
RacerDの解析は通常のinfer
コマンドで起動する。これは同時に他のInferの解析も実行する。もしくはinfer --racerd-only
コマンドでRacerDだけ実行する。たとえばコマンドinfer --racerd-only -- javac StockPortfolio.java
はStockPortfolio.java
に対してRacerDを実行する。
以下のサンプルコードはRacerDが検査し、競合状態を1つ警告している。
@ThreadSafe
public class StockPortfolio {
int shares = 0;
public void buy(int count) {
if (count > 0) {
shares += count;
}
}
public int sell(int count){
if (count >= 0 && shares - count >= 0) {
shares -= count;
return shares;
} else {
return 0;
}
}
}
RacerDがバグを発見
読み込み/書き込みの競合。publicメソッドint StockPortfolio.sell(int)はフィールドStockPortfolio.sharesから読み込んでいる。メソッドvoid StockPortfolio.buy(int)とint StockPortfolio.sell(int)による書き込みと競合する可能性がある。
RacerDは保護されていない書き込みか読み込み/書き込みかいずれかを含むデータ競合も警告する。RacerDは現在データ競合のチェックのみに限られる。他の並列処理の問題、デッドロックやアトミック性などはチェックしない。またRacerDは以下の原因でデータ競合を見落とす。
- エイリアス
- そのスコープの外にあるローカルに宣言されたオブジェクト
- 異なるロックで保護されたアクセス
- 所有されていないオブジェクトが入っているローカルオブジェクト
- weakメモリとJavaのvolatileキーワード
こうした限界はたとえフォールス・ネガティブとなってもフォールス・ポジティブを減らすという設計目標に起因する。
共同作成者であるSam Blackshear氏とPeter O'Hearn氏が告知にこう書いている。
Inferはフェイスブックでコードレビューにおけるバッチモードのデプロイとボット参加者の両方で使われています。コードレビューに対するデプロイでは、Inferをフェイスブックの継続的統合(CI)システムの一部として実行します。開発者が書いた各コードの変更に対して、CIはコンパイルやテストといった他のジョブと同時にInferを実行します。
RacerDはGitHubにあり、ユーザガイドにより詳しい情報がある。
Rate this Article
- Editor Review
- Chief Editor Action