ソフトウェアの実行を分析するための低侵襲なモニタリングツールの試作
嶋利 一真1,a)

石尾 隆2,b)

井上 克郎1,c)

概要：本研究では，ソフトウェアの内部状態を迅速に分析する方法として，開発者が指定した内部情報に限定して情報収集を行う低侵襲デバッグを提案する．ソフトウェアの実行について調べたい情報が決まっているとき，デバッガが開発者に指示された情報だけをソフトウェアの実行を短時間の停止だけで読み出すことで，ソフトウェアの実行への影響を最小化すると同時に，開発者への迅速な応答を実現する．

1. はじめに本研究では，ソフトウェアの内部状態を迅速に分析する方法として，開発者が必要であると指定した内部情報に限

情報システムは現代社会の様々な活動を支える重要な基定して情報収集を行う低侵襲デバッグを提案する．ここで盤であるが，情報システムのあらゆる実行状況を事前にテ

低侵襲とは，元のプログラムの実行に与える影響が小さいストし欠陥を取り除くということは現実には難しい．例えことを意味しており，特にプログラムの実行を中断しない

ば，2007 年に首都圏で発生した自動改札機の動作障害は，1

こと，実行速度に影響を与えないことを重視している．低年間のテストと半年間の運用を経た後に初めてソフトウェ侵襲性を実現する方法として，ブレークポイントによる実アの欠陥が顕在化したものである [1]．

行中断を許さず，そのかわりに開発者が指定した任意の時ソフトウェアに障害が発生したとき，そのソフトウェア点において情報の収集，出力のみを行う形式を採用する．の内部状態を調査するための重要な道具がデバッガである．

ソフトウェアの実行を一時停止してから変数の一覧を閲覧

現在主流のデバッガはブレークポイント・デバッガと呼ばするのではなく，収集した値を開発者が閲覧している最中れており，開発者がソフトウェアの実行を一時停止し，ソにも実行を継続することで，実行性能への影響を軽減する．

フトウェアの内部状態を自由に分析することを可能として

本研究では，低侵襲デバッグの実現可能性を評価するたいる．しかし，開発者による実行状況への干渉は，例えばめに，Java に対する低侵襲なモニタリングツールを試作しソフトウェア内部の並行処理の実行順序が入れ替わる，一た．そして，ローカル変数とフィールドの観測処理を行っ定時間内に完了するべき処理の実行が間に合わなくなるなた場合の Java 仮想マシンの実行性能への影響と，変数の値どの実行の変化を引き起こす可能性がある．また，サーバを観測するために生じる実行オーバーヘッドを調査した．

上で運用されているソフトウェアなどで，既にそれを利用

以降，2 章では本研究の背景と関連研究について説明し，している一般ユーザがいる場合，開発者による分析活動が3 章では本研究の提案手法を説明する．4 章では評価の結ユーザにまで影響を与えてしまう．ソフトウェアを停止さ果を説明し，最後に，5 章で本研究のまとめと今後の課題せるかわりに，ソフトウェアの実行履歴を詳細に記録してを述べる．

実行状況を再現するといった方法も存在しているが，企業の開発者らは「実行に時間がかかるのであれば使いたくない」という立場を取っている [2]．
1

2a)
b)
c)

大阪大学大学院情報科学研究科
Graduate School of Information Science and Technology, Osaka University.
奈良先端科学技術大学院大学情報科学研究科
Graduate School of Information Science, Nara Institute of
Science and Technology.
k-simari@ist.osaka-u.ac.jp
ishio@is.naist.jp
inoue@ist.osaka-u.ac.jp

2. 背景
デバッグとは，外部から観察できるソフトウェア障害の症状から，その原因となるソースコード内の欠陥を突き止める作業である [3]．その分析作業では，障害につながる命令の実行順序や変数の値を観測，調査することが重要である [4]．
開発者がソフトウェアの実行の様子を観測する手段として，ソフトウェアの処理の進行状況を示すメッセージや重要なデータをプログラムの外部に出力するロギング処理が殊な動作が確認されたとき，バッファにはその特殊な動作広く用いられている．実装の方式はプログラムによって異の際に観測された値が残る可能性が高い．命令はそれぞれなるが，いわゆる print 文や，様々なロギングライブラリ実行される頻度が異なるため，バッファは観測命令ごとにが活用されている [5]．しかし，ロギングによって記録され用意する．

るのは開発時点で選定されたデータのみであり，デバッグ開発者はソケット通信を介して低侵襲モニタリングツーの時点で任意の変数の値が閲覧できるわけではない．事前

ルにアクセスし，データ観測命令の編集や，収集した情報に多くの変数の値を記録するようにロギングを設計するこの読み取りを行う．開発者が実行できる操作は，以下の 3とも可能であるが，記録するデータ量が増加すると記憶媒つである．

体の管理などの運用面まで気を配る必要がある．
デバッグのために一時的なロギング命令が追加される場
合もあるが，運用環境で発生した障害の分析などでは，開• 観測命令 < p, v > の追加．
• 観測命令 < p, v > の削除．
• 観測命令 < p, v > に対応するバッファの中身の出力．

発者がシステムの状態を勝手に変更できない場合もある．

観測命令の位置 p にはソースファイル名と行番号を用いAspectJ [6] のように対象プログラムに観測したい処理をる．Java では実装上はバイトコード単位も利用可能であ

実行時に追加することが可能な処理系も存在するが，例えるが，記述の容易性の観点から行番号を採用した．観測すば Java においては 1 メソッドあたりの大きさに制限がある変数 v としては，その位置 p で利用可能なローカル変数るなど，任意のプログラムに対してプログラム変換が可能

および this 参照と，呼び出し元のメソッドで定義されてなわけではない．

いる変数，それらの変数を基点としたフィールド参照の式

デバッガは，ソフトウェアそのものに手を加えず，外部から任意の時点での変数の観測を可能にするツールであを指定可能とした．また，変数を指定せず，単に通過時刻のみを記録することも可能である．

る．現在主流のデバッガはブレークポイント・デバッガとモニタリングツールの機能を，Java 仮想マシンに追加呼ばれており，対象となるソフトウェアの実行の制御とメするエージェントライブラリとして実装した．観測命令

モリの状態の観測を可能としている [7]．ただし，実行の一< p, v > の処理は，内部的には Java 仮想マシンの持つブ時停止は，システムの動作のタイムアウトなど，予期せぬレークポイント機能を使用して実現した．実行スレッド th

影響を引き起こす可能性がある．本研究では，システムのの指定された命令位置 p への到達が Java 仮想マシンから実行への影響を最小限とするため，状態の観測に特化した通知されるので，p に対応して観測するべきデータ v を手法を提案する．

バッファに記録し，元のプログラムの処理に復帰させる．

3. 提案手法

通常のデバッガであればここで Java 仮想マシンに対して実行スレッドの停止を指示するところであるが，本研究で本研究では，ソフトウェアの内部状態を迅速に分析する構築したモニタリングツールはスレッドの停止を行わない．

方法として，開発者が必要であると指定した内部情報に限モニタリングツールは開発者との対話に専用のスレッド定して情報収集を行う低侵襲デバッグを提案する．デバッを使用する．CPU 資源が十分にあれば，対話そのものがグのための観測処理が低侵襲である，つまりデバッグ対象プログラムの実行に影響を与えることはない．また，いわプログラムの実行への影響を抑えるために，開発者からはゆるサーバ・クライアントモデルに相当し，複数の開発者情報収集の指示のみを受け付けるものとし，また，開発者が同じプログラムに接続し，観測命令等を独立に編集するから情報が要求された場合のみ出力を行う．

ことも可能である．開発者の認証の仕組みなどは本研究のスコープ外とした．

3.1 モニタリングツールの試作プログラムの起動直後などは，対話的操作での観測指示低侵襲デバッグの実現可能性を評価するために，Java をが難しいため，モニタリングツールはプログラム起動時に対象とした低侵襲モニタリングツールを試作した．この設定する観測命令のリストを受け付ける．また，プログラ

ツールは，プログラムに対するデータ観測命令の集合を保ム終了時に，内部バッファに蓄積したすべてのデータを持し，その命令に従って情報収集を行う．1 つの観測命令ファイルに出力する．これにより，実行がすぐに終わるよ

はプログラムで観測を行う命令の位置 p と，観測対象デーうなプログラムでもデータの観測は可能である．

タ v の組 < p, v > である．プログラムの実行が命令 p に到達するたびにデータ v の観測を実行し，得られたデータをプログラムの実行スレッド th，観測時刻 t とともに内部のバッファに記録する．バッファは固定長であり，最新 k個（現在の実装では 100 とした）の観測結果のみを保持する．これにより，例えばプログラムのクラッシュなどの特3.2 モニタリングツールの利用例
モニタリングツールの利用例として，ANTLR によって生成された構文解析器のエラーメッセージの分析方法を示す．ANTLR によって生成された解析器は, 認識できない文字列が入力として与えられたとき，Lexer クラス中の以下のソースコードで警告メッセージを通知する（行頭の数

実行オーバーヘッドについては，実験のための小規模なプ字は行番号である）．

ログラムを用いて観測する．

359 public void notifyListeners
360

361

ムを各条件でそれぞれ 10 回実行し平均値を求める．プロ

String text = _input.getText

グラムをそのまま実行した場合の計測結果を ti ，モニタ(Interval.of(_tokenStartCharIndex,リングツールを有効にした場合の計測結果を t′i とすると_input.index()));（1 ≤ i ≤ 10），オーバーヘッド O(%) は以下の通りである．
′i=1 tiO = ( ∑10i=1 ti

362
ANTLRErrorListener listener= getErrorListenerDispatch();364∑10String msg = "token recognition error at:’"+ getErrorDisplay(text) + "’";

363

オーバーヘッドは実行ごとに変動するため，プログラ(LexerNoViableAltException e) {listener.syntaxError− 1) × 100

性能計測の環境は，CPU として Intel(R) Xeon(R) CPU

E5-1603（2.80GHz），メモリ 16GB，ストレージとしてSATA HDD を搭載したワークステーションである．OS と(this, null,_tokenStartLine,

して Windows 10 Pro，Java 仮想マシンには Oracle Java

_tokenStartCharPositionInLine, msg, e);SE の build 1.8. 121-b13 を用いた．

365 }このエラーメッセージはトークンの文字列と行番号を含んでいるが，そのトークンに対応するファイル名は含んでいない．ファイル名自体は構文解析器には渡されておらず，この構文解析処理を呼び出したメソッドが持つ情報を参照する必要がある．
ブレークポイントデバッガであれば，ブレークポイントを 363 行目に設定して変数のビューを確認し，呼び出し元のメソッドを確認することができる．ただし，この方法ではエラーが発生する都度，実行の中断と目視での確認が必要となってしまう．
これに対して，本研究で試作したモニタリングツールでは，たとえば以下のように観測命令を 1 つ作成することになる．

Lexer.java <main>.filename 363
この観測命令は，Lexer.java ファイルの 363 行目において，現在実行中の main メソッドで有効な変数 filenameを参照することを指示する．モニタリングツールは，当該命令位置にスレッドが到達したとき，コールスタックを辿り，main メソッドにおける filename の値を記録する．呼び出し元となっているメソッドの名前や変数名は事前に調査が必要であるが，デバッガの能力を用いた変数の値の収集が可能である．

4.1 DaCapo Benchmarks への適用
Java 仮想マシンが持つデバッグのための機能を有効にしたことによって生じるオーバーヘッドを確認するために，モニタリングツールを観測命令なしの状態で使用したときの実行性能への影響を，DaCapo Benchmarks[8] のバージョン 9.12-bach を用いて計測した．DaCapo Benchmarks に収録された 14 個のベンチマークのうち，ツールに対して動作が確認できた 12 個のベンチマークを用いた．
使用したベンチマークごとのオーバーヘッドの分布を箱ひげ図として図 1 に示す．通常実行を基準としたオーバーヘッドは平均 7.9%，最大 21%であった．この値は，例えば企業の業務アプリケーションなど，リアルタイム性の低い環境では影響は小さいと考えらえる．
実験で相対的に大きなオーバーヘッドを示したベンチ
マークについて，その原因を分析したところ，JVM TI の利用する機能を指定する AddCapabilities 関数の実行の有無によって実行速度に大きな差が出ることが判明した．
具体的には，ブレークポイントを設置するための権限を付与した場合に，大きなオーバーヘッドがかかっている．これは，ブレークポイントを設置しない場合にのみ実行できるような最適化がこれらのベンチマークに大きく寄与していた可能性がある．

4. 評価
作成したモニタリングツールがプログラムの実行に与える影響の評価を行う．デバッグ機能を有効にすると，Java仮想マシンがデバッグのために何らかの最適化などを抑制する可能性がある．そのため，ベンチマークを用いて，モ

4.2 観測および出力のオーバーヘッド観測命令の実行に対して，どの程度のオーバーヘッドが生じるかを計測した．計測に使用したコードの基本形は以下のようなものである．



ニタリングツールを組み込んだことによって生じるオー1

var1=0;バーヘッドを評価する．また，デバッグ機能によって実際

2

for(int i=0; i<N; i++){に変数の値を観測し，出力を行った場合，観測や出力の実3行回数に比例して実行時間が増加すると考えられる．この4 }

var1++;

ツールではこれらの情報が同じ場合，一度だけの出力で済25%

むようにログの出力が制御されているため，実行時間が短20%くなっている．

15%

られるため，適切なログのみを出力するように指示を行え䜸䞊䝞䞊䝦䝑䝗[%]また，本ツールは出力や値の取得をコマンドで切り替えば，オーバーヘッドはほぼ無視できるものと考えられる．
10%

5. まとめと今後の課題
5%

本研究では，既存のデバッガで十分にできない低侵襲デバッグを実現するために，JVM TI を用いて低侵襲モニタ0%リングツールの試作を行った．
今後の課題としては，ロギングを用いた有効なデバッグ

-5%

図 1

DaCapo Benchmarks に対する実行のオーバーヘッドのために必要なデータの量を調査し，本モニタリングツールのバッファへの記録の仕方やそのデータ量を変更したり，必要なオプションを追加することが挙げられる．なお，モ

表 1 ログ出力命令の実行回数と実行時間 [ms]
出力回数10000

20000

30000

40000

50000

ニタリングツールが情報を自由に収集できる点はセキュリ

通常実行

787.3

1616.12432.53246.84063.8

ティ面での懸念を伴うため，何らかのアクセス制御などの局所変数

579.0

1142.91889.32656.73387.1対策を施したうえでツールの公開を目指す予定である．

クラス

362.8

711.1

1232.01772.22307.2

フィールド
インスタンス1135.62251.93546.24859.86167.3

謝辞

本研究は JSPS 科研費 JP25220003, JP26280021の助成を受けたものです．

フィールド

参考文献
通常実行として，変数 var1 の値とスレッド，現在時刻を[1]出力するような println 呼び出しを埋め込んだものを用いた．また，モニタリングツールを使用した場合については，[2]

3 行目における var1 を観測対象として選んだ．観測対象となる変数が局所変数，クラスフィールド，インスタンス
フィールドのいずれかによって本ツールが内部的に利用する Java 仮想マシンの API が異なり，実行時間も変わってしまうため，それぞれの種別に対してループ文の実行にかかる時間の測定を行った．ループの実行回数 N は最大

[3]
[4]

50000 とし，通常実行時と出力回数を合わせるために，モニタリングツールも最新 50000 件までのデータを保存する[5]設定とした．そして，実行終了時に一括でそれらのデータの出力を行った．
ログ出力命令の実行回数と実行時間を表 1 に示す．実行時間と実行回数は通常実行時，モニタリングツール使用時共に，ほぼ線形に増加する．出力もモニタリングツールによる値の取得も行わずに実行時間を計測した結果は，5 万回実行しても両者共に高々 2ms であった．つまり，ログ出力命令の実行時間は通常実行では出力に，モニタリングツールでは値の取得と出力に大きく依存している．
局所変数とクラスフィールドにおいて，値の取得と出力に大きなコストがかかっているにもかかわらず通常実行時よりも実行時間が短くなった原因としては，ログの出力量が減少したことが原因であると考えられる．具体的には，通常実行時は毎回ファイル名，メソッド名，行番号，変数名，型名について出力する必要があるが，本モニタリング

[6]
[7]
[8]

ITMedia ニュース：「260 万人の朝の足を直撃 プログラ
ムに潜んだ 魔物 」
，http://www.itmedia.co.jp/news/articles/0710/12/news117.html (2007).
Siegmund, B., Perscheid, M., Taeumel, M. and Hirschfeld,
R.: Studying the Advancement in Debugging Practice ofProfessional Software Developers, Proceedings of International Workshop on Program Debugging, pp. 269–274(2014).
Zeller, A.: Why programs fail, the 2nd edition, O Reilly
Japan，second edition (2012).
Spinellis, D.: Eﬀective Debugging: 66 Specific Ways toDebug Software and Systems, Addison-Wesley Professional (2016).
Kabinna, S., Bezemer, C.-P., Shang, W. and Hassan,
A. E.: Logging Library Migrations: A Case Study for theApache Software Foundation Projects, Proceedings of International Conference on Mining Software Repositories(2016).
千葉 滋：アスペクト指向入門，技術評論社 (2005).
Jonathan B. Rosenberg 著 吉川 邦夫訳：How Debuggers
Work デバッガの理論と実装，アスキー (2007).
Blackburn, S. M., Garner, R., Hoﬀman, C., Khan, A. M.,
McKinley, K. S., Bentzur, R., Diwan, A., Feinberg,D., Frampton, D., Guyer, S. Z., Hirzel, M., Hosking,A., Jump, M., Lee, H., Moss, J. E. B., Phansalkar,A., Stefanović, D., VanDrunen, T., von Dincklage, D.
and Wiedermann, B.: The DaCapo Benchmarks: JavaBenchmarking Development and Analysis, Proceedingsof ACM SIGPLAN conference on Object-Oriented Programing, Systems, Languages, and Applications, pp.
169–190 (2006).