...

ReBucket を用いた Linux カーネルバグの分類

by user

on
Category: Documents
14

views

Report

Comments

Transcript

ReBucket を用いた Linux カーネルバグの分類
Vol.2014-OS-130 No.11
2014/7/28
情報処理学会研究報告
IPSJ SIG Technical Report
ReBucket を用いた Linux カーネルバグの分類
佐久間 亮1,a)
菊池 伸郎1
吉村 剛1
河野 健二1
概要:オペレーティングシステムカーネルには多くのバグが存在している.Windows や Linux にも多く
のバグが存在しており,Microsoft では Windows Error Reporting (WER) と呼ばれるシステムを用いて
クライアントからバグによって障害が起きた際の情報を集めている.集めたクラッシュログを WER シス
テムを用いてバグごとに分類し,多くのユーザで発現するバグからデバッグを行っている.バグの分類に
はコールスタックに注目して類似度を計算する事によって分類を行う ReBucket が知られている.しかし,
Linux では ReBucket のようなバグの分類を行っていない.Linux で ReBucket が適用できれば,開発者
がクラッシュレポートを分類する負担を軽減することができる.しかし,Linux ではフレームポインタの
最適化によりコールスタックが正確ではない場合があり,バイナリが多様なため同じバグでも異なる情報
を出力することがある.本研究は ReBucket を Linux に適用した場合の効果について,定量的に評価を
行った. 調査はフォールトインジェクタを用いて挿入したバグによってクラッシュした際のクラッシュロ
グ,850 種類,全 10294 件を用いて ReBucket を行う.調査の結果,全体の 69% のバグはバグごとに同
じグループに分類されていた.また,全体の 46% のグループには一種類のみのバグが分類されていた.
1. はじめに
ポートが送付されることとなる.たとえば,RedHat 社の
リポジトリでは,ひと月に約 1 万件 のクラッシュレポー
近年オペレーティングシステムのカーネルは多機能,複
トを受信している [6].このように多数のクラッシュレポー
雑化しており,ソースコードの量も膨大になっている. た
トが送付されてくるため,送付されたクラッシュレポート
とえば,Linux カーネルのバージョン 3.15.2 のコード量
をひとつひとつ人手で解釈・分類していくことは現実的で
を SLOCCount (2.26) で調べたところ,約 1200 万行にも
はない.そのため,クラッシュレポートを何らかの基準で
なっている [1].さらに,市場競争力のために開発期間も
分類・整理し,対応するべきクラッシュレポートに優先順
短縮される傾向にあり,出荷前にソフトウェアの品質検査
位をつけて対処できるようにしていく必要がある.特に,
を完璧に行うことは難しくなっている.Palix らの調査で
同一の原因(root cause)によって発生したクラッシュレ
も Linux カーネルに多くのバグがあることが示されてい
ポートをひとつにまとめ,クラッシュの発生頻度の高いバ
る [2].
グから優先的に対処できるようにすることが重要である.
そのため,開発者はソフトウェアのリリース後にも,
対応するクラッシュレポートの優先度付けを行うため,ク
ユーザからソフトウェアの不具合についての情報を集め
ラッシュレポートを自動的に分類する手法には Bucketing
る必要がある.実際,ソフトウェアの不具合(バグ)を収
[3] や ReBucket [7] といった手法が知られている.これら
集するためにさまざまなクラッシュログやバグレポート
の手法を用いることで,クラッシュレポートを root cause
のリポジトリが運用されている.たとえば,Microsoft 社
ごとに分類することができるため,クラッシュ頻度の高い
の Windows Error Report (WER)[3], Mozilla の Mozilla
バグからデバッグを行うことが可能になっている.
crash report[4], Apple の Apple crash report[5] などが
本稿は, Linux に ReBucket を適用してクラッシュレ
知られている.こうしたバグ・リポジトリを用いる事によ
ポートの分類をした場合の精度について調査を行う.調査
り,ユーザの遭遇したクラッシュなどの情報を自動的に収
で用いるクラッシュログの収集にはソフトウェアフォー
集し,効率的にデバッグ等のメンテナンス作業を行うよう
ルトインジェクタの SAFE [8] によってソースコードレベ
になっている.
ルでバグを挿入した Linux カーネルを用いた.SAFE で
このようなバグ・リポジトリには多量のクラッシュレ
生成した約 7700 種類のバグをひとつずつ挿入したカーネ
ル上で,ワークロードを走らせてクラッシュした際のク
1
a)
慶應義塾大学
[email protected]
c 2014 Information Processing Society of Japan
ラッシュログを基に ReBucket を適用する.本調査では全
1
Vol.2014-OS-130 No.11
2014/7/28
情報処理学会研究報告
IPSJ SIG Technical Report
10294 件のクラッシュログに ReBucket を適用した.
Linux には多くのバージョンやディストリビューション
がある上,カーネルコンパイル時のコンフィグレーション
も多岐にわたっており,同一のバグによるクラッシュが
あってもコールトレースに違いが出てくる可能性が高い.
また,Linux ではフレームポインタがスタックに積まれてい
ないことを前提にコールトレースが生成されるため,コー
ルトレースが不正確なものとなっている.このような原因
から Windows では有効に機能する ReBucket が Linux で
も有効に機能するかどうかは必ずしも自明ではない.
今回の調査では 2 つの評価基準によって ReBucket の効
図 1
Distance to the Top Frame と Alignment Offset
果を評価した.一つ目は同種のバグがいくつのグループに
分類されたか,というものである.この評価の最善の結果
てバグの分類を行うが,ReBucket はエラーレポートのコー
は同種のバグは全て同じグループに分類されるというもの
ルスタックのみに注目してバグの分類を行う.ReBucket
である.この評価の結果では,850 種類のバグの内 72% が
を用いて既知の Microsoft 製品のエラーレポートを分類し
一つのグループに分類されていた.二つ目の評価方法は,
たところ,Bucketing に比べ約 10 % の精度向上が示され
バグが分類された各グループ内に存在するバグの種類の数
ている.
である.この評価の最善の結果は,各グループには 1 種類
のバグのみが存在するというものとなる.この評価の結果
2.2 ReBucket
では,全体の 50% のグループはグループ内には一種類の
ReBucket はエラーレポート間のコールスタックに注目
みのバグを分類していた.また,最大で一つのグループに
して root cause ごとに分類を行う.類似しているコールス
70 種類のバグを分類しているケースが存在した.これら
タックを持つエラーレポートは同 Bucket へ,類似してい
の結果は Windows に ReBucket を適用した場合に比べて
ないコールスタックを持つエラーレポートは異なる Bucket
精度の低下が見られ,Linux 特有のコールトレースの生成
へ分類する.ReBucket の分類は 2 つの段階に分けること
方法やバイナリの多様さが原因であると考えられる.
ができ 1) エラーレポート間のコールスタックの類似度の
本論文の構成を以下に示す.2 章では WER と ReBucket
計算を行い,2) 類似度を基にクラスタリングを行う.本研
について,また Windows と Linux におけるクラッシュレ
究で用いる ReBucket のアルゴリズムについての簡単な説
ポートの違いを説明する.3 章では Linux における Re-
明を行う.
Bucket の有用性を示す.4 章ではまとめと今後の課題につ
2.2.1 類似度
いて述べる.5 章では本研究の関連研究について述べる.
コールスタックの類似度はふたつのコールスタックの最
大共通部分列と二つのメトリックを基にした重み付けに
2. Windows Error Reporting と ReBucket
よって計算する.ひとつ目のメトリックはコールスタッ
2.1 Windows Error Reporting の概要
どバグに関係のあるものであるというものであり,ふた
Windows では WER によってカーネルやソフトウェア
クのトップ(クラッシュを起こした関数)に近い関数ほ
つ目はコールスタック間で一致する関数の位置が近い程,
がクラッシュした際の情報を Microsoft 社のサーバへ集め
二つのコールスタックは類似しているという考え方であ
ている.WER で集められたエラーレポートは Bucketing
る.このメトリックを基に Distance to the Top Frame と
と呼ばれるアルゴリズムによってクラッシュの原因のバ
Alighnment Offset というパラメータから重み付けを行う.



 Mi−1,j−1 + cost(i,j)
Mi,j = max
(1)
Mi−1,j


 M
グごとにグループ (Bucket) に分類される.Bucketing に
よって分類された グループ (Bucket) には 1 種類のバグ
(root cause)に対応するエラーレポートが分類され,同じ
i,j−1
{
root cause によるエラーレポートは 1 つの Bucket に分類
されることが理想的である.Microsoft ではこの Bucketing
を用いてエラーレポートの分類を行うことで 10 年間で 数
十億件のエラーレポートに対応している.
バグの分類手法として Bucketing とは別に Microsoft の
cost(i,j) =
e−c∗min(i,j) e−o∗abs(i−j)
0
Mm,n
sim(C1 ,C2 ) = ∑l
−cj
j=0 e
if fi of C1 = fj of C2
(2)
otherwise
(3)
Dang らが提案した ReBucket が知られている.Bucketing
図 1 に Distance to the Top Frame と Alignment Offset
は Windows 特有のさまざまなヒューリスティックを用い
の例を示す.Distance to the Top Frame はコールスタッ
c 2014 Information Processing Society of Japan
2
Vol.2014-OS-130 No.11
2014/7/28
情報処理学会研究報告
IPSJ SIG Technical Report
クのトップからの位置を示し,たとえば f1 では Distance
to the Top Frame は 1 となる.Alignment Offset はふた
つのコールスタック間で共通する関数同士の位置の差を表
し,f5 と f70 では Alignment Offset は 2 となる.
具体的な計算方方法を式 (1) - (3) に示す.コールスタッ
ク間の最大共通部分列問題を解く方法として知られる動的
計画法を用いてコールスタック C1 ,C2 の最大共通部分
列を式 (1) のように解く.通常の最大共通部分列問題とは
異なり,式 (2) で表す cost(i,j) によって重み付けを行い
計算する.式 (2) で用いる min(i,j) と abs(i − j) はそれ
ぞれ共通する関数の Distance to the Top Frame の最小値
図 2 oops メッセージのサンプル
と Alignment Offset にあたる.また,c ,o は Distance to
the Top Frame と Alignment Offset に対するパラメータ
で??で説明するようにその製品に対して最適なパラメータ
ジョンとマシンモデルを示している.ディストリビュー
を用いることができる.最終的なコールスタック間の類似
ションによってはカーネルバージョンが正確に出力されな
度 sim(C1 ,C2 ) は式 (3) で求めることができる.
いことがある.
2.2.2 クラスタリング
コールトレース: コールトレースはカーネルがクラッ
計算されたコールスタック間の類似度をもとにクラスタ
シュに至るまでの関数呼び出しの実行履歴を示している.
リングし,クラッシュレポートの分類を行う.ReBucket
8 行目から 18 行目までがコールトレースになっており,
では凝集型階層的クラスタリングを使う.これは,始めに
関数名の “+” 以降はバイナリでのオフセットを表してお
各クラッシュレポートを一つのクラスタとし,一番類似度
り,8 行目の最後にある “[ext3]” はモジュール名を表して
が高いものから階層的に併合していくクラスタリングであ
いる.また,18 行目の RIP はクラッシュが起こった関数
る.ReBucket では各クラスタ間の距離を決める方法は最
なので,この関数がコールスタックのトップにあたる.
長距離法を取っており,各クラスタ同士の最大距離が閾値
2.3.2 コールストレースと “?”
d より大きくなった場合クラスタリングを終了し,その結
oops メッセージのコールトレースには,図 2 の 9 行目
果が分類結果となる.
にある “?
2.2.3 パラメータ
名の前に “ ? ” が付いているものがある.この “ ? ” の
ReBucket では 2.2.1 で説明した二つのパラメータ c,o
とクラスタリングの閾値 d に対して最適な値を用いること
ext3 journal dirty metadata()” のように関数
付いた関数は実際に呼び出された保証の無いものであり,
Linux 特有のコールトレースの生成方法によって出力され
によって分類の精度を高めることができる.パラメータの
るものである.Linux のコールトレース生成の仕組みを,
決定方法は,root cause が分かっているクラッシュレポー
スタックフレームとフレームポインタとともに解説をし,
トのデータセットに各パラメータ c,o,d を変化させて分
どのようにコールスタックをトレースしているのか,ま
類を行い,一番精度の高かった場合のパラメータの組み合
たどのような関数が “ ? ” 付きで出力されるのかを解説
わせを用いるというものである.
する.
スタックフレーム: コールスタックは各関数ごとのス
2.3 Linux におけるクラッシュレポート
タックフレームから構成される.通常一つのスレッドには
Linux カーネルはクラッシュした際に,クラッシュログ
一つのスタックが対応して存在し,関数呼び出しの際に関
にあたる oops メッセージを出力する.oops メッセージ
数のフレームをスタックにプッシュしていき,処理が終了
にはカーネルがクラッシュした際の情報が含まれており,
すると積んだフレームをポップすることによって,関数を
開発者はデバッグの際にユーザから送付された oops メッ
呼び出す前の情報を取り出すことができる.
セージを用いてデバッグを行う.
2.3.1 oops メッセージ
oops メッセージの簡単な解説をする.図 2 に oops メッ
セージの簡単なサンプルを示す.
スタックフレームの簡単な構造を図 3 に示す.新しい関
数のスタックフレームをプッシュする際は,最初に現在の
スタックフレームの上に関数への引数をプッシュする.次
に,呼び出した関数の処理が終わった後に,戻るべきアド
原因 : 1 行目にはクラッシュの原因が記述される.図 2
レスを記憶するために実行中の関数の命令アドレスをス
の場合は NULL ポインタを参照したことによってクラッ
タックにプッシュする.最後に,ローカル変数などに必要
シュしている.
な分だけローカル領域にプッシュを行う.
カーネルバージョン: 3 行目は Linux カーネルのバー
c 2014 Information Processing Society of Japan
フレームポインタ: スタックフレーム内に格納されてい
3
Vol.2014-OS-130 No.11
2014/7/28
情報処理学会研究報告
IPSJ SIG Technical Report
らデータをひとつずつプッシュしていきシンボルテーブル
を参照し,カーネル内の有効なアドレスを指しているなら
その関数名を 2 の 9 行目のように “ ? ” 付きで出力する
(有効でないなら出力は行わない).
フレームポインタを有効にしている場合もこの処理が行
われ,フレームポインタの隣のアドレスに格納されている
リターンアドレスのみを “ ? ” の付かない通常のコールト
レースとして出力するが,それいがいの関数は “ ? ” 付き
図 3 stack frame
で出力される.
図 4
frame pointer
このため,フレームポインタを最適化した場合コールト
レースで出力される全ての関数が “ ? ” 付きで出力される
る変数や引数を参照する際にはスタックポインタやフレー
こととなる.
ムポインタを用いる.スタックポインタは最も最近参照さ
2.3.3 Windows と Linux におけるクラッシュレポー
れた位置のアドレスを指しており,例えば図 3 のローカル
領域に変数をプッシュしていくと,その分スタックポイン
タもインクリメントされていく.
トの違い
Linux の oops メッセージを Windows の ReBucket に
適用する場合,Windows で用いた場合のようにうまく分
フレームポインタはスタックフレームのベースアドレス
類できない可能性がある.これは Windows と Linux では
を記憶しておくためのものである.ベースアドレスはス
コールトレースの生成方法に違いがあることや,Linux は
タックフレームの底,正確にはフレーム内のリターンアド
Windows に比べてカーネルバージョンやディストリビュー
レスとローカル領域の間のアドレスを示している.通常
ション,コンフィグレーションが多く存在しバイナリが多
ベースアドレスは EBP レジスタに保存されているが,関
様であることが理由となる.
数呼び出しを行う際に呼び出し元の関数のベースアドレス
コールトレースの生成方法: Windows で生成されるコー
をフレームポインタとしてスタックにプッシュして記憶し
ルトレースはコールスタックにフレームポインタを積んで
ておくようになっている. フレームポインタはカーネルを
いるため,正確な情報が期待できる.しかし,Linux の場
ビルドする際にコンパイルオプションで最適化することが
合フレームポインタを最適化した場合,表示されるコール
できるため,環境によっては用いられない場合が存在する.
トレースは全て “ ? ” 付きの関数なので実際には呼び出し
フレームポインタはコールトレースを生成する際に重要
を行っていない関数がコールトレースにまぎれる可能性が
な役割を持っている.フレームポインタを用いる場合,ス
ある.このため,Linux のコールトレースは Windows の
タックフレーム内のフレームポインタを辿ることによっ
コールトレースに比べて正確でない場合がある.
て,コールトレースを生成する.
カーネルバージョンやディストリビューション: Linux
図 4 にフレームポインタを辿っていく流れを示す.ス
には多くのカーネルバージョンやディストリビューショ
タックには関数 A,B,C のスタックフレームに積まれて
ン,コンフィグが存在する.また,[6] で見ることができ
いる.スタックフレームにはそれぞれ,呼び出し元の関数
るように,ディストリビューションが不明な “ unknown ”
のフレームポインタが積まれている.関数 C から関数 A
のクラッシュログが多数送られてくる.このようなクラッ
までフレームポインタを辿る場合,スタックフレーム C は
シュログはユーザ自身がカーネルをビルドしている場合が
レジスタに保存してあるベースポインタを見ることによっ
あり,カーネルのバージョンが同じでもコンフィグやパッ
て,呼び出しもとの関数 B のベースポインタを知ること
チレベルによって多様なバイナリが存在し,それぞれが異
ができる.さらに,関数 B のベースポインタに隣接する
なる動作をすることがあるため同じ原因のバグでクラッ
アドレスに関数 A のフレームポインタが格納されている
シュした場合でも,異なる oops メッセージを出力する可
ため,関数 B の呼び出しもとである関数 A のベースポイ
能性がある.
ンタを知ることが出来る.この赤い矢印の順番にフレーム
図 5 にカーネルバージョンが同じでも,バイナリが異
ポインタを辿る事によってコールスタックをトレースする
なるために異なるコールトレースを出力してしまう例を示
ことができる.
す.5 (a) は vanilla カーネルを通常のコンフィグでビルド
Linux のコールトレース: Linux のコールトレースの生
したもので,図 5 (b) はカーネルコンフィグの “ Spinlock
成はフレームポインタがスタックに積まれていないこと
and rw-lock debugging: basic checks ”,“ Mutex debug-
を前提にしているため,少し異なる方法で行われている.
ging: basic checks ”,“ Lock debugging: detect incorrect
Linux のコールトレースでは実行中の関数を取得した後は,
freeing of live locks ”,“ Lock debugging: prove locking
フレームポインタを辿ることができないため,スタックか
correctness ”,“ Lock dependency engine debugging ” を
c 2014 Information Processing Society of Japan
4
Vol.2014-OS-130 No.11
2014/7/28
情報処理学会研究報告
IPSJ SIG Technical Report
図 5 異なるバイナリのカーネルによって生成されるコールトレース
有効にしてロックを取る際にログを取るように設定したも
のである.このようにコンフィグなどが異なるため,同じ
db
カーネルバージョンでも多様なバイナリが存在し,同じバ
1897
表 1 収集したクラッシュログ
fb
iz
ltp
ub
total
1864
10294
1664
3095
1774
グでもコールトレースが異なってしまうことがある.
3. Linux における ReBucket の有用性
本研究はバグの分類方法である ReBucket を Linux に
ログを収集した.5 つのマシンで異なるワークロードを用
いる理由は,現実のクラッシュログは同じバグでもユーザ
によって異なるワークロードによってクラッシュを引き起
適用してその効果を定量的に評価する.
こすためである.
3.1 調査方法
3.2 調査環境
Linux での ReBucket の効果を調査するためにひとつの
調査に用いたカーネルは,vanilla カーネルのバージョン
root cause に対応する複数のクラッシュログと,異なる
2.6.32.60 で,バグの挿入はファイルシステムの ext3 に行っ
root cause によってクラッシュした際の複数のクラッシュ
た.クラッシュログを集めるために使用したワークロード
ログが必要となる.しかし,実際の Linux カーネルバグに
は UnixBench (ub) ver.5.1.3 [10],FileBench (fb) ver.1.4.9
よって生成されたクラッシュログから調査をすることは難
[11],DBench (db) ver.4.0 [12],IOzone (iz) ver.3.420 [13],
しい.なぜなら,Redhat の提供する [6] のように実際に
Linux Test Project (ltp) [14] であった.また,同じワーク
ユーザから送付されたクラッシュログを用いることは可能
ロードでもクラッシュした際に生成されるクラッシュログ
だが,その root cause を判別できないため,分類した結果
が異なる可能性があるため,ひとつの root cause に対して
が正しいか判断できないためである.また Bugzilla のよ
同じワークロードを 5 周実行させた(5 回の内全ての場合
うなバグ管理システムに報告されたバグを再現して,複数
でクラッシュするわけではない).
のクラッシュログを集めることも困難で現実的ではない.
クラッシュログ: 上記の方法で収集したクラッシュログ
そのため,本研究では Linux カーネルにソフトウェア
の数をワークロードごとに表 1 に示す.5 つのワークロー
フォールトインジェクションを行うことにより,Linux カー
ドを用いて収集したクラッシュログは全てで 10294 件で,
ネルバグの再現を行う.フォールトインジェクタには,実
それらに対応する root cause は全てで 850 種類であった.
在するソフトウェアバグを調査 [9] して作られたバグモデ
パラメータ: 2.2.3 節で解説した最適なパラメータの決定
ルを基に作成された SAFE [8] を用いた.
方法を用いてパラメータ c, o, d を決定した.本調査では
本調査では SAFE によって生成された 7096 種類のバグ
400 件のクラッシュログをデータセットとして,最適なパ
をひとつずつ挿入し,そのカーネル上でワークロードを実
ラメータを求めた.本調査ではパラメータをそれぞれ c =
行してクラッシュした際に生成されるクラッシュログを用
0.4,o = 0.4,d = 0.3 として ReBucket を行った.
いて分類を行った.分類を行うためにひとつのバグ (root
cause) に対して複数のクラッシュログが必要であるため,
3.3 調査結果
5 つのマシンで異なるワークロードを実行してクラッシュ
3.3.1 評価方法
本調査では ReBucket の結果を評価するために,ふたつ
c 2014 Information Processing Society of Japan
5
Vol.2014-OS-130 No.11
2014/7/28
情報処理学会研究報告
IPSJ SIG Technical Report
の評価方法を用いて評価を行った.(1) ひとつ目は,同じ
シュログが同じようなコールトレースを持っていた場合,
root cause に対応するクラッシュログがいくつの bucket
これまでの実行履歴を表す “ ? ” 付きの関数があることに
に分類されたか,というものである.これは,ベストケー
よって正しく分類ができるためである.
スでは同じ root cause に対応するクラッシュログは全て
フォールトインジェクタの SAFE では同じ関数内に複
同じ bucket に分類される.(2) ふたつ目は,同じ bucket
数のバグを挿入する.たとえば,最大で一つの関数の中に
の中に何種類の root cause に対応するクラッシュログが
63 個のバグを挿入している.このように,同じ関数内に存
分類されたか,というものである.これは,ベストケース
在するバグは同じような関数の実行順序を辿るものが多い
ではひとつの bucket には一種類の root cause に対応する
とため,同じ bucket 内に同じ関数内のバグが分類されて
クラッシュログのみが分類される.また,2.3.3 に挙げた
しまうことがある.そのため,実際には一つの関数に何個
ような問題があるため,コールトレース中の “ ? ” が付い
もバグが存在する可能性は低いということと,デバッグの
た関数を使って分類した場合と,取り除いて分類した場合
際には同じ関数のバグごとに纏まるだけでも負担がかなり
で以上のふたつの評価を行う.
減り,関数の特定が容易になることから,同じ関数内に挿
3.3.2 評価方法 1
入されたバグは同じバグという考えによって評価方法 2 を
同じ root cause に対応するクラッシュログがいくつの
関数ごとに評価したものを図 7 に示す.
bucket に分類されたかを図 6 に示す.“ ? ” 付きの関数を
“ ? ” を有効にして分類した場合では,ひとつの bucket
有効にした場合,ひとつの bucket に集まったバグは全体
に一種類のバグのみが分類されたものは全体の約 72 % と
の約 73 % であった.それに対して, “ ? ” 付きの関数を
なり,同じ関数へのバグを異なるバグと考えて評価した
取り除いた場合,ひとつの bucket に集まったバグは全体
ものよりも,約 22 % 増加した.“ ? ” なしの場合でも,
の 約 78 % であった.“ ? ” が付いた関数は関数が引数
約 68 % が一種類のバグのみが分類された bucket となり,
に取る関数ポインタや,前にスタックに積んであった関数
前の評価のものよりも約 23 % 増加した.また,“ ? ” あ
のリターンアドレスによって表示されるため,実際は同じ
りの場合,なしの場合でもひとつの bucket に分類された
コールトレースでも環境や実行履歴などによって出力され
root cause は最大でも 11 種類に減少していた.
るコールトレースが異なる場合がある.そのため,“ ? ”
3.3.4 うまく分類されなかったケース
を有効にして分類を行った場合,同じコールトレースでも
評価方法 1 について,同じ種類のバグが複数の bucket
実行履歴などによって別々の bucket に分類されている場
に分類されてしまったクラッシュログについて調査し,そ
合がある.“ ? ” を取り除いて分類した場合,このような
の原因についての分析を行った.その結果,複数の bucket
理由によって別々の bucket へ分類されていたクラッシュ
に分類されてしまった原因として 2 つのパターンを確認す
ログが同じ bucket へ分類されるため,“ ? ” を取り除い
ることができた.2 つのパターンについて例を示して説明
て分類した場合の方が精度が高くなっている.
する.また,ひとつの bucket に複数のバグを分類してし
3.3.3 評価方法 2 - “ ? ” あり場合 -
まった理由についても考察を行う.
同じ bucket の中に何種類の root cause に対応するク
原因 1: ひとつ目の原因は “ ? ” の有無によって複数の
ラッシュログが分類されたかを図 7 に示す. “ ? ” 付き
bucket に分類されているものであった.具体的な例を図 8
の関数を有効にして分類した場合,bucket の中に一種類の
に示す.コールトレースの横に “ * ” がある関数がふたつ
root cause に対応するクラッシュログのみが分類されたも
のコールトレース間で共通しているものである.図 8 の場
のは全体の約 50 % であった.図 7 ではひとつの bucket
合,“ ? ” が付いた関数のみが異なっており,“ ? ” の付い
に 10 種類のバグが分類されたものまで示しているが,最
た関数を除去すると全く同じコールトレースになるが,こ
大ではひとつの bucket に 70 種類のバグが分類された.ま
の二つのクラッシュログは異なる bucket へ分類されてい
た,図 7 に示している 1 から 10 種類のバグが分類された
た.このように,ReBucket では共通する関数がトップの
bucket は全体の 95 % であった.
位置に近いほど,または共通する関数の位置が差が近いほ
“ ? ” 付きの関数を取り除いて分類した場合, bucket の
ど重み付けをするため,トップに近い位置やコールトレー
中に一種類のバグのみが分類されたものは全体の約 45 %
ス間で別の位置に “ ? ” のついた関数がある場合,誤って
であった.また,ひとつの bucket には最大で 74 種類の
分類してしまう場合がある.
root cause に対応するクラッシュログが分類されていた.
原因 2: ふたつ目の原因はコールトレース間のトップに
図 7 に示している 1 から 10 種類のバグが分類されていた
近い位置の関数のみが共通していて,下のコールトレース
bucket は,全体の 91 % であった.
は異なる関数であるというものであった.具体的な例を図
“ ? ” 付きの関数を有効にして分類した場合,取り除い
9 に示す.“ * ” がついている関数の str2hashbuf sgned()
て分類した場合よりも精度が高くなった.これは,評価方
と ext3fs dirhash() が共通しているが,それより下の関数
法 1 の場合とは逆に,異なる root cause に対応するクラッ
は共通していないことが分かる.このようにクラッシュを
c 2014 Information Processing Society of Japan
6
Vol.2014-OS-130 No.11
2014/7/28
情報処理学会研究報告
IPSJ SIG Technical Report
図 6
評価方法 1
図 7
評価方法 2:
起こした関数の直近のみが共通するコールトレースの場
は “ ? ” を除いて分類した場合,有効にして分類した場合
合,ReBucket では異なるの bucket へと分類されてしまう
よりも異なる bucket に分類されるバグの割合が低くなっ
可能性がある.
ていた.これは 3.3.4 節の原因 1 で示したように “ ? ” が
し か し ,こ の 例 で 示 す よ う な コ ー ル ト レ ー ス を 生
原因で同じバグが別々の bucket へ分類されてしまう,と
成するバグは現実に即したバグでない可能性がある.
いうことがなくなったためである.評価方法 2 では “ ? ”
こ の 例 の 場 合 ,SAFE に よ っ て 挿 入 し た バ グ は 関 数
を有効にして分類した場合,除いて分類した場合よりも異
ext3fs dirhash() へのものであり,クラッシュを起こし
なるバグが同じ Bucket に分類される割合が低くなってい
た RIP の str2hashbuf sgned() との距離が近い.このよう
た.これは,別々のバグでも “ ? ” がない場合類似してい
に多くのシステムコールで共通して呼ばれるような関数で,
るコールスタックが “ ? ” つきの関数の違いによって異な
その関数に入ったらすぐクラッシュするバグは,リリース
る bucket に分類されたためであると考えられる.
前のデバッグによって取り除かれているようなバグである
2.3.3 節で “ ? ” のついている関数は実際のコールトレー
可能性があるため,テストケースとしてあまり良いバグと
スではないと述べた.しかし,“ ? ” のつく関数は関数へ
は言えない.本調査ではフォールトインジェクタを用いた
の引数や以前にスタックに積まれたリターンアドレスのよ
ためこのようなバグが生成されてしまったと考えられる.
うな実行履歴なので有用な情報を示していると言える.そ
その他の原因: 上に挙げた 2 つの原因以外では,コール
のため,異なるバグのコールトレースが類似している場合
トレースが全く異なるものや,全て “ ? ” つきの関数に
でも実行履歴の違いによって別々の bucket に分類される
なっているものなどが挙げられる.このような例はコール
ことがある.また,“ ? ” を無くしてしまうことによって
トレースのみで分類を行う ReBucket では分類を行う事が
極端にコールトレースが短くなってしまうものもあり (“ ?
困難である.
” を除いた場合コールトレースが 2 つになってしまうもの
bucket に複数のバグが分類された理由: ひとつの bucket
に複数のバグが分類された理由の一つは,バグを挿入した
システムが ext3 だけであるため,似たようなコールトレー
スのクラッシュログが集まってしまったと言うことが挙
を確認した),そのようなバグの分類にも実行履歴を示して
いる “ ? ” は有効であると言える.
4. 関連研究
げられる.本来開発者に送付されるクラッシュレポートは
Microsoft 社 は Windows Error Reporting を用いてユー
様々なシステム (e.g. デバイスドライバ,ネットワークな
ザからクラッシュログを集めており,そのクラッシュログ
ど) のバグが原因でクラッシュした際に生成されるものな
を Bucketing[3] によって root cause ごとに分類している.
ので,コールトレースもその分異なるものが多いと考えら
しかし,Bucketing は Windows に固有のさまざまな知識
れる.しかし,本研究では ext3 という限られたシステム
を利用したアドホックな手法となっており,Linux などの
のバグによるクラッシュログを対象にしているため,コー
他の基盤ソフトウェア上のシステムに適応できるものでは
ルトレースが類似しているものが多く,複数のバグが同じ
ない.
bucket に分類されてしまうということが起こってしまった
また,Bucketing ではうまく分類できなかったクラッ
と考えられる.ふたつ目の原因は,同じプロセスでクラッ
シュログを分類するために提案された方法として,Crash
シュをしているとコールスタックも類似してしまう,とい
Graph [15] と 本研究で用いた ReBucket が知られている.
う点である.実際に図 7 の関数ごとで見た場合の 10 種類
Call Graph は Bucketing の分類で同じ root cause のク
のバグが分類されている bucket では,分類されたクラッ
ラッシュログが複数のグループに分類されてしまう問題に
シュログのプロセスは全て umount であった.
対処している.これは,分類されたグループ内のコールト
3.3.5 “ ? ” の影響について
レースを集約してグラフにすることで,他のグループとの
コールトレース中の “ ? ” の影響は評価方法 1 の場合で
c 2014 Information Processing Society of Japan
比較を行い同じ root cause に対応するグループを判別す
7
Vol.2014-OS-130 No.11
2014/7/28
情報処理学会研究報告
IPSJ SIG Technical Report
図 8
原因 1 の例
図 9
原因 2 の例
るというものである.
ものは全 850 種類のバグの内,73% ,“ ? ” を取り除いた
一方,本研究で用いた ReBucket は,クラッシュレポート
コールスタックの場合では 78% であった.一つの bucket
のコールスタックの部分に注目し,類似したコールスタッ
に一種類のバグのみが分類されたものは,全体の bucket
クを持つクラッシュレポートを同グループに分類する.[7]
の 50% で,“ ? ” を取り除いたコールスタックの場合で
によれば ReBucket は Bucketing に比べ 9 % の精度の向
は,45% であった.異なるバグでも同じ関数内のバグを同
上が示されている.この二つのバグ分類方法は Windows
じバグとしてみた場合は,全体の 72% の bucket は一種類
製品のバグを対象にしているが,本研究では Linux カーネ
のバグのみが属する bucket であった.また, “ ? ” を取
ルのバグを対象に分類を行った.
り除いたコールスタックの場合では,68% であった.
Palix らは Linux カーネルバグの時系列による変化を調
同じ種類のバグが複数の bucket に分類されてしまった
べている.Linux カーネルバグは 10 年間で殆ど変わらな
原因についての分析を行ったところ,“ ? ” 付きの関数が
い件数を維持しており,これらのバグが原因でユーザから
異なるために異なる bucket に分類されたものと,バグを
送付されるクラッシュログの分類が ReBucket で可能なら
挿入した関数とクラッシュを起こした関数が近いため異な
ば,開発者の負担を軽減することができる.また,Palix
る bucket に分類されてしまったケースを確認した.
らは Linux カーネルバグはファイルシステムのバグが多い
調査結果から,Windows のバグ分類手法である ReBucket
こと示しており,本研究もファイルシステムのバグを対象
は Linux で用いる場合,Windows で用いる場合よりも有
にバグの分類を行っている.
効ではないことが分かった.Windows ほど分類が有効で
5. まとめ
は無い理由としては Linux 特有のコールトレースの生成方
法が挙げられる.Linux ではフレームポインタがないこと
本稿では,Windows Error Reporting で用いられるバグ
を前提にコールトレースを生成しているため,実際のコー
の分類方法である ReBucket を Linux カーネルバグに適用
ルトレースとは異なる関数が “ ? ” つきで出力されること
した場合の効果について調査し,定量的な評価を行った.
になる.このため,Linux では Windows のように効果的
ソフトウェアフォールトインジェクタの SAFE を用い
にバグの分類が行えないと考える.
てカーネルコード中にバグを挿入し,クラッシュした際の
クラッシュログを収集した.集まったクラッシュログ全
5.1 今後の課題
10294 件,850 種類に ReBucket を適用してバグの分類を
本稿では vanilla カーネル ver.2.6.32.60 の ext3 にバグ
行った.分類結果から同じ種類のバグがいくつのバグに分
を挿入して生成されたクラッシュログを対象に調査を行っ
類されたか,一つの bucket に何種類のバグが分類された
た.しかし,実際に開発者には,さまざまなディストリ
か,についての評価を行った.
ビューション,カーネルバージョン,コンフィグレーショ
同じ種類のバグが一つの bucket に集まって分類された
c 2014 Information Processing Society of Japan
ン,システムでクラッシュした際のクラッシュログが送付
8
情報処理学会研究報告
IPSJ SIG Technical Report
Vol.2014-OS-130 No.11
2014/7/28
されるため,ReBucket の効果を評価するためには様々な
シチュエーションでのクラッシュログを対象にする必要が
ある.
参考文献
[1]
[2]
[3]
[4]
[5]
[6]
[7]
[8]
[9]
[10]
[11]
[12]
[13]
[14]
[15]
D. Wheeler. SLOCCount. http://www.dwheeler.com/.
Nicolas Palix, Gaël Thomas, Suman Saha, Christophe
Calvès, Julia Lawall, and Gilles Muller. Faults in linux:
Ten years later. In Proceedings of the Sixteenth International Conference on Architectural Support for Programming Languages and Operating Systems (ASPLOS
XVI), pages 305–318, 2011.
Kirk Glerum, Kinshuman Kinshumann, Steve Greenberg, Gabriel Aul, Vince Orgovan, Greg Nichols, David
Grant, Gretchen Loihle, and Galen Hunt. Debugging in
the (very) large: Ten years of implementation and experience. In Proceedings of the 22nd Symposium on Operating Systems Principles (SOSP ’09), pages 103–116,
2009.
MoZilla: Crash Stats. http://crash-stats.mozilla.com.
Apple:
Technical Note TN2123:
CrashReporter.
http://developer.apple.com/library/mac/#technotes/.
Linux Kernel Oops. http://www.kerneloops.org.
Yingnong Dang, Rongxin Wu, Hongyu Zhang, Dongmei
Zhang, and Peter Nobel. Rebucket: A method for clustering duplicate crash reports based on call stack similarity. In Proceedings of the 2012 International Conference
on Software Engineering (ICSE ’12), pages 1084–1093,
2012.
Marcello Cinque, Domenico Cotroneo, Roberto Natella,
and Antonio Pecchia. Assessing and improving the effectiveness of logs for the analysis of software faults. In Dependable System and Networks (DSN ’10), pages 457–
466, 2010.
João Durães and Henrique Madeira. Emulation of software faults: A field data study and a practical approach. IEEE Transactions on Software Engineering
(TSE ’06), 32(11):849–867, 2006.
UnixBench.
http://code.google.com/p/byteunixbench/.
Filebench. http://sourceforge.jp/projects/sfnet filebench/.
DBENCH. http://dbench.samba.org/.
IOzone. http://www.iozone.org/.
Linux Test Project. http://ltp.sourceforge.net/.
Nachiappan Nagappan Sunghun Kim, Thomas Zimmerman. Crash graphs: An aggregated view of multiple
crashes to improve crash triage. pages 486–493, 2011.
c 2014 Information Processing Society of Japan
9
Fly UP