日本ソフトウェア科学会第 31 回大会 (2014 年度) 講演論文集

REMViewer: 複数回実行された Java メソッドの実行経路可視化ツール
松村 俊徳

石尾 隆

鹿島 悠

井上 克郎

プログラムの実行時情報はプログラム理解に有用であることが知られており，Omniscient Debugging などのツールを使うことで開発者は実行の任意の時点の状態を調査することができる．これらのツールはある１つの時点の状態を分析するには有効だが，複数の実行経路を持つようなメソッドの動作を理解するには不十分である．そこで本論
文では，REMViewer (Repeatedly-Executed-Method Viewer) という Java メソッドの複数の実行経路を可視化するツールを提案する．このツールはプログラムの実行を記録しておき，メソッドの 1 回ごとの実行経路を別々のビューとして表示するので，開発者は興味のある実行パスを選択し，それらの実行パスにおける局所変数の状態を比較するといった分析が可能となる．

The state of a program at runtime is useful information for developers to understand a program. Omniscient
Debugging and logging-based tools enable developers to investigate the state of a program at an arbitrary
point of time in an execution. While these tools are eﬀective to analyze the state at a single point of time,they might be insuﬃcient to understand the generic behavior of a method which includes various controlflow paths. In this paper, we propose REMViewer (Repeatedly-Executed-Method Viewer), or a tool thatvisualizes multiple execution paths of a Java method. The tool shows each execution path in a separated
view so that developers can firstly select actual execution paths of interest and then compare the state of
local variables in the paths.

構造や振舞いを把握する前にデバッガを的確に用いる

1 はじめにことは難しい．

プログラム理解において，開発者は対象プログラ

プログラムの実行時の状態を分析する手法には様々

ムのソースコードを読むだけでなく，デバッガを用いなものがあるが，事前のソースコードの調査を必要てプログラムの実行時の状態を分析している [12] [14].

としない技術としては Omniscient Debugging をは

GDB や Eclipse JDT などの広く使われている対話

じめとする “logging-based” 技術 [6] [7] [8] が挙げられ的デバッガでは，開発者はソースコード内の興味のある．たとえば Omniscient Debugging [8] はプログラ

る部分にブレークポイントを前もって設定し，プログ

ム実行中のすべての命令の実行順序と変数の状態をラムを実行する必要がある [11]. 一般的なデバッグ作

記録しておき，プログラムの実行の任意の時点の状態

業であれば，開発者はソースコードの構造を十分にを計算機上で再現，分析する技術である．このような知っていることが多く，このことは問題にならない．

技術は実行時情報を記録するのでプログラムの実行

一方，他人が記述したプログラムの挙動をこれから分速度は低下するが，ソフトウェア保守においてプログ

析しようとしている開発者にとっては，プログラムのラムの動作を理解する上で有望なアプローチである

REMViewer: A Visualization Tool for Multiple Execution Paths of Java Method
Toshinori Matsumura, Takashi Ishio, Yu Kashima,
Katsuro Inoue, 大阪大学大学院情報科学研究科, Graduate School of Information Science and Technology,
Osaka University.

とされている．
プログラムの実行時の状態を再現する手法は既に実現されているが，その再現結果をプログラム理解に活用する方法については，十分な研究はなされていない．デバッグ作業では，バグによって生じた障害

の原因を究明することが目的となっているため，プログラムの実行のある一時点（バグによって発生した障2 REMViewer

害を観測した時点）を調査の起点として，そこに至っ

REMViewer は Java を対象とした実行トレース

た実行経路を分析することに主眼が置かれている [7]．

(execution trace) の可視化ツールである．本ツール

しかし，メソッドの一般的な動作を理解するには，特はあらかじめプログラムの実行を観測，記録してお定の時点の調査だけでは不十分な可能性がある．たとき，ユーザーによって指定されたメソッドの動作を再えば，メソッドの内部に複数の制御パスが存在する場

現する．ツールは Instrumentation, Replay, Viewer

合，開発者は個々の制御パスについて順番に分析を行という 3 つのコンポーネントで構成されている．In-

わなければならない [13].

strumentation コンポーネントは，ユーザが指定した本研究では，Java メソッドの複数の実行経路を可対象 Java プログラムのバイトコードに実行トレース

視化するツール REMViewer (Repeatedly-を出力する命令を埋め込む．得られたプログラムにExecuted-Method Viewer) を提案する．REMViewer

観測したいテストケースを与えて実行すると，実行はプログラムの実行を記録し，ユーザーの指定したトレースがファイルとして保存される．Replay コン

メソッドについて，そのメソッドの実行すべてを再現

ポーネントは，ユーザに指定されたメソッドの実行時し表示する．個々の制御パスに対する調査を支援するの状態を再現する．Viewer コンポーネントは，得らため，REMViewer はメソッドの実行を実行経路に基れた再現結果を対話的に閲覧する GUI を提供する．

づき分類し，それぞれの分類の代表を可視化し表示する．可視化された実行経路を比較することで，開発

2. 1 実行トレースの記録

者は，興味のある実行を選び，その後局所変数の状態

REMViewer は，実行トレースとしてメソッド間のを比較するといったことが可能となる．通常のデバッ

すべての制御フローとデータフローを記録しておき，

ガにおけるブレークポイントと比較すると，実行完了

メソッド間で受け渡された引数などの情報をもとにメ後の調査という方法に限定するかわり，開発者が実行

ソッド内の命令列を再度実行するという方針で設計さ経路を見てから任意の時刻を選択できる点が特徴で

れている．

ある．
本論文の主要な貢献は以下の通りである．

2. 1. 1 実行トレースの情報
メソッド間の制御フローを表すイベントは，メソッ• Java の任意のメソッドの実行を再現するツール

ドの開始，メソッドの終了，メソッドの呼び出し，例を実現した．メソッドの実行の再生は，ユーザに外の送出と捕捉である．これに加えて，メソッドの引とっての対話的なツールとしての有用性だけでな数と返り値の受け渡し，フィールドと配列へのアクセ

く，他の動的解析手法の研究基盤としても利用可

スに使われた実際の値を記録する．

能である．

すべてのイベントはスレッド ID と命令 ID という• 実行経路の分類による可視化を実現した．2 つ

2 つの属性を持ち，イベントが発生したスレッドとバのプログラムの実行履歴に対して適用し，多くのイトコード命令を識別する．スレッド ID は，プログ

メソッドに有効であることを確認した．

ラムの実行時に，最初に出現したスレッドを 0 番となお，本論文は文献 [9] に対して，実行履歴の観測として，実行トレースへの出現順に割り当てられる数

再生の方法に関する実装の詳細を追加したものとなっ値である．命令 ID は，ログ記録用命令を埋め込む段ている．

階で，観測対象となるバイトコードの各命令に対し以降，2 章ではツールの機能および実装を説明し，て数値を一意に割り当てたものである．各イベント

3 章ではツールの性能，4 章では関連研究，5 章でまは，表 1 に示すように，それぞれのイベントで実際とめと今後の課題について述べる．

に使用されたデータを保持する．たとえば，オブジェ
クトのフィールドを更新するイベントでは，フィール

表1
イベント名
Entry
NormalExit
ExceptionalExit
Call
ReturnValue
GerField
PutField
ObjectCreation
NewArrayMultiNewArray
ArrayLoad
ArrayStore
ArrayLength
Throw
Catch
InstanceOf
MonitorEnter
MonitorExit

イベントの種類

イベントの意味
メソッドの開始
メソッドの正常な終了メソッドの例外発生による終了
メソッドの呼び出し
メソッドの返り値の受け取り
フィールドの読み出し
フィールドへの書き込み
オブジェクトの生成
配列の生成
多次元配列の生成
配列の値の読み出し
配列の値の書き込み
配列の長さの参照
throw 文による例外の送出
catch ブロックによる例外の補足
instanceof 命令の実行
synchronized ブロックの実行開始
synchronized ブロックの実行終了

値
仮引数の値
返り値
例外オブジェクト ID
呼び出しの実引数の値
呼び出し結果の返り値
読み出し対象オブジェクトの ID, 読み出した値
書き込み対象オブジェクトの ID, 書き込んだ値生成されたオブジェクトの ID生成された配列のオブジェクト ID, 配列の長さ生成された配列のオブジェクト ID, 配列の長さ
配列のオブジェクト ID, インデクス, 読みだした値
配列のオブジェクト ID, インデクス, 書き込んだ値
配列のオブジェクト ID, 配列の長さ
例外オブジェクト ID
捕捉したオブジェクト ID
対象のオブジェクト ID, 結果の boolean 値
同期対象のオブジェクト ID
同期対象のオブジェクト IDドに新たに代入される値と，代入の対象となったオである．メソッドの引数など個数が可変のデータは，ブジェクトの ID が記録される．オブジェクト ID は，

メソッド呼び出し等の対応するイベントの直後に，固スレッド ID と同様に，プログラムの実行中に登場し定長のデータ形式に合わせて格納する．文字列オブたオブジェクトに順番に long 型の数値を割り当てた

ジェクトの内容，例外オブジェクトのスタックトレー

ものである．実装では，Java 仮想マシンのガベージ

ス情報などの可変長データは，それぞれ別ファイルとコレクションに影響しないように WeakReference をして出力する．固定長を採用した理由は，圧縮率の向使ったオブジェクトの管理を行い，オブジェクト参照

上と，展開後のデータ系列へのランダムアクセスの実

から ID へと対応付けを行っている．

現である．圧縮後のデータ量では，1 イベントあたり

マルチスレッドプログラムの実行によって生じた

最大で 6 バイト程度となっている．

イベント系列は，実行トレースを書き出す処理内のイベント数は膨大となる可能性があるので，実行ト

synchronized ブロックにより逐次化される．そのレースは 1000 万イベントごとに 1 ファイルの単位でため，実行トレースを書き出す処理がスレッドスケ

分割されて出力する．プログラムの実行時のオーバー

ジューリングに影響を与える可能性はあるが，結果とヘッドを下げるため，対象プログラムのスレッドに加して得られたマルチスレッドの動作順序はそのまま実えて実行トレースを書き出すためのスレッドを追加で

行トレースとして出力される．

起動することを可能としている．バッファを複数用意

実行トレースのファイル形式は，1 イベントあたり

し，1 つのバッファにイベント系列が蓄積されている

30 バイトのデータを固定長で並べ，それを gzip アル間に，満杯になったバッファを圧縮，出力する処理をゴリズムにより圧縮したものである．データの内容

実行する実装となっている．

は，イベントの種類（2 バイト），スレッド ID（4 バイト），命令 ID（4 バイト），イベントごとの情報

2. 1. 2 実行トレース観測命令の埋め込み
REMViewer は，ASM †1 を使用して対象プログラ（20 バイト）である．イベントごとの情報は，最もムに観測用命令を埋め込む．たとえばメソッドのすべ

データ量の多い配列の書き込み命令に合わせており，ての実行開始と終了を記録するために，以下のようなオブジェクト ID（8 バイト），配列の添え字の整数（4 バイト），配列の値（最大で long 型の 8 バイト）

†1 ASM. http://asm.ow2.org/

ソースコードに対応する命令を作成する．

することが可能である．

try {Logging.recordMethodEntry(0);2. 2 再現// 元々のメソッド本体の内容

Replay コンポーネントは，プログラムの実行が終Logging.recordMethodExit(1);} catch (Throwable t) {わった後，前準備として一度実行トレースを探索し，すべてのメソッド開始イベントの位置を特定しておLogging.recordExceptionalExit(2, t);

く．そして，ユーザから指定されたメソッドの開始位

throw t;

置から，実行トレースに記録された値を利用しながら}バイトコード命令を解釈し，指定されたメソッドの実

ここで，Logging というクラスが実行トレースの観行を再現する．

測用クラス，各メソッドの引数に登場する定数が命令メソッドの実行の再現方法を詳しく説明すると，まID である．Replay コンポーネント等は命令 ID からず実行トレースのメソッド開始イベントの位置から引対象のバイトコード位置を特定する．

数の情報を読み出し，ローカル変数の初期状態を構

バイトコードの中に命令を埋め込む都合上，記録にはいくつかの制限がある．

築する．そして，次のイベントを 1 つ読み出し，そのイベントに紐付けられた命令 ID までのバイトコー• メソッドに含まれる命令数が非常に多い場合，追ド命令を順に解釈し，スタックやローカル変数の状態

加の命令を埋め込んだ結果，メソッドの大きさを更新する．配列やフィールドへのアクセスの結果なが Java 仮想マシンの制限（64KB）を超えてしど，メソッド外部の情報については読み出したイベン

まうことがある．たとえば配列を定数の列で初トに保持されている値を利用する．命令 ID までのバ期化しているメソッドは，配列の各要素への代

イトコード命令の実行が終わると，実行トレース中の入の並びとしてコンパイルされているため，各次のイベントを読み出し，同様にバイトコード命令を代入に対応した観測命令を追加することになり，解釈していく．この操作をメソッドの終了イベントをこのサイズ制限に抵触することがある．この制限

読み出すまで繰り返すことで，メソッドの実行を再現に抵触した場合，REMViewer はまず配列へのする．

代入命令のみを観測対象から除外し，それでも制Java ではローカル変数を未初期化の状態で使うこ限に抵触する場合はメソッドの開始と終了のみをとはできないため，すべての変数はイベント情報に格観測する最小限の命令を埋め込む．

納された引数の値か，バイトコード命令が参照する• Java の ク ラ ス は 初 め て 使 用 さ れ る 際 に定数値から値を決定することができる．また，メソッ

ClassNotFoundException が発生し，クラスのドの戻り値などの情報はイベントとして記録されて読み込みと初期化が実行されるが，実行トレースいるため，メソッドの呼び出し先など，再生対象ではの記録を行うために使われる java.io パッケー

ないメソッドの中での動作の再生は，すべて省略する

ジのクラスについては，この初期化の発生を記録ことができる．マルチスレッドで並行して何らかの処することができない．

理が実行されていたとしても，それによって更新され• バイトコードの改変を禁止する署名付きプログる可能性がある値は配列，フィールドに限られるたラムに対しては観測を行うことができない．

め，実行トレースで実際に参照した値を使用すれば，

なお，観測範囲は，バイトコード変換をかける対象

スレッド間の影響があっても実行を正しく再現するこのファイルを選定することで指定可能である．各メ
ソッドについて，メソッドの外部から受け取る引数やとができる．
ユーザーが指定したメソッドが N 回実行されていフィールド，例外等の情報はすべて記録されるため，た場合には，N 回の実行すべてを再現する．再現さ観測範囲内のメソッドについて自由にその状態を再現れたメソッドの実行を E = {e1 , · · · , eN } とおく．1

れている．ソースコードの表示領域は，デバッガと同様，実行の位置を指すカーソルを持っている．ユー
ザーはこのカーソルを実行経路に沿って前後に操作することができ，現在の実行位置における変数の状
態がビュー中央の領域に表示される．これに加えて，
ユーザーはソースコード中の任意の行をクリックし選択することで，その行における変数の状態を確認する
ことが可能である．選択した行における変数の状態はビューの下部に表示される．このとき，たとえばルー
プ内の行を選択した場合，複数回その行が実行される可能性があるため，選択した行における変数の状態は表形式での表示となっている．図 1 の例では，２つの列がそれぞれ while 文の 1 度目の実行と 2 度目の実行を示している．列名の 4-4, 4-8 という表示は，
対象メソッドの 4 回目の実行における 4 ステップ目，

8 ステップ目の変数の状態であることを示している．
実行経路を可視化するため，ソースコードの背景に
図1

対象メソッドの 1 回の実行を表すビュー

は緑色の矩形を表示している．図 2 は実行経路の例を示しており，実行 e における各状態 ⟨bk , lk , vk ⟩ が座
標 (xk , lk ) の矩形として描かれている．水平方向の値

xはプログラムの実行がソースコードの上方向に向かう

152

ときにインクリメントされる．すなわち，lk−1 > lk

3
4

であれば xk = xk−1 + 1，そうでなければ xk = xk−1となる.
6

メソッド実行の比較を支援するため REMViewer
図2line
矩形により示される実行経路

では複数のビューを同時に表示する．ここで，すべてのメソッド実行を単純に並べて表示すると表示領域が回のメソッドの実行 ei は状態 ⟨bk , lk , vk ⟩ の列であり，不足するため，異なる実行経路をたどる実行を優先的

bk は k 番目のバイトコード命令, lk はバイトコードに表示する．そのために，REMViewer は実行 E を命令に対応するソースコード中の行番号, vk は bk をグループに分類し，グループから 1 つずつメソッド実行した後の局所変数の状態をそれぞれ表している．

実行を表示する．REMViewer は path-based と line-

based という 2 つの分類基準を採用しており，それぞ2. 3 可視化

れ，実行の集合 E を同値類に分類する．path-based

REMViewer は 1 回のメソッド実行に対し，図 1 のの分類では，集合 E を実行したバイトコード命令番

ようなビューを表示する．なお，図 1 に表示されてい号の列が等しい同値類 P (E) = {P1 , · · · , PNp } に分

る gcd という名前のメソッドは，引数の 2 つの正整類する (Np は同値類の個数)．P ath(e) を実行 e 中の数の最大公約数を求めるメソッドであり，ユークリッ

バイトコード命令番号の列 (b1 , b2 , · · ·) とすると，分ドの互除法のアルゴリズムに従って実装されている．

類は以下のような条件で表現できる．

ビューは，上から順にソースコード，変数の状態，
行における変数の状態という 3 つの領域から構成さ∀e1 ∈ Pi , e2 ∈ Pj . i = j ⇔ P ath(e1 ) = P ath(e2 )同様に，line-based の分類では，実行 E をバイト

コ ー ド 命 令 番 号 の 集 合 が 等 し い 同 値 類 L(E) =表2{L1 , · · · , LNl } に分類する (Nl は同値類の個数)．
∀e1 ∈ Li , e2 ∈ Lj . i = j ⇔ Lines(e1 ) = Lines(e2 )ここで Lines(e) は実行 e 中で実行されたバイトコー
ド命令番号の集合である．

REMViewer は分類された各グループから代表を 1つずつ選びだし表示を行う．図 3 が Viewer のスク
リーンショットである．図 1 のメソッドを対象に 3 つの実行経路を含むビューを表示している. 左のビュー

実行トレースBenchmark

batik

fop

通常の実行時間

4.44 sec

2.80 sec

トレース記録の実行時間

33.67 sec

36.91 sec

履歴サイズ

717MB

860MB

メソッド数

3,131

3,611

17,319,055

26,551,919

メソッド実行数

は if 文と while 文が共に false となる実行経路，中央のビューは if 文内の return 文を通る実行経路，右の
1000

ビューは while 文内のブロックを 1 度だけ実行する実行経路をそれぞれ示している．これら 3 つのビュー

500

でメソッドの基本的な動作を特定し，ユーザーは実行とそうでない実行を区別することも可能である．同一グループに分類された実行経路であっても，たとえばwhile 文内のブロックが実行された回数などは異なる

200
100

に含まれる実行の個数が表示されるので，珍しい実行50とができる．各ビューの上部にはそれぞれのグループ

Time (sec)

経路や変数の状態を 1 つのウィンドウで比較するこ可能性があるので，ユーザは各ビューに表示する実行
パスを切り替えたり，グループ化を解除することで，
batik

詳細な動作の比較を行うことも可能としている．
図4fop

1 メソッドの再現に要する時間の分布

3 ツールの性能
実行時間と可視化の適応可能性という 2 つの観点でレースとして保存されたファイルの合計サイズであツールの評価を行った．実験対象としては，Java アり，「メソッド数」はアプリケーション内部で少なくとプリケーションのベンチマーク集合である DaCapo

も 1 回は実行されたメソッドの数，「メソッド実行数」

benchmark [4] に収録された 2 つのアプリケーション，

はメソッドの総実行回数をそれぞれ示している．

batik と fop を使用した．DaCapo benchmark のアプ対象となるプログラムの実行に関して詳細な実行

リケーションは実行のサイズを指定できるが，ここでトレースを記録しているため，プログラムの実行時間

は，default を指定しアプリケーションの実行を記録しは大きく増加しているが，開発者がいくつかの機能をた．実行環境としては，CPU が Intel Xeon 2.90Hz,

試験的に実行する程度であれば，開発者の作業を大メモリが 256GB であるマシン上で行っている．

幅に中断させるほどのコストではない．また，一度トレースを記録すれば，その実行に関してはすべてのメ

3. 1 実行時間

ソッドを調査することができるため，あらかじめテス

表 2 に実行トレースに関する情報を示す．最初の 2

ト自動化のようなツールを活用して事前にトレース

行は，実行トレースを記録しない通常の各アプリケーを収集しておくことも可能である．

ションの実行時間と，実行トレースの記録を行った場

図 4 はメソッドの再現にかかる時間の分布を箱ひ合の実行時間を示している．
「履歴サイズ」は実行トげ図で示したものである．batik では平均で 44.7 秒，

図3

表3

対象メソッドの 3 つの実行経路を表示している REMViewer のスクリーンショット

分類対象としたメソッドの情報
1.0

batik

fop

メソッド数

1029

1160

メソッド内の分岐数の平均

5.05

4.11

メソッドの実行回数の平均

8512

8939

fop では平均で 50.6 秒の時間がかかっている．開発者は一般に複数のメソッドを調査することが想定さ

0.9
Methods with Branches

Benchmark

0.8

0.7

0.6

Path (batik)Line (batik)
Path (fop)Line (fop)れるが，1 つのメソッドについて調査している間に他のメソッドの再生の計算を行うといった工夫により，利用者の待ち時間の合計は削減することが可能であ

0.5
0

5

ると考えている．

3. 2 分類

10

15

20

The Number of Path Groups

図5

分類数の累積相対度数グラフ

頻繁に実行されるメソッドであっても可視化が適用可能であるかを調査するため，各メソッドの実行経路

図 5 はそれぞれの分類基準における分類数に関するの分類によって得られるグループ数を調査した．条件

累積度数グラフである．グラフから path-based の分分岐が含まれないメソッドは path-based, line-based類では 60%のメソッドが 1 つのグループに分類されのいずれであっても常に 1 つのグループに分類されることが分かる．言い換えれば，これら 60%のメソッるので，条件分岐を少なくとも 1 つ含むメソッドを

ドは 1 つの実行経路しか実行されていない．90%の計測対象とする．batik では 1029，fop では 1160 個

メソッドが line-based では高々3 個，path-based でのメソッドに対して分類を行った．対象としたメソッは高々5 個のグループに分類されている．この結果かドに関する情報を表 3 に示す．

ら，多くのメソッド実行は少数のグループに分類されることが分かる．
一方で，分類数が多くなるメソッドも存在した．

と失敗の区別は行わず，実行経路による分類のみを行っている．

org.apache.fop.layoutmgr.BreakingAlgorithm ク

Abramson らはバージョンの異なる 2 つのプログ

ラスの considerLegalBreak メソッドは，全メソッ

ラムの実行を比較する Relative Debugging を提案し

ド中 line-based による分類数が最大の 30 であった．

た [1]．我々のツールは単一バージョンのプログラム

このメソッドには 28 個の分岐が含まれており，このでの複数回の実行を 1 つのウィンドウで比較するもような複雑なメソッドに対しても分析を可能にするのである．

ためには分類方法を改善する必要がある．たとえば，

Bell らは実行トレースを記録する際のオーバーヘッ

実行を通常の実行と例外的な実行に分類することで，ドを少なくする Chronicler という技術を提案した [3]．

開発者はまず通常の実行におけるメソッドの振る舞い

我々のツールにもこの技術を応用することで性能を向を調査するといったことが可能になると考えられる．

上できる可能性がある．

Alsallakh らは，プログラムのある 1 つの変数に着4 関連研究目し，その値の変化を可視化する手法を提案していプログラムの実行を過去にさかのぼって調査する [2]．我々のツールは選択された行における変数のることはデバッグに非常に有用である．Ko らは制値の系列を抽出できるので，この手法のような可視化

御およびデータの依存関係をさかのぼる手法 [7] を，を適用すると，より効果的な分析ができるようになる

Mirghasemi らは変数が代入された位置にさかのぼる可能性がある．また，Sagdeo らはメソッドの特定の手法 [10] をそれぞれ提案している．これらの手法はデ実行経路に対して不変条件を抽出する手法を提案しバッグを主眼としており，開発者が調査したい特定のており [13]，各実行において取りうる変数の状態の要時刻を選択できることを前提としている．我々のツー約を作る，異常値を発見するといったツールの拡張に

ルは，開発者がソースコードを読解する際，まず対象応用できると考えられる．

のソースコードを選定してから興味のある実行経路，
そして時刻の順で選択できるようにしている．

5 まとめと今後の課題

Joshi らは指定されたメソッドの実行の再現を行う

我々はメソッドの実行経路および変数の状態を可視Selective Capture and Replay 技術を提案し，開発者化するツール REMViewer を提案した．REMViewerの作業における有効性を確認している [6]．Omniscientを使うことで，開発者は実行経路を比較しながらメ

Debugging [8] のような完全なプログラムの状態の再

ソッドの振る舞いを調査することが可能となる．本

現は，対象プログラムのメモリ状態を再現するためにツールを使うことで，メソッドのテストケースの効率

必要なメモリ使用量と実行トレースの解析時間の両的な理解や，デバッグにおいて異常な実行経路を発見

面で現実的とは言い難いが，Selective Capture and

するのに利用できると我々は考えている．また，実行

Replay は再現対象のメソッドを限定することで実用の記録，再現がそのものが動的スライスの計算等の，性を達成している．我々のツールもまたメソッド単位

他の動的解析技術の基盤としても利用可能である．

の実行を再現することで，実用的なサイズのプログラ

今後の課題としては，開発者の実際の活動におけるムであっても状態の分析を可能とし，さらに複数回の有用性の評価が挙げられる．本ツールの現在の実装で実行から特定の振る舞いを選択して分析するためのは，メソッド内部で参照されたデータのみを用いて状

ユーザーインターフェースを提供した．

態の再現を行うため，再生したメソッドの中で一度もJones らは複数のテストケースの実行を比較し，参照されなかったオブジェクトのフィールドについて成功した実行と失敗した実行とを比較するツール

は，再現の範囲に含まれない．開発者が作業中にどの

Tarantula を提案した [5]．我々のツールはデバッグでような情報を必要とするのか，ツールの操作履歴を記

はなく，プログラム理解を目的としているため，成功録するなどして，ツールの機能を改善していく必要がある．
実行経路の分類の改善も今後の課題として挙げられる．実行が複雑なメソッドほど，実際の動作を分析できることに価値があると考えられるが，そのようなメソッドほど通過した命令行などによる分類では結果が細分化されやすい．メソッドの通常の振る舞いと例
外的な振る舞いをより簡単に区別できるようにする必要がある．
謝辞 本研究は科研費 No.26280021 の助成を得た．

参 考 文 献[ 1 ] David Abramson, Clement Chu, Donny Kurniawan, and Aaron Searle. Relative debugging in
an integrated development environment. Software
Practice and Experience, Vol. 39, No. 14, pp. 1157–
1183, 2009.
[ 2 ] Bilal Alsallakh, Peter Bodesinsky, Alexander
Gruber, and Silvia Miksch. Visual tracing for the
eclipse java debugger. In Proceedings of the European Conference on Software Maintenance andReengineering, pp. 545–548, 2012.
[ 3 ] Jonathan Bell, Nikhil Sarda, and Gail Kaiser.
Chronicler: Lightweight recording to reproduce field
failures. In Proceedings of International Conference
on Software Engineering, pp. 362–371, 2013.
[ 4 ] S. M. Blackburn, R. Garner, C. Hoﬀman,
A. M. Khan, K. S. McKinley, R. Bentzur, A. Diwan, D. Feinberg, D. Frampton, S. Z. Guyer,
M. Hirzel, A. Hosking, M. Jump, H. Lee, J. E. B.
Moss, A. Phansalkar, D. Stefanović, T. VanDrunen,
D. von Dincklage, and B. Wiedermann. The DaCapo benchmarks: Java benchmarking development and analysis. In Proceedings of International
Conference on Object-Oriented Programming Systems, Languages, and Applications, pp. 169–190,
2006.
[ 5 ] James A. Jones, Mary Jean Harrold, and John
Stasko. Visualization of test information to assist
fault localization. In Proceedings of International
Conference on Software Engineering, pp. 467–477,

2002.
[ 6 ] Shrinivas Joshi and Alessandro Orso. SCARPE:
A technique and tool for selective capture and replay of program executions. In Proceedings of International Conference on Software Maintenance, pp.
234–243, 2007.
[ 7 ] A.J. Ko and B.A. Myers. Debugging reinvented:
Asking and answering why and why not questions
about program behavior. In Proceedings of International Conference on Software Engineering, pp.
301–310, 2008.
[ 8 ] Bil Lewis. Debugging backwards in time. In Proceedigns of International Workshop on AutomatedDebugging, 2003.
[ 9 ] Toshinori Matsumura, Takashi Ishio, Yu Kashima,
and Katsuro Inoue. Repeatedly-executed-method
viewer for eﬃcient visualization of execution paths
and states in java. In Proceedings of International
Conference on Program Comprehension, pp. 253–
257, 2014.
[10] Salman Mirghasemi, John J. Barton, and Claude
Petitpierre. Querypoint: Moving backwards onwrong values in the buggy execution. In Proceedings of the joint meeting of the European Software
Engineering Conference and the Symposium on theFoundations of Software Engineering, pp. 436–439,
2011.
[11] Jorge Ressia, Alexandre Bergel, and Oscar Nierstrasz. Object-centric debugging. In Proceedings ofInternational Conference on Software Engineering,pp. 485–495, 2012.
[12] Tobias Roehm, Rebecca Tiarks, Rainer Koschke,and Walid Maalej. How do professional developers comprehend software? In Proceedings of International Conference on Software Engineering, pp.
255–265, 2012.
[13] Parth Sagdeo, Viraj Athavale, Sumant Kowshik,and Shobha Vasudevan. Precis: Inferring invariants using program path guided clustering. In Proceedings of International Conference on AutomatedSoftware Engineering, pp. 532–535, 2011.
[14] Jonathan Sillito, Gail C. Murphy, and Kris De
Volder. Asking and answering questions during a
programming change task. IEEE Transactions on
Software Engineering, Vol. 34, No. 4, pp. 434–451,
2008.