計算機言語システム論 10/02 論文サーベイ

35
計計計計計計計計計計 10/02 計計計計計計 計計 計計 ( 計計計計計 D1)

Upload: bianca

Post on 09-Jan-2016

85 views

Category:

Documents


2 download

DESCRIPTION

計算機言語システム論 10/02 論文サーベイ. 吉野 寿宏 ( 米澤研究室 D1). 今回の論文. M. Naik, A. Aiken, J. Whaley. Effective Static Race Detection for Java . PLDI ’06. Race detection を行うシステム Chord を実装した http://www.stanford.edu/~mhn/chord.html にて入手可 Chord を用いて実際のアプリケーションの race condition を発見し、バグの修正につながった. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: 計算機言語システム論  10/02 論文サーベイ

計算機言語システム論 10/02

論文サーベイ吉野 寿宏

( 米澤研究室 D1)

Page 2: 計算機言語システム論  10/02 論文サーベイ

今回の論文

M. Naik, A. Aiken, J. Whaley. Effective Static Race Detection for Java. PLDI ’06. Race detection を行うシステム Chord を実装

した http://www.stanford.edu/~mhn/chord.html にて入手

可 Chord を用いて実際のアプリケーションの ra

ce condition を発見し、バグの修正につながった

Page 3: 計算機言語システム論  10/02 論文サーベイ

背景 :Race Detection

Race ( 競合 ) とは何か? マルチスレッドのプログラムが同一のメモリ領域

に対して同時に ( 同期なしに ) 参照を行うこと しかも少なくとも一つが書き込みアクセスである

ような場合

Race はバグの元である プログラムの invariant ( 常に成り立っているべき

条件 ) を壊すおそれがある スケジューリングなどの状況により発生し、再現

が難しい

Page 4: 計算機言語システム論  10/02 論文サーベイ

An Example of Race

JdbF からの例

public class ConnectionSource { private Connection conn; private boolean used;   public Connection getConnection() throws SQLException { if (!used) { used = true; return conn; } throw new SQLException(...); }};

ロックをかけていない スレッド

1      2

2 2 スレッドがスレッドがConnection Connection をを持ってしまう!持ってしまう!

Page 5: 計算機言語システム論  10/02 論文サーベイ

既存研究 (1)

動的な検出 既存研究の多くはほとんどこちらの手法 Happens-before relation[L. Lamport 1978]

時間順に起こらなければならない制約を表す半順序 False negative が非常に多い ( 検出精度が悪い )

Lockset algorithm スレッドの保持しているロックを動的に管理 lock/unlock 以外の同期手法を使うと false positive

が出る

Page 6: 計算機言語システム論  10/02 論文サーベイ

既存研究 (2)

静的な検出 本論文はこちらの手法に分類される 型検査器によるシステム

同期に関する挙動を型などで表す方式 しかし型を自動的に推論することは非常に難しい

モデル検査器によるシステム Path sensitive な解析をするのでさまざまな同期機

構に対応できる しかし open program には対応できない

静的 Lockset algorithm

Page 7: 計算機言語システム論  10/02 論文サーベイ

Static Race Detection はどうあるべきか?

5 つの指標を掲げている 正確さ

False positive ( 誤検知 ) の確率は十分に低いか? スケーラビリティ

大規模なプログラムも現実的な時間で解析できるか? 幅広い同期機構への対応

現実に用いられている同期機構に対応できるか? それ自身で閉じていないプログラム ( ライブラリ

やデバイスドライバ等 ) への対応

( デバッグのための ) 反例生成の枠組み

Page 8: 計算機言語システム論  10/02 論文サーベイ

Chord

中核は k-object sensitivity[Whaley, Lam 2004] によるエリアス解析 BDD (Binary Decision Diagram) を用いて効率化

bddbddb[Lam, Whaley 2005] による実装 全体として 4 つのステージ

Reachable-/Aliasing-/Escaping-/Unlocked-Pairs Computation

いずれも実行箇所のペア ( 別スレッドで同時に実行される箇所を抽出したいことに注意 ) を扱う

各ステージで、 race にならないものを枝狩りしていく Flow-insensitive な解析 ⇒ Unsound な手法

False positive/false negative が出る可能性がある

Page 9: 計算機言語システム論  10/02 論文サーベイ

Chord: システム構成図

Page 10: 計算機言語システム論  10/02 論文サーベイ

Open Program の扱い

それ自体では完結しないプログラムは、補完してから検証の必要がある ライブラリ等は、自身がどのように呼び出され

るかわからない (missing caller) テスト用の harness を生成してやる必要

またプログラムが依存するライブラリの挙動が不明な場合もある (missing callee)

Java の native method など Chord では一部をモデル化し、それ以外は nop と等

価として扱っている ( このあたりも unsoundness の要因 )

Page 11: 計算機言語システム論  10/02 論文サーベイ

Test Harness Synthesis

プログラムを解析するにあたって、エントリポイント (main) を自動生成 チェックしたいインターフェイス (I とする ) に含ま

れるメソッドの引数をローカル変数として準備 参照型の変数に、非決定的に同じ型の値を代入 I のそれぞれのメソッドを、上で準備した値を用い

て非決定的に呼び出し、結果を型の合う変数に代入

詳細は後ほど例を出します

Page 12: 計算機言語システム論  10/02 論文サーベイ

Synchronization Idioms

Java にはいくつかの同期手法がある synchronized(expr) { … }

自然に扱うことができる fork/join synchronization

Flow sensitive な ( プログラムの場所を考慮する )解析が必要

Chord は flow insensitive なので、ユーザが annotation をつけてやる必要がある

オブジェクトのモニタ (Object#wait/notify) あまり重要ではない、と著者らは書いている

Page 13: 計算機言語システム論  10/02 論文サーベイ

Stage 1:Reachable-Pairs Computation

Page 14: 計算機言語システム論  10/02 論文サーベイ

Original-Pairs Computation

まず最初に、プログラムの中で同じ変数を使う可能性のある場所をすべて列挙する インスタンス変数 f 、 static 変数 g 、配列 a への

read/write アクセスを行う場所の組 Soot framework[R. Vallée-Rai et al. 1999] により求める インスタンス変数は、同一インスタンスの中のみを考慮

すればよい

しかしこれはものすごく大雑把な解析⇒ 後段の解析により refine してい

Page 15: 計算機言語システム論  10/02 論文サーベイ

Original-Pairs Computation

Page 16: 計算機言語システム論  10/02 論文サーベイ

Original-Pairs Computation: 例public class A { int f;

public A() { this.f = 0; } private int rd() { return this.f; } private int wr(int x) { this.f = x; return x; } public int get() { return this.rd(); } public synchronized int inc() { int t = this.rd() + (new A()).wr(1); return this.wr(t); }}

writeread

OriginalPairs ={(fr, fw), (fw, fw), (fr, f’w), (f’w, f’w), (fw, f’w)}

Page 17: 計算機言語システム論  10/02 論文サーベイ

Reachable-Pairs Computation

プログラムのエントリポイントから到達可能でなければ race は起こらない Race を起こす組は、 main からどこかスレッド

を立ち上げる箇所を経由して到達可能なはず

到達可能性により Original-Pairs を枝狩り コールグラフ ( 呼び出し - 呼び出されの関係をグ

ラフにしたもの ) の解析による

Page 18: 計算機言語システム論  10/02 論文サーベイ

Call Graph

遷移関係の定義

  は call site と context から、そこで呼ばれるメソッドと context の組を与える関数

Ifork は、スレッドを立ち上げる (thread-spawning) call site の集合

→ と ⇒ の違いは、スレッドの起動が起こりうるかどうか

→n 、⇒ n も帰納的に定義できる

Page 19: 計算機言語システム論  10/02 論文サーベイ

Computation of Reachable Pairs

Call Graph の関係 ( の反射推移閉包 ) を用いて、次のように計算される

  は main から到達可能な thread-spawning call site とコンテクストの集合

   は call site ( またはメモリアクセス ) からそれが含まれるメソッドを返す関数

ReachablePairs が求める集合

Page 20: 計算機言語システム論  10/02 論文サーベイ

public class A { public int get() { return this.rd(); } public synchronized int inc() { int t = this.rd() + (new A()).wr(1); return this.wr(t); }

static public void main() { A a; if(*) a = new A(); if(*) a.get(); if(*) a.inc(); }}

Reachable-Pairs Computation: 例

ReachablePairs ={(fr, fw), (fw, fw), (fr, f’w), (f’w, f’w), (fw, f’w)}

コンストラクタの race は検出しな

いので消える

Test Harness

Page 21: 計算機言語システム論  10/02 論文サーベイ

public class A { public int get() { return this.rd(); } public synchronized int inc() { int t = this.rd() + (new A()).wr(1); return this.wr(t); }

static public void main() { A a; if(*) a = new A(); if(*) a.get(); if(*) a.inc(); }}

Reachable-Pairs Computation: 例

ReachablePairs ={(fr, fw), (fw, fw), (fr, f’w), (f’w, f’w), (fw, f’w)}

ReachablePairs ={(fr, fw), (fw, fw), (fr, f’w), (f’w, f’w), (fw, f’w)}

ReachablePairs ={(fr, fw), (fw, fw), (fr, f’w), (f’w, f’w), (fw, f’w)}

Page 22: 計算機言語システム論  10/02 論文サーベイ

Stage 2:Aliasing-Pairs Computation

Page 23: 計算機言語システム論  10/02 論文サーベイ

Aliasing-Pairs Computation

同じ変数実体に同時にアクセスしていない限り race は起こらない あるオブジェクトの異なるインスタンスにある同一名の変

数 エリアスしていない配列へのアクセス

エリアスしていてもインデックスが異なれば race にはならないが、ここでは保守的にインデックスは省いて考えている

Reachable-Pairs として計算されたものからエリアス解析により枝狩り k-object sensitive alias analysis[Milanova et al. 2002] の手法をここ

では用いる Flow insensitive, context/object/field sensitive analysis Inclusion-base analysis

Page 24: 計算機言語システム論  10/02 論文サーベイ

エリアス解析 (Alias Analysis)

オブジェクトへの参照が同じ場所を指しているかどうかを静的に解析する手法 参照 = ポインタ (C, C++) 、参照 (C++, Java, C

# ...)

たとえば、次のコードは安全か?void swap(int* x, int* y) { *x ^= *y ^= *x ^= *y; }

x == y だったら *x も *y も 0 になってしまう! そうならないことを保証するために、エリアス解析

が有効

Page 25: 計算機言語システム論  10/02 論文サーベイ

Stage 3:Escaping-Pairs Computation

Page 26: 計算機言語システム論  10/02 論文サーベイ

Escaping-Pairs Computation

複数のスレッドに共有されていないデータは race を引き起こさない Aliasing-Pairs をさらに枝狩りできる

データ共有のためには 2 つの場合がある メソッド呼び出し (thread-spawning) における引数

explicit な呼び出し (java.lang.Runnable#start) implicit な呼び出し (main から )

オブジェクトのフィールドとしての共有

Page 27: 計算機言語システム論  10/02 論文サーベイ

Stage 4:Unlocked-Pairs Computation

Page 28: 計算機言語システム論  10/02 論文サーベイ

Unlocked-Pairs Computation

( 共通の ) ロックをとっている組は race を引き起こさない Call graph と alias analysis から導出できる しかし計算量等の観点から、いくつか unsound

な仮定が必要になる 次で説明

Page 29: 計算機言語システム論  10/02 論文サーベイ

Unlocked-Pairs Computation

UnlockedPairs’’ のほうが正確 しかし UnlockedPairs’’ はすべてのパスについて計算する

必要があるので計算量が膨大 UnlockedPairs’’ ⊆ UnlockedPairs’ になっている ( 証明済 )

つまり、 false positive が出る可能性がある

May-alias の解析しかしていない 「正しく」やるためには、 must-alias (True と判断された

場合は必ず alias) の解析が必要 ⇒ Chord が race-free と結論づけた場合でも、ひょっとすると別のオブジェクトに対して同期しているかもしれない

False negative が出る可能性がある しかし実験中にそのような不都合は起きなかった、とのこと

Page 30: 計算機言語システム論  10/02 論文サーベイ

後処理

最後まで残った変数アクセスの組を race の可能性があるものとして報告 そこに至るまでのパスを反例として出力 どの変数、またはオブジェクトが race を起こ

しているのかを表示する

しかし最終的に本当のバグによるものかを判断するには人手が必要

Page 31: 計算機言語システム論  10/02 論文サーベイ

public class A { int f;

public A() { this.f = 0; } private int rd() { return this.f; } private int wr(int x) { this.f = x; return x; } public int get() { return this.rd(); } public synchronized int inc() { int t = this.rd() + (new A()).wr(1); return this.wr(t); }}

Escaping-Pairs ={(fr, fw), (fw, fw)}

Unlocked-Pairs Computation: 例

inc() は synchronized メソッドなので、同時に到達することはない

Page 32: 計算機言語システム論  10/02 論文サーベイ

Chord の評価実験

実際に広く使われているプログラムを検証

Page 33: 計算機言語システム論  10/02 論文サーベイ

実験結果 (1)

速度 646KLoC を 30 分弱で検査完了 大規模プロジェクトでも使用に耐える

アノテーションはほとんど必要なかった 手動でつけてもそれほど

苦にはならない

Page 34: 計算機言語システム論  10/02 論文サーベイ

実験結果 (2)

発見された race False alarm が出ている箇所はさほど多くない

実際開発者に報告して修正がされたケースも Apache commons-pool における 17 箇所のバグの

指摘に対し、実際に 5 箇所に修正パッチが出た

Page 35: 計算機言語システム論  10/02 論文サーベイ

まとめ

静的解析により race を見つけ出すための画期的な手法を提案した bddbddb を用いてシステムを実装した 広く使われている ( マルチスレッド ) プログラ

ムを用いてベンチマークを行った

かなり巨大なプログラムでも現実的時間内で解析可能であることが確かめられた

False positive の数が少ないことが確かめられた 実際にバグの解決に役立った事例もある