180 likes | 341 Views
デバッグ支援のための グラフベース推薦システム. 九州工業大学 塩塚大 九州 大学 鵜林尚靖. 概要. 見たことない 例外 に直面 !. 例)同じ例外に関連した修正 例) API の誤りやすい例. public class Property { public String readFile (String pathname) throws IOException { String val = null; File file = new File(pathname);
E N D
デバッグ支援のためのグラフベース推薦システムデバッグ支援のためのグラフベース推薦システム 九州工業大学 塩塚大 九州大学 鵜林尚靖
概要 見たことない 例外に直面! 例)同じ例外に関連した修正 例)APIの誤りやすい例 public class Property { public String readFile (String pathname) throws IOException { String val = null; File file = new File(pathname); FileReader fileReader = new FileReader(file) ; BufferedReader br = new BufferedReader(fileReader); val = br.readLine(); return val; } } public class Property { public String readFile (String pathname) throws IOException { String val = null; File file = new File(pathname); FileReader fileReader = new FileReader(file) ; BufferedReader br = new BufferedReader(fileReader); val = br.readLine(); return val; } } プロジェクトXXXの リポジトリ public class Property { public String readFile (String pathname) throws IOException { String val = null; File file = new File(pathname); FileReader fileReader = new FileReader(file) ; BufferedReader br = new BufferedReader(fileReader); val = br.readLine(); return val; } } プロジェクトXXXの リポジトリ APIの 使い方が間違ってる?! プロジェクトXXXの リポジトリ 生成 推薦 DCG 関心事 既存のリポジトリを活用! 他プロジェクトを活用! Debug Concern Graph 実行 生成 TDD(テスト駆動開発) デバッグのノウハウの収集 ・テスト結果の取得 ・関連したプログラム要素の取得 ・修正パターンの取得
発表の流れ 1.問題意識 2.DCG 3.ツールdcNavi 4.実験 5.関連研究 6.今後の課題
1.問題意識 public class Property { public String readFile (String pathname) throws IOException { String val = null; File file = new File(pathname); FileReader fr = new FileReader(file) ; BufferedReader br = new BufferedReader(fr); val = br.readLine();// 1行読み込む return val; } } public class PropertyTest extends TestCase { public void testReadFile () throws IOException { Property property = new Property(); assertEquals(“true”, property.readFile("property.txt")); } public void testReadFileFileNotExist () throws IOException { Property property = new Property(); // property2.txt は存在しないファイル assertEquals(null, property.readFile(“property2.txt”)); } } 例外 FileNotFoundException 発生! テスト対象プログラム テストプログラム • 例題シナリオ • A君:プログラミング初心者 • readFileメソッド:ファイルから1行読み込みその値を返す • 発生した問題:ファイルが存在しない場合のテストで例外FileNotFoundExceptionが発生
デバッグの際にA君が困ったこと バグ情報の利用方法: • 例外から察するにファイルが存在しない場合の処理が要求されているが、どこをどのように修正すべきか? ライブラリ利用方法: • ライブラリの使い方が間違っているのではないか? テスト作成方法: • 他にテストすべき項目はないのか? 修正箇所: • ソースコードのどこを特に注意して見直すべきか?
考えられる解決策 [解決策] 同様の例外に直面したときのソースコードを見つけ出し、あるライブラリ利用における誤りやすい例と、そのときの修正方法を提示するのが有効 [課題] 発生した例外/テスト結果の蓄積 ライブラリの利用に際し、どのような修正が頻繁に行われるのかの蓄積 ⇒ デバッグ履歴の表現としてデバッグ関心事グラフ(DCG)を提案
2.DCG readFile のデバッグ :クラス :テスト結果 :メソッド :修正パターン diff-1 diff-2 バグ修正パターン(全27種) MC-DAP: メソッド呼出しのパラメータの変更 SQ-AROB: メソッド呼出しの追加 MC-DM:同一オブジェクトに対する呼び出すメソッドの変更 BufferedReader File Property PropertyTest Property File PropertyTest 修正パターン*: メソッド呼出の追加 FileReader exist readFile testReadFileFileNotExist testReadFile readLine readFile テスト成功 assertEquals testReadFileFileNotExist テスト成功 ⇒ デバッグ終了 テスト失敗 例外:FileNotFound *Pan, K., et al.: Toward an understanding of bug fix patterns. Empirical Software Engineering, pp.286-315, 2009. テスト成功 テスト失敗 ⇒ デバッグ開始 readFileメソッドのテスト失敗から成功までに作られるDCG • 下の図が先ほどのreadFileメソッドのテスト失敗から成功までに作られるDCG • 説明の都合上、修正後テストに成功したとしている
3.ツールdcNavi テスト結果:JUnitを利用 修正パターン:diff + ASTParser SQ-AROB: メソッド呼び出しの追加/削除 関連したメソッド、フィールド、クラス:Mylyn*を利用 Eclipse上でのファイル閲覧、編集、カーソル位置などを監視し作業(タスク)に関連した要素を記録. *Kersten, M. and Murphy, G. C.: Mylar: a degree-of-interest model for IDEs. In AOSD 2005, pp.159-168, 2005. • 統合開発環境Eclipseのプラグインとして作成 • 機能1.デバッグ活動を監視しDCGを自動生成 • 機能2.関連情報を推薦 • 機能3.既存のSVNなどのバージョン管理システムからDCGを生成
推薦機能の利用例 • 一般的なデバッグの流れ テスト対象プログラム(再掲) public class Property { public String readFile (String pathname) throws IOException { String val = null; File file = new File(pathname); FileReader fr = new FileReader(file) ; BufferedReader br = new BufferedReader(fr); val = br.readLine();// 1行読み込む return val; } } 支援範囲 テスト実行.例外FileNotFound発生 トレース実行などで例外箇所を特定⇒FileReaderを特定 FileReader()のドキュメントを読む「FileNotFoundException - if the file does not exist, is a directory rather than a regular file, or for some other reason cannot be opened for reading.」 原因として引数のfileに問題があるのではと推測(原因推測) 具体的な修正方法を考え修正.テスト再実行し成功すれば終了.失敗した場合4, 5を繰り返す.
推薦結果を得るまでの過程 readFileのデバッグ Q1. アルゴリズム 1)指定した例外から辿れる修正パターン見つける。 2)複数ある場合は、グラフの要素間の類似度が高いものを優先 3)他のテストにより作られたものを優先 4)修正パターンを含むソースコードを順に推薦 ・・・ ・・・ ・・・ ・・・ ・・・ 入力 calls 共通要素 関連性有り! テスト失敗 例外:FileNotFound readLine calls H1:readFileのデバッグ H2:JUnitTestRunMonitorのデバッグ プログラム要素間の類似度(H1, H2) = 共通要素数/ ((H1の総数 + H2の総数) / 2) 例)|H1| = 30, |H2| = 40, |H1∧H2| = 20 20 / ((30 + 40)/2) =0.57 例)|H1| = 30, |H2| = 40, |H1∧H2| = 30 30 / ((30 + 40)/2) =0.85 修正パターン: メソッド呼出の追加 ・・・ 推薦 (出力) ・・・ ・・・ ・・・ JUnitTestRunMonitorのデバッグ
推薦結果の例 • JUnitTestRunMonitorコンストラクタが推薦された • - readFileメソッドと似たファイル操作をしている • - メソッド呼出し(SQ-AROB)追加が行われた • - 修正方法として、メソッド呼出しを追加すればいいと推測できる! if文追加パターン? 修正箇所:メソッド呼出し追加(SQ-AROB) 修正前 修正後
リポジトリからのDCG生成方法 public class Property { public String readFile (String pathname) throws IOException { String val = null; File file = new File(pathname); FileReader fileReader = new FileReader(file) ; BufferedReader br = new BufferedReader(fileReader); val = br.readLine(); return val; } } public class Property { public String readFile (String pathname) throws IOException { String val = null; File file = new File(pathname); FileReader fileReader = new FileReader(file) ; BufferedReader br = new BufferedReader(fileReader); val = br.readLine(); return val; } } public class Property { public String readFile (String pathname) throws IOException { String val = null; File file = new File(pathname); FileReader fileReader = new FileReader(file) ; BufferedReader br = new BufferedReader(fileReader); val = br.readLine(); return val; } } [取出し]バグ修正リビジョンRに関連したソースコード コミットログのキーワードで特定: ”bug”, “fix”, “patch” ⇒ テスト成功に対応 リビジョンT のデバッグ リビジョンS のデバッグ diff-1 diff-2 リビジョンR のデバッグ diff-1 diff-2 diff-1 diff-2 プロジェクトAのSVN diff-1 diff-2 diff-1 diff-2 関連したプログラム要素 + 修正パターン プロジェクトA のDCG 依存する プロジェク 依存する プロジェク 依存する最新の プロジェク public class Property { public String readFile (String pathname) throws IOException { String val = null; File file = new File(pathname); FileReader fileReader = new FileReader(file) ; BufferedReader br = new BufferedReader(fileReader); val = br.readLine(); return val; } } public class Property { public String readFile (String pathname) throws IOException { String val = null; File file = new File(pathname); FileReader fileReader = new FileReader(file) ; BufferedReader br = new BufferedReader(fileReader); val = br.readLine(); return val; } } public class Property { public String readFile (String pathname) throws IOException { String val = null; File file = new File(pathname); FileReader fileReader = new FileReader(file) ; BufferedReader br = new BufferedReader(fileReader); val = br.readLine(); return val; } } [取出し]バグリビジョンRに関連したソースコード ⇒ テスト失敗に対応 • 対象リポジトリ:SVN • 生成DCG:関連したプログラム要素 + 修正パターン の2情報を持つ • ※ 例外やテスト結果の取得は現状では未対応
4.実験 • 準備.リポジトリからのDCG生成 • DCG生成時間の確認 • Eclipseプラグインで、Mylynに関連した9つのオープンソース • 実験.推薦量/推薦時間/推薦の質の確認 • 上記で生成したDCGを利用 [実施環境] CPU: Atom N280(1.66GHz), RAM:1GB, OS:Windows XP
DCG生成結果 • DCG生成時間の目安: • 1000のバグ修正リビジョン ⇒ 80分 • DCG生成40分、リポジトリからのファイルのエクスポート40分
実験 推薦元データ 修正対象 推薦 + 自プロジェクトの 残りのDCGの1/5 自プロジェクトの DCGの4/5 他の8プロジェクトの DCG全部 • 例外情報無しで関連したプログラム要素の類似度で検索 • 推薦量/推薦時間を確認 • 推薦の質は修正パターンの一致/不一致で評価
結果 推薦量/推薦時間ともに十分 修正候補一致度は9プロジェクト全体で平均15.4%
5.関連研究 [実行履歴&クエリを使ったデバッグ] • Debugging by Asking Questions About Program Output [Ko, A.J. ICSE2006] • 問題コードの代わりに、実行履歴などの出力に対して質問を重ねていくことで問題箇所を絞り込んでいく方法を提案 [履歴活用のデバッグ] • DebugAdvisor: A Recommender System for Debugging [Ashok, B., et al. FSE2009] • バージョン管理,バグデータベース,デバッガログなど統合して類似バグが検索できるクエリ(fat query)を提案 • 本研究では、自プロジェクトの履歴 + 他プロジェクトの履歴を活用した推薦を実現⇒ プロジェクトの初期段階(履歴が無い状態)でも利用可能
6.今後の課題 • 推薦の質の向上 • テスト実行結果を含めたDCGの生成 • リポジトリからファイルを取出した際に依存するテストも実行 • if文関連の修正パターンへの対応(論理エラー) • 例)nullチェックパターン:どういった型のオブジェクトに対しチェックが必要なのか.チェック漏れが起こりやすいのか • 実行履歴と組み合わせて活用