250 likes | 397 Views
プログラムの変更前後での 実行履歴の差分検出手法. 大阪大学大学院情報科学研究科 ○伊藤芳朗 渡邊結 石尾隆 井上克郎. 概要. 背景 オブジェクト指向プログラムの解析 実行履歴の比較 提案手法 プログラムの変更前後での実行履歴の差分検出手法 実験 ソースコードの変更による影響を確認 まとめ. 背景. オブジェクト指向プログラム オブジェクト同士の相互作用としてシステムの振る舞いを捉える考え方 実行時の動作を理解するのは難しい クラスの継承 多態性(ポリモーフィズム) オブジェクト指向プログラムの動作理解 実行履歴等の動的情報の解析が有効
E N D
プログラムの変更前後での実行履歴の差分検出手法 大阪大学大学院情報科学研究科 ○伊藤芳朗 渡邊結 石尾隆 井上克郎
概要 • 背景 • オブジェクト指向プログラムの解析 • 実行履歴の比較 • 提案手法 • プログラムの変更前後での実行履歴の差分検出手法 • 実験 • ソースコードの変更による影響を確認 • まとめ
背景 • オブジェクト指向プログラム • オブジェクト同士の相互作用としてシステムの振る舞いを捉える考え方 • 実行時の動作を理解するのは難しい • クラスの継承 • 多態性(ポリモーフィズム) • オブジェクト指向プログラムの動作理解 • 実行履歴等の動的情報の解析が有効 • オブジェクト間のメソッド呼び出し関係を可視化
@1 0 void org.jhotdraw.samples.draw.Main(0).main(java.lang.String[]){ 返り値の型 クラス名 オブジェクトID スレッド番号 タイムスタンプ メソッド名 引数の型 実行履歴 • プログラム実行時のメソッド呼び出し系列 • 実行時に決定される情報が記録されている • サイズが巨大になりがち • 画像編集ソフトで簡単な操作をしただけで5万回のメソッド呼び出し @1 0 void org.jhotdraw.samples.draw.Main(0).main(java.lang.String[]){ @1 1 void org.jhotdraw.app.DefaultSDIApplication(1).<init>(){ @1 2 void org.jhotdraw.app.AbstractApplication(1).<init>(){ @1 } @1 3 void org.jhotdraw.samples.draw.DrawApplicationModel(2).<init>(){ @1 4 void org.jhotdraw.app.DefaultApplicationModel(2).<init>(){ @1 } @1 } @1 } @1 5 void org.jhotdraw.app.DefaultApplicationModel(2).setName(java.lang.String){ @1 6 void org.jhotdraw.beans.AbstractBean(2).firePropertyChange(){
シーケンス図生成システム Amida • Javaプログラムの実行履歴を取得し,シーケンス図を生成するシステム • メソッドの呼び出し関係をシーケンス図で表示 • ループや再帰呼び出しを圧縮する機能を持つ • シーケンス図が巨大になるのを防ぐ 谷口, 石尾, 神谷, 楠本, 井上: “プログラム実行履歴からの簡潔なシーケンス図の作成手法” , コンピュータソフトウェア,Vol.24,No.3 (2007),pp.153-169.
A B C D E F G H I シーケンス図 • オブジェクト間のメッセージ通信を時系列に沿って表現する • システムの設計時に作成される • プログラムの動作の理解に有効
プログラムの振る舞いの比較の必要性 • ソースコードを変更すると実行時の動作が変わる • デバッグ作業でのソースコードの変更 • ソースコードの変更が正しいかの確認したい • 予想していない動作の変化を発見したい • プログラムの振る舞いを比較する必要がある • 実行時の動作は実行履歴に記録される • 実行履歴を比較すれば動作の変化がわかる • ソースコードの変更前後で同じシナリオを実行する • ソースコードの変更による動作の変化が表れる
実行履歴の比較の問題点 • 実行履歴は巨大 • 人間が比較すると時間がかかってしまう • 予想していない変更点の発見が困難 • 実行履歴ごとに生成したオブジェクトのIDが異なる • オブジェクトIDは生成順序やメモリ上の配置などを元に実行ごとに決定される • 同じ役割のオブジェクトの対応が取れない
提案手法 • 2つの実行履歴を比較し,動作の変化を検出する • ソースコードの変更前後で同じシナリオを実行した実行履歴を取得 • メソッドの呼び出し関係を木構造にして比較し,動作の変化を検出 • 動作の変化を可視化する • 可視化にはAmidaを利用し,シーケンス図を生成する • 実行履歴全体のシーケンス図を生成 • 動作の変化である部分を強調表示
A B C D E F G 0 2 0 1 3 4 1 5 5 2 3 6 6 6 6 4 木構造への変換 • 実行履歴をメソッド呼び出し関係木に変換する • 1つのメソッド呼び出しを1つのノードにする • メソッドの実行中に呼ばれたメソッドを子ノードとする メソッド呼び出し関係木
メソッド呼び出し関係木の比較 • 一方のメソッド呼び出し関係木の中から部分木を取り出し,一致する部分木があるか判定する • トップダウン方式で比較していく • 部分木が一致したら,ノードにマークをつける • マークのついた部分木は変化していない部分である • 全ての部分木で探索が終わったら比較が終わる • 最終的にマークのないノードが変化した部分だとわかる
部分木の一致条件 • 部分木の一致条件 • 部分木の形状が完全に一致する • 2つの木の対応する位置にあるノードが1対1で対応する • ノードの一致条件 • 呼び出し元のオブジェクトが一致する • メソッド呼び出しイベントが一致する • メソッド呼び出し名,オブジェクト名,引数の型,返り値の型が全て一致する • スレッド番号,タイムスタンプ,オブジェクトIDは実行履歴ごとに異なるため一致条件に使用しない
メソッド呼び出し関係木の比較の例 • 左側の木の部分木に一致する部分木を探す • ノード1と一致するノードを探す • ノード1の子ノードが一致するか調べる • ノード3の子ノードが一致するか調べる • 一致する部分のないノードは変化した部分とする 0 0 1 1 5 7 2 3 2 3 6 6 6 4 4
0 1 2 3 4 5 6 3 5 6 シーケンス図へ可視化 • 実行履歴全体をシーケンス図にする • 変化した部分を強調して表示 • 変化した部分を自動で探索 • シーケンス図が巨大になると探すのが困難 • 変化した部分に関係する一連のメソッド呼び出しを抜き出す 抽出
適用実験 • 実験の目的 • 提案手法で実際にソースコードの変更による振る舞いの変化を確認する • 実験対象 • 画像編集ソフトJHotDrawの実行履歴 • バージョン7.3と7.3.1で同じシナリオを実行 • 「プログラムを起動し,三角形を1つ描き保存せずに終了する」 • ライブラリの呼び出しは記録しない
実験結果 • 実際にソースコードの変更を動作の変化として表示できた • 振る舞いが変化したと判定された部分を調査 • 3個のクラスで変更点を発見 • 新しいメソッドの追加(DefaultDrawingEditorクラス) • メソッドの処理の変更(AbstractToolクラス) • コンストラクタの処理の変更(DefaultDrawingViewクラス) • ソースコードが変更されていないのに動作の変化があると判定された • 実行時に派生クラスが変わっていたため (IncreaseHandleDetailLevelActionクラス)
実験対象の詳細 • JHotDrawのバージョン間の変更 • 変更があったのは全部で45個のクラス • 取得した実行履歴 • 「メソッド呼び出しに影響のある変更がされたクラス」について調査 • 実験では3個のクラスを全て発見することができた
考察 • 提案手法のメリット • 全体の流れが追える • メソッドを追加したときにどのような影響が出たのかが分かる • 予期しない変化があった場合,どのような状況で呼び出されているかが分かる • ソースコードの変更以外に適用 • 設定ファイルや入力データの変更による動作の変化 • 入力による振る舞いの変化の理解 • バグ検出に応用
提案手法の現状と今後の課題 • 実行時間の削減 • マルチスレッドへの対応 • クラス名の変更への対応
実行時間の削減 • 比較計算に時間がかかる • 実験で使用した実行履歴で約11分 • 対策 • ハッシュを使用する • 前処理として部分木のハッシュ値を求め,比較を行う • Amidaのループ圧縮と組み合わせる • ループ圧縮によりメソッド呼び出し関係木のノード数を減らす • ループ圧縮にも計算時間が必要なため,効果を調べる必要がある
マルチスレッドへの対応 • スレッド名が同じスレッドを比較 • スレッド単位でメソッド呼び出し関係木を構築し比較 • スレッド名を変更されると比較計算ができない • 対策 • どのスレッドがどこで生成されたかを解析する • スレッドオブジェクトのコンストラクタ呼び出しで区別 • 呼び出し元が同じスレッド同士を比較する • スレッド名が変わっても対応が取れる
クラス名の変更への対応 • クラス名だけが変わり,内部の振る舞いが変わっていない場合 • 現在は全て変化として表示 • 「クラス名の変更も変化として表示すべき」 • クラス名の変更以外の変化が分かりづらくなる • 対策 • 比較時に変更情報を与える • クラス名が違っても振る舞いが同じならば変化と判定しない • 変更情報を事前に知る必要がある
まとめ • まとめ • プログラムの変更前後での実行履歴の差分検出手法を提案した • プログラムの変更による動作の変化を検出 • 検出した動作の変化をシーケンス図に視覚化 • 実験を行い,動作の変化からソースコードの変更点を発見した • 3個のクラスの変更を発見できた