ソフトウェアエンジニアリングシンポジウム 2012

開発履歴情報を用いた修正漏れの検出
肥後 芳樹1,a)

楠本 真二1,b)

概要：バグ修正や機能追加を行うためにソースコードに対して修正を行う場合は，修正が必要なすべてのコード片を把握しなければならない．修正が必要なコード片を見落としてしまうと，ソースコード中に修正漏れが発生してしまう．ソースコードの修正前であれば，grep 等のキーワード検索ツールを用いること
により，修正が必要なコード片を見落とす可能性は低くなる．しかし，発生した修正漏れに対しては，そのようなツールでは十分な支援を得られない．本論文では，ソースコード中において修正漏れを含むコード
片の検出手法を提案する．提案手法は，ソースコードの開発履歴をマイニングし，どのようなコード片がどのように変更されたかを学習する．そして，その学習データに基づいて最新バージョンのソースコード
から，修正漏れを含むコード片を検出する．提案手法を実装し，HTTPD と FreeBSD に対して実験を行った．その結果，バグ修正漏れ，リファクタリング実施漏れ，機能変更・機能追加漏れ，コメント修正漏れを含むコード片を多数検出できた．

Identifying Unintended Inconsistencies Based on Mining Development Histories
H IGO YOSHIKI1,a)K USUMOTO S HINJI1,b)

Abstract: When we modify source code for performing a given bug fix or functional addition, we must recognize
all the code fragments to be modified. If not, unintended inconsistences occur in the source code. Before modifying the source code, keyword-based search tools like grep are suitable for preventing the code fragments from being
overlooked. However, once inconsistencies occur in the source code, such tools cannot help us adequately. In thispaper, we propose a new method to identify unintended inconsistencies in source code automatically. The proposed
method analyzes source code modifications in a repository to derive modification patterns. A modification patternindicates what kind of code and how it was modified. The derived modification patterns are queries to identify unintended inconsistencies from the latest version of source files. We implemented the proposed method and applied
it to HTTPD and FreeBSD. As a result, we identified many overlooked code fragments for bug fixes, refactorings,
functional enhancements, and code comments.

1. はじめにらは，オープンソースソフトウエアのバッファオーバーフ
ローの修正を題材に，修正が必要なコード片の見逃し防止

バグ修正や機能追加を行う場合には，ソースコード中の策として，grep とコードクローン検出ツールが有効である

修正が必要な全てのコード片を把握する必要がある．もしことを示した [1]．また，森崎らは，国内の企業が開発した

それらを見落とすと修正漏れが発生してしまう．それらはシステムに対してコードクローン検出ツールを適用し，そ後にフォールトの原因となり，システムの可用性を下げる

れがコード片の見逃し防止対策として有効であることを示ばかりではなく，そのコード片を特定し修正するためのコ

した [4]．しかし，それらのツールは，発生した修正漏れつストも必要となる．

いては十分に支援できない．

ソースコードの修正前であれば，grep 等のキーワード検• grep を利用するには検索対象キーワードが必要であ索ツールやコードクローン検出ツールを用いることにより，る．しかし，どのコード片において修正漏れが存在す

修正が必要なコード片を見落とす可能性は低くなる．泉田

るのか不明なため，キーワードの指定ができない．

1

a)
b)

大阪大学 大学院情報科学研究科
Graduate School of Information Science and Technology, Osaka University
higo@ist.osaka-u.ac.jp
kusumoto@ist.osaka-u.ac.jp

c 2012 Information Processing Society of Japan• コードクローン検出ツールを用いれば，コピーアンド
ペースト後の変数名の置換漏れ等の軽微な修正漏れを検出できる [3]．しかし，文の追加・削除等の大きな単1

ソフトウェアエンジニアリングシンポジウム 2012

:	
354 	
355 for (lr = head_listener; lr ; lr = lr->next) {	83,956	
356
ap_get_os_sock(lr->sd, &nsd);	
ap_get_os_sock(&nsd, lr->sd);	
357
if (FD_ISSET(nsd, main_fds)) {	
358
head_listener = lr->next;	
:	
380
num_listeners++;	
381
if (lr->sd != NULL) {	83,956	
ap_get_os_sock(&nsd, lr->sd);	
382
ap_get_os_sock(lr->sd, &nsd);	
383
FD_SET(nsd, &listenfds);	
384
if (listenmaxfd == INVALID_SOCKET || nsd > listenmaxfd) {	:	1083/* Associate each listener with the completion port */	
1084
for (lr = ap_listeners; lr != NULL; lr = lr->next) {	83,956	
ap_get_os_sock(&nsd, lr->sd);	
1085
ap_get_os_sock(lr->sd, &nsd);	
1086
CreateIoCompletionPort((HANDLE) nsd, //(HANDLE)lr->fd,	
1087
AcceptExCompPort,	
:	1313
ap_log_error(APLOG_MARK, APLOG_NOERRNO | APLOG_INFO, server_conf,	
1314"Parent: Duplicating socket %d and sending it to child process %d.", lr->sd );	
1315
ap_get_os_sock(lr->sd,&nsd);	
83,960	
ap_get_os_sock(&nsd, lr->sd);	
1316
if (WSADuplicateSocket(nsd, 	
1317
pi.dwProcessId,	
:	

様の命令がある．リビジョン 83,956 において，そのうちの 3 つ（356 行目，382 行目，1085 行目）が変更されている．その後，リビジョン 83,960 において，1,315 行目に対しても同様の修正が行われている．リビジョン 83,960 のコミットログには，修正漏れがあったことを表す文章が記述されている．このことから，これら 4 つのコード片は同時に同様の修正がされるべきであったが，開発者がこのう
ちの 1 つを見落としていたことがわかる．この例で示した
ように，複数のコード片に対して同様の修正を行う必要がある場合に，開発者が修正すべき全てのコード片を把握しているとは限らない．
そこで，本論文では，下記のリサーチクエスチョンを設定する．

図 1 server/mpm/winnt/mpm winnt.c の一部（リビジョン 83,955）

Fig. 1 a part of server/mpm/winnt/mpm winnt.c (revision 83,955)

RQ1 同時に行われていない同様の修正がどの程度存在す
るのか
修正すべきコード片を特定した場合に，grep 等のキー

位の修正漏れは検出が難しい．また，コードクローン

ワード検索ツールを用いれば，他の修正すべき箇所を列挙として検出されるためには，コード片が一定以上の大することができるため，修正漏れが発生する可能性が低くきさで類似している必要がある．
本論文では，開発履歴をマイニングすることにより，修なる．しかし，発生した修正漏れについては，grep で支援を得ることは難しい．

正漏れを含むコード片を検出する手法を提案する．具体的

コードクローン検出手法を用いて修正漏れを検出する方には，開発履歴のマイニングにより，どのようなコード片が法が提案されている [3]．この手法ではコードクローン検

どのように変更されているのかを学習する．その学習デー

出し，そこに含まれている変数の対応関係を調べる．対応

タを用いて，対象ソースコードから過去に変更されている関係がとれていないコードクローンが修正漏れの候補としコード片と同形のコード片を検出する．提案手法は，grepてユーザに提示される．この手法はコードクローンに含まやコードクローン検出ツールの問題点を解決しており，以れる修正漏れを提示するが，コードクローンとして検出さ下の特徴を持つ．

れないコード片については修正漏れを指摘できない．図 1• 字句単位の修正漏れ（変数やリテラルの置換漏れ）だでは，修正を行うべき 4 つの行はコードクローンであるが，けではなく，文単位の修正漏れ（文の追加・削除漏れ）

その前後の行は重複していない．つまり，一行のみの小さも検出可能なコードクローンが 4 つ存在している．コードクローン検• 修正漏れを含むコード片がある程度以上の大きさの重複コードである必要がない• ソースコードの深い解析を必要とせず，複数のプログ
ラミング言語への展開が容易• スケーラビリィが高く，数百万行規模のソフトウェア
であっても数十分程度で解析可能
提案手法をツールとして実装し，HTTPD と FreeBSD に適用し，以下の結果を得た．

出ツールの設定を変更することで，このような小さいコー
ドクローンを検出することは可能である．しかし，そのよ
うな小さいコードクローンの検出を行った場合，多量のコードクローンが検出されてしまうため，検出されたコー
ドクローンを調査する負荷が大きい．さらには，修正内容
が図 1 に示すような変数名の変更ではなく，文の追加や削除といったより大きな変更だった場合は，コードクローン
として検出されない．

• 多くのリビジョンにおいて修正漏れが存在しているこ

本論文では，開発履歴をマイニングすることにより修正と，および，それらの多くは後に修正が加えられてい漏れを含むコード片とその修正方法を提示する手法を提案ること（修正漏れではなくなること）がわかった．

する．たとえば，図 1 の場合では，リビジョン 83,955 から• 1 つのバージョンに着目した場合に，それまでの開発

83,956 への変更をマイニングすることにより，下記の変更

履歴から得た学習データを用いて多数の修正漏れを検出できた．

2. 研究の動機
図 1 は，HTTPD のソースコードである．このソースコー

が 3 回起こったことがわかる．
ap_get_os_sock(lr->sd, &nsd);↓
ap_get_os_sock(&nsd, lr->sd);
この情報を用いることにより，リビジョン 83,956 以降でドでは，356 行目，382 行目，1,085 行目，1,315 行目に同

c 2012 Information Processing Society of Japan2

ソフトウェアエンジニアリングシンポジウム 2012

は，ソースコード中に “ap_get_os_sock(lr->sd, &nsd);”が存在した場合には，“ap_get_os_sock(&nsd, lr->sd);”に変更すべきである，という提示ができる．
また，提案手法の有効性を調査するために，下記のリ
サーチクエスチョンを設定する．

RQ2 開発履歴をマイニングすることにより，どの程度の修正漏れを検出できるか

3. 提案手法

1: A	
2: B	
3: changing 1	
4: changing 2	
5: C	
6: D	
7: deleting 1	
8: deleting 2	
9: E	
10: F	
11: G	
12: H	

1: A	
2: B	
3: changed 1 	
4: changed 2	
5: C	
6: D	
7: E	
8: F	
9: G	
10: added 1	
11: added 2	
12: H	

3,4c3,4	
< changing 1	
< changing 2	---	> changed 1 	> changed 2	
7,8d6	
< deleting 1	
< deleting 2	
11a10,11	
> added 1	
> added 2	(a) 修正前(b) 修正後(c) 差分

本論文では，ソースコード中に存在する修正漏れを自動的に検出する手法を提案する．提案手法は，開発履歴を解析するマイニング処理と対象ソースコードから修正漏れを検出する検出処理から構成されている．まず，3.1 節で提図 2 修正前ソースファイル，修正後ソースファイル，diff コマンドを用いたそれらの間の差分出力

Fig. 2 Source files before and after a modification, and diff output be-

案手法で利用する用語の定義を行う．次に，3.2 節でマイtween them

ニング処理，その後，3.3 節で検出処理について述べる．なお，提案手法は，CVS や Subversion 等のバージョン管理シ

コード片に変化しうるため，m ≤ n となる．

ステムで管理されているソフトウェアを前提としている．

3.2 マイニング処理
3.1 用語の定義

マイニング処理の入力と出力を以下に示す．

まず，コード片を定義する．

入力 対象ソフトウェアのリポジトリ

定義 1 (コード片) ソースファイル中の一部分を表す，

出力 支持度と確信度の付いた修正パターン群

長さが 0 以上の文字列である．

マイニング処理は下記の手順からなる．

修正パターンは，どのようなコード片が，いつ，どのよう

手順 1

ソースファイルが修正されたリビジョン群の特定なコード片に修正されたのかを表す．以下に定義を示す．

手順 2

特定したリビジョン群から修正パターンを抽出

定義 2 (修正パターン) 修正前のコード片を CFbe f ore ，修

手順 3

抽出した修正パターンの支持度と確信度を計算

正後のコード片を CFa f ter ，修正が行われたリビジョンを r

手順 1 では，少なくとも 1 つのソースファイルが修正さとした場合，その修正パターンを，(CFbe f ore ,CFa f ter , r) でれたリビジョンを特定する．リポジトリでは，ソースコー

表す．

ドに加えてドキュメント等の成果物も管理されている．そ次に，修正パターンの支持度*1 を定義する．

のため，すべてのリビジョンでソースコードが修正されて

定義 3 (支持度) 修正パターンの出現回数を表す値でいるわけではない．そのようなリビジョンは修正パターン

ある．2 つの修正パターン MP1 = (CF1be f ore ,CF1a f ter , r1 )，の抽出対象とはならない．バージョン管理システムは，指MP2 = (CF2be f ore ,CF2a f ter , r2 )，があった場合に，CF1be f ore =定したリビジョンで修正されているファイル一覧を表示すCF2be f ore ∧CF1a f ter = CF2a f ter が真になれば，MP1 と MP2る機能を持つ．この機能により表示されたファイルの拡張は同じ修正パターンと定義される．よって，MP1 や MP2 が子を調査することにより，マイニング処理が必要であるリ

表す修正パターンの出現回数は 2 回となる．もし，MP1 とビジョン群の特定を行える．

MP2 が同じでない場合は，それぞれの修正パターンは 1 回ずつ出現したことになる．

手順 1 において，n 個のリビジョン {r1 , r2 , · · · , rn } でソー
スファイルが修正されていた場合，手順 2 では，r1 と r2 ，r2

次に，修正パターンの確信度*2 を定義する.

と r3 ，· · · , rn−1 と rn の間の差分を取得する．取得した差分

定義 4 (確信度) ある修正前コード片から，ある修正後に現れているコードが，修正パターンの修正前コード片とコード片が生成される確率である．修正パターンの集合が修正後コード片である．図 2 は，修正前後のソースコード与えられた時に，それらの中で修正前コード片が CFbe f oreとその差分を diff コマンドを用いて出力した様子を表してである修正パターンの数を n とする．また，それらのうち，いる．この例の場合だと図 2(c) の 3,4c3,4, 7,8d6，11a10,11

修正後コード片が CFa f ter である修正パターンの数を m との 3 つが修正パターンとして抽出される．

する．このとき，修正前コード片が CFbe f ore ，修正後コー
ド片が CFa f ter である修正パターンの確信度は， mn で表さ全ての修正パターンを抽出した後に，手順 3 では，修正パターンの支持度と確信度を計算する．

れる．なお，一種類の修正前コード片は複数種類の修正後*1*2

supportconfidencec 2012 Information Processing Society of Japan

3.3 検出処理
まず，検出処理の入力と出力を以下に示す．

3

ソフトウェアエンジニアリングシンポジウム 2012

入力

正パターンの誤検出*4 が多数検出されてしまうため，コー• 対象リビジョンのソースファイル群

ド片の正規化を行う．正規化後の修正前コード片と修正後• 支持度と確信度の付いた修正パターン群（マイニン

コード片を比較し，それらが同じ文字列である場合は，修グ処理の出力）• 支持度，確信度，一致箇所数のしきい値
出力

対象リビジョンのソースファイル中における修正漏

れ候補とその修正方法

正パターンとしての抽出は行わない．具体的には下記の手順で処理を行う．
手順 1

svn diff コマンドを用いて差分を取得

手順 2

差分に現れている修正前後のコード片の正規化（空一致箇所数とは，1 つの修正パターンによって検出されたコード片（修正漏れ候補）の数である．例えば，多くの

白，タブ，改行文字の削除）
手順 3

コード片が 1 つの修正パターンによって検出された場合は，それらは修正漏れとは考えにくい．過去に修正されたコード片と同形のコード片が，修正前の状態で対象ソースファ

正規化後の修正前後のコード片が同一文字列でなければ，修正パターンとして抽出
この実装では，コード片の同値性は以下のように定義されている．

イルに存在していることは事実であるが，それらは意図的

定義 5 (コード片の同値性) 2 つのコード片から全てのにその状態であると考えられる．このような誤検出（意図空白，タブ，改行文字を取り除いた後に，それらが同一文的に修正を行っていないコード片の検出）を抑えるために，字列になるのであれば，その 2 つのコード片は同値である．

一致箇所数にしきい値を設ける．たとえ，修正漏れ候補のコード片が見つかった場合でも，そのしきい値以上の数で5. 評価

あれば，それらは検出処理において出力されない．
検出処理は以下の手順からなる．

オープンソースソフトウェアの HTTPD*5 と FreeBSD*6 に対して実験を行った．実験対象の詳細については，表 1 に示

手順 1

修正漏れの検出に用いる修正パターンの抽出

す．HTTPD の実験対象期間は，1.3.x ブランチが作成され

手順 2抽出した修正パターンを用いて，対象リビジョンる前とした．この期間では，バージョン 1.3.0 のリリースにから修正漏れ候補を検出

向けて新機能の追加とバグ修正が行われていた．FreeBSD

手順 1 では，入力として与えられた修正パターン群のうの実験対象期間は，STABLE8 ブランチが作成されてからち，支持度と確信度が共にしきい値以上の修正パターンが

STABLE9 ブランチが作成されるまでの期間とした．この抽出される．

期間では，バージョン 9 に搭載する新機能の追加を行い，

手順 2 では，，抽出した修正パターンの修正前コード片を期間終了間近では，新機能の追加は凍結され，安定化のた用いて対象リビジョンのソースファイルを検索する．一致めのバグ修正のみを行うという開発プロセスが取られていしたコード片が修正漏れ候補である．もし，一致したコー

た．これらの期間に存在しており，かつ，1 つ以上の.c ファ

ド片の数が一致箇所数のしきい値以下であれば，それらはイルが更新されている 2,784 個のリビジョン（HTTPD）と出力される．なお，その修正パターンの修正後コード片が7,689 個のリビジョン（FreeBSD）を対象とした．また，こ修正方法となる．

の実験では，しきい値を用いて下記の値を用いた．

4. 実装
提案手法をツールとして実装した．現在のところ，対応支持度の下限 3
確信度の下限 1.0
一致箇所数の上限 1

しているバージョン管理システムは Subversion のみである．作成したツールの入力を以下に示す．

マイニング処理の結果として，HTTPD から 737 個，

FreeBSD から 983 個の修正パターンを得た．以降，本節で• 対象システムのリポジトリ

は，これらの修正パターンを用いて，2 節で示した 2 つの• 修正漏れコード片の検索対象ソースファイル群

RQ について調査した結果を述べる．

• 支持度，確信度，一致箇所数のしきい値
出力は検索対象ソースファイル群から検出された修正漏れ

5.1 RQ1 に対する実験候補である．

HTTPD については 145/737(=19.6%)，FreeBSD について

ツールから Subversion リポジトリの操作には，SVNKit*3 をは 94/983(=9.6%) の修正パターンが複数のリビジョンに出用いている．マイニング処理では，更新されたファイルの現していた．これら 145 個と 94 個の修正パターンについ特定を行うために svn log コマンドを，リビジョン間の差分て，手作業でその修正内容を確認し*7 ，4 つのカテゴリに取得のために svn diff コマンドを用いている．しかし，diff*4

コマンドにより得られたコード片をそのまま用いると修
*5
*6
*3

http://svnkit.com/

c 2012 Information Processing Society of Japan*7

ここでの誤検出とは，修正漏れの指摘には役にたたない修正パ
ターンの意味である．
http://svn.apache.org/repos/asf/httpd/httpd/trunk/
http://svn.freebsd.org/base/head/sys/
著者らがリポジトリのログ，修正パターン周辺のコード，その後

4ソフトウェアエンジニアリングシンポジウム 2012

表1

対象ソフトウェアの概要

Table 1 Outline of target software

ソフトウェア

開始リビジョン (日付)

終了リビジョン (日付)

対象リビジョン数

終了リビジョンの総行数

HTTPD

81,442 (1998-06-02)

90,607 (2001-08-24)

2,784

131,675

FreeBSD

196,121 (2009-08-12)

225,533 (2011-09-14)

7,689

3,570,021

90,605	

write(c->fd,request,reqlen);	
deleted line	
if (posting) {	
if (posting>0) {	added line	
write(c->fd,postdata,postlen);	
totalposted += (reqlen + postlen);
	
} 	

	

呁
吪
吏
吾
呉

(a) HTTPD

83,343	
修正パターン	if (ste_newbuf(sc, cur_rx) != 0) {	
ifp->if_ierrors++;	
ifp->if_iqdrops++;	
cur_rx->ste_ptr->ste_status = 0;	
continue;	
} 	(a) HTTPD
225,533	

呁
吪
吏
吾
呉

deleted line	
added line	(b) FreeBSD	  図 4 最も長期間にわたって現れた修正パターンのソースコード

Fig. 4 Source code of modification patterns occuring longest period
196,121	
修正パターン	  していたことを表している．61 個の修正パターンがリファ(b) FreeBSD
図3

クタリングに分類された．大部分は関数名やマクロ名の変RQ1 で抽出した修正パターンの出現期間更であった．これらはソフトウェアの振る舞いに直接影響

Fig. 3 Occurrence periods of extracted modification patterns in RQ1 investigation

を与えるわけではないが，ソースコード中に一貫性のない
コード片が存在しているという点では望ましくない．19
個の修正パターンがコメントに分類された．全ての修正パ分類した（表 2）．各カテゴリについて説明する．

ターンは，著作権記述部分における西暦の修正漏れであっバグ修正 バグを取り除くための修正
リファクタリング リファクタリングのための修正．変数名の変更等の簡単な修正も含む
機能変更・機能追加 すでに実装された機能の変更や，新機能の追加のための修正
コメント ソースコード中のコメントに対する修正．主として著作権関係の記述のためた．著作権情報を正しく記述するという点では，これらも望ましくはない．
図 3 は，複数リビジョンに出現していた 145 個と 94 個の修正パターンの出現期間を表している．横軸には修正パ
ターンが並べられており，縦軸はリビジョンを表している．

Y 軸方向の線分の両端は，その修正パターンが現れる最初

42 個の修正パターンがバグ修正に分類された．これら

表 3 最も長期間にわたって現れた修正パターン

は，開発者がバグを取り除くために修正しなければならな(a) HTTPD

いコード片を見落としていたことを表している．117 個の

リビジョン

日付

修正されたファイル

修正パターンが機能変更・機能追加に分類された．これら

83,946

1999-10-08

support/ab.c (2 places)も必要な機能が正しく実装されていないリビジョンが存在

88,628

2001-04-02

support/ab.c(b) FreeBSD

表 2 RQ1 の調査で抽出した修正パターンの内訳

Table 2 Extracted modification patterns in RQ1 investigation
ソフトウェア

合計

HTTPD

145

FreeBSD

94

リビジョン

日付

修正されたファイル2009-12-25

sys/dev/ste/if ste.c

バグ

リファク

機能変更・

コメ

200,965

修正

タリング

機能追加

ント

213,438

2010-10-05

sys/dev/usb/net/usb ethernet.c

19

22

93

11

218,832

2011-02-19

sys/dev/dc/if dc.c

23

39

24

8

223,648

2011-06-29

sys/dev/gem/if gem.c

223,951

2011-07-12

sys/dev/cas/if cas.c (2 places)の修正の様子を調査した．

c 2012 Information Processing Society of Japan5

ソフトウェアエンジニアリングシンポジウム 2012のリビジョンと最後のリビジョンを表している．たとえば，FreeBSD（図 3(b)）の一番左に配置されている修正パ
ターンは，リビジョン 196,386 で最初に現れ，リビジョン

dump_avail[0] = phys_avail[0];	
dump_avail[1] = phys_avail[1] - phys_avail[0];	
dump_avail[1] = phys_avail[1];	
	
physmem = realmem;	

203,049 で最後に現れている．修正パターンは最初に現れれが含まれていることがわかる．具体的には，HTTPD の

92.7%，FreeBSD の 98.4%のリビジョンが該当する．

ap.fd = uap->fd;	
ap.offset = (uap->offsetlo | ((off_t)uap->offsethi << 32));	
ap.offset = PAIR32TO64(off_t,uap->offset);	
ap.len = (uap->lenlo | ((off_t)uap->lenhi << 32));	
return (posix_fallocate(td, &ap));	

修正パターンのコードを図 4 に，この修正パターンが出現したリビジョンの情報を表 3 に示す．HTTPD の修正パ
ターン（図 4(a)）では，if 文の条件式が変更されている．

if (port < 0) {	device_printf(ch->dev, "SATA connect timeout status=%08x\n",	
 deleted lines	
status);	
device_printf(ch->dev,	
"SATA connect timeout time=%dus status=%08x\n",	
added lines	
timeout * 100, status);	
} else {	FreeBSD の修正パターン（図 4(b)）では，インクリメント
する変数が変更されている．これら 2 つの修正パターンはバグ修正に分類された．いずれも軽微な変更ではあるが，最初の修正と最後の修正が一年半以上も離れている．
以上のことから，RQ1 に対して以下のように回答でき(c) 機能変更・機能追加/*-	* Copyright (c) 2005-2010 Pawel Jakub Dawidek pjd@FreeBSD…	
 deleted line	* Copyright (c) 2005-2011 Pawel Jakub Dawidek <pawel@daw…	
 added line	* All rights reserved.	
* 	(d) コメント

る：修正パターンのうちの 19.7%と 9.6%が複数のリビジョンに現れていた．また，これらの修正パターンは，対象リ
ビジョン群の 92.7%と 98.4%に存在していた．

deleted line	
added line	(b) リファクタリング

図 3 より，長期間にわたって出現するパターンも存在していることがわかる．最も長期間にわたって出現していた

added line	

(a) バグ修正

たリビジョンが早い順に並べられている．この図より，大部分の対象リビジョンにおいて，少なくとも 1 つの修正漏

deleted line	

図5

リビジョン 225,533 において見つかった修正漏れの例

Fig. 5 Examples of detected overlooked code fragments in revision
225,533

5.2 RQ2 に対する実験
マイニング処理で抽出した 737 個と 983 個の修正パターで追加されていた．また，このマクロはこのリファクタリンを用いて，HTTPD のリビジョン 90,607 と FreeBSD のリング漏れが検出されたファイルに定義されていた．よって，

ビジョン 225,533 から修正漏れコード片を検出した（提案

簡単に置換によるリファクタリングを行える．このコード手法の検出処理を行った）．その結果，HTTPD から 18 個，

片は，リビジョン 205,014 において実施したリファクタリ

FreeBSD から 94 個のコード片が検出された．これらすべング実施時に見落とされたと考えられる．

てのコード片を手作業により調査し，一致した修正パター

12 個の機能変更・機能追加漏れが検出された．図 5(c) はンの修正後コード片のように変更すべきかどうかを確認しその一例である．この修正パターンでは，タイムアウトにた*8 ．

なった処理時間を表示する機能が追加されている．修正パ

表 4 は，調査の結果を表している．15 個のバグ修正漏

ターンの修正後コード片で出現している変数 timeout は，れが検出された．図 5(a) はその一例である．この修正パ検出されたコード片では利用可能であるため，簡単に機能

ターンでは，配列の要素 dump avail[1] の計算方法が変更

追加を行える．

されている．修正パターンが現れたリビジョンのコミッ

3 つのコメント修正漏れが検出された．図 5(d) にその一トログには，“dump avail layout should be sequence of [start,

例である．この修正パターンでは，西暦と開発者のメール

end) pairs, not <start, size>.” と記載されており，この修正アドレスが古い情報のままであった．

パターンがバグ修正であることを表している．FreeBSD

また，27 個のコード片を誤って検出していた．これらのリビジョン 225,533 のファイル ar71xx machdep.c にはは，手作業による調査により意図的に修正を行なっていな“deleted line” に示す行が存在しており，この行は修正パいと判断された．

ターンの修正前コード片と一致するため，バグの修正漏れであると判断した．

以上のことから，RQ2 に対して以下のように回答できる：

HTTPD と FreeBSD から，16 個と 69 個の修正漏れを検出で55 個のリファクタリング漏れのが検出された．図 5(b)きた．HTTPD については 8,229 行あたりに 1 つ，FreeBSD

はその一例である．この修正パターンでは，シフト演算おについては 51,739 行あたり 1 つの修正漏れが存在していた

よび論理演算を行う式がマクロに変更されている．このマ計算になる．また，検出の精度は 88.8%と 73.4%であった．

クロは，この修正パターンを抽出したリビジョン 205,014*8

著者らがリポジトリのログ，修正パターン周辺のコード，その後の修正の様子から判断した．

c 2012 Information Processing Society of Japan

5.3 コードクローン検出ツールとの比較
2 節で述べたように，提案手法の目的はコードクローン

6ソフトウェアエンジニアリングシンポジウム 2012

表4

RQ2 の調査で検出した修正漏れ候補の内訳

Table 4 Detected overlooked code fragments in RQ2 investigation

ソフトウェア合計

HTTPD
FreeBSD

修正漏れと判断

誤検出数

精度

0

2

88.9%

3

25

73.4%

バグ修正

リファクタリング機能変更・機能追加

コメント

18

2

4

10

94

13

51

2

検出手法では検出できない修正漏れを検出することである．

ドクローンとして検出できなかったためである．

その目的が達成されているかを調査するために，コードク

FreeBSD の場合は，CCFinder は 38 個のリファクタリ

ローン検出ツールが RQ2 で検出した修正漏れコード片を

ング漏れを検出できた．これらは関数名が変更されたリ検出できるのかを調査した．この調査では，CCFinder とファクタリングであり，字句単位での修正漏れであるため，

Nicad を利用した．これらのツールの特徴を以下に述べる．

CCFinder では検出できた．一方，この部分の重複コードはCCFinder [2] 字句単位でコードクローンを検出するツー

ブロック内における割合が低かったために，Nicad では検ル．変数名や関数名等のユーザ定義名を置換した上で出できなかった．

コードクローンを検出するため，それらが異なってい表 6 はツールによって検出されたクローンセット*10 とるコード片でもコードクローンとして検出できる．つ

コードクローンの数を表している．2 つのツール共に多く

まり，字句レベルでの修正漏れを検出できる．

のコードクローンを検出した．しかし，表 5 に示すように，

関数単位やブロック単位*9 でコードクローン

修正漏れの多くを検出できなかった．この結果は，コードを検出するツール．Nicad は，LCS（Longest Common

クローンの検出ツールを用いて効率的に修正漏れを検出す

Sequence）アルゴリズムを用いて連続して字句が一致るのは難しいことを示唆している．

Nicad [5]

している部分を検出する．その一致部分が関数やブロック全体の一定以上の割合であれば，その関数やブロックがコードクローンとして検出される．つまり，

6. 議論
6.1 正規化について

Nicad は字句単位だけではなく，より大きな単位の不

現在の実装では，空白，タブ，改行文字を取り除く簡単

一致部分が含まれていてもコードクローンとして検出な正規化しか行っていない．そのため，用いている変数はできる．

異なるが処理内容自体は同じであるコード片を同値である

この実験では，デフォルトの設定を用いてコードクロー
ンを検出した．表 5 は，ツールによる修正漏れの検出結果と判定できない．よって，そのようなコード片に対しては修正漏れの指摘ができない．

を表している．CCFinder と Nicad 共に，提案手法が検出し全ての変数やリテラルを同一の特別な文字に置き換える

た修正漏れの大部分を検出できなかった．この理由は，修正規化を行えば，より多くの修正漏れを検出できるだろう．

正漏れの前後に十分な重複コードが存在しておらず，コー

しかし，そのような正規化を行うためには，ソースファイ
ル全体に対する構文解析を行う必要がある．現在は，svn

表5

CCFinder と Nicad により検出された修正漏れの数

diff コマンドを用いているため，各リビジョン間において差Table 5 Number of overlooked code fragments detected by CCFinderand Nicad

分の解析を行うコードの量は多くない．よって，大規模なシステムからでも短時間でマイニング処理を行える．全て(a) HTTPD
バグ

リファク

機能変更・

コメ

修正

タリング

機能追加

ント

16

2

4

10

0

2

0

0

2

0

手法

合計

提案手法
CCFinder
Nicad

2

0

0

2

表6

Table 6 Number of code clones detected by CCFinder and Nicad(a) HTTPD

0(b) FreeBSD
手法

*9

合計

バグ

リファク

機能変更・

コメ

修正

タリング

機能追加

ント

CCFinder と Nicad が検出したコードクローンの数

検出ツール

クローンセット数

コードクローン数

CCFinder

1,004

3,435

Nicad

117

324

(b) FreeBSD

提案手法

69

13

51

2

3

検出ツール

クローンセット数

コードクローン数

CCFinder

39

1

38

0

0

CCFinder47,016357,353

Nicad

2

1

1

0

0

Nicad

3,871

138,233

ここでブロックとは，if 文や while 文のように，関数内での構造的なまとまりのある部分を指す．

c 2012 Information Processing Society of Japan*10

コードクローンの集合．1 つのクローンセットに含まれる任意のコード片のペアは互いにコードクローンである．

7

ソフトウェアエンジニアリングシンポジウム 2012のリビジョンのソースファイルをチェックアウトして（手ウェアに対して実験を行った．その結果，多数のバグ修正

元にダウンロードして）構文解析を行うことも可能である

漏れ，リファクタリング漏れ，機能変更・機能追加漏れ，が，処理時間が著しく長くなってしまう．

コメント修正漏れを検出できた．今後は，システムの開発者に協力していただいて実験を行い，ツールの検出結果の6.2 手作業による確認作業
この実験では，著者らが検出された修正漏れの確認作業を行った．しかし著者らは対象システムの開発者ではないため，バグ修正やリファクタリング等への分類が誤ってい正しさをより正確に評価する予定である．また，コードの正規化を工夫し，検出の精度も高めていく予定である．

謝辞る可能性がある．より正確に手法を評価を行うためには，

本研究は，日本学術振興会科学研究費補助金基盤研究

対象システムの開発者に協力していただいて実験を行う必(A)(課題番号：21240002)，萌芽研究 (課題番号：23650014，

要がある．

24650011)，若手研究 (A)(課題番号：24680002) の助成を得た．

6.3 実験で用いたしきい値
本実験では，支持度，確信度，一致箇所数の 1 つの組み
合わせのみを修正漏れ検出のしきい値として用いた．例え

参考文献
[1]

ば，支持度を 2 にするなど，より緩いしきい値を用いることにより，さらに多くの修正漏れが検出される．この実験[2]

では著者らが検出された修正漏れを手作業で確認したが，著者らは対象システムの開発者ではないために，確認作業には長い時間を必要とした．RQ1 と RQ2 で検出された修[3]

正漏れを確認するために要した時間は約 20 時間であり，これ以上検出数が多い場合には手作業による確認が困難であった．対象システムの開発者がこの確認作業を行った場[4]

合には，検出された修正漏れの真偽を素早く判断できるだ
ろう．
[5]

6.4 比較対象ツール
この実験では，CCFinder と Nicad のデフォルトの設定を用いてコードクローンを検出した．しかし，検出する最小

泉田聡介，植田泰士，神谷年洋，楠本真二，井上克郎：ソフトウェア保守のための類似コード検索ツール，電子情報通信学会論文誌， Vol. 86-D-I, No. 12, pp. 906–908 (2003).
Kamiya, T., Kusumoto, S. and Inoue, K.: CCFinder: A Multilinguistic Token-Based Code Clone Detection System forLarge Scale Source Code, IEEE Transactions on Software Engineering, Vol. 28, pp. 654–670 (2002).
Li, Z., Lu, S., Myagmar, S. and Zhou, Y.: CP-Miner: Finding
Copy-Paste and Related Bugs in Large-Scale Software Code,IEEE Transactions on Software Engineering, Vol. 32, pp. 176–
192 (2006).
森崎修司，吉田則裕，肥後芳樹，楠本真二，井上克郎，佐々木健介，村上浩二， 松井恭：コードクローン検索による類似不具合検出の実証的評価，電子情報通信学会論文誌
D， Vol. J91-D, No. 10, pp. 2466–2477 (2008).
Roy, C. K. and Cordy, J. R.: NICAD: Accurate Detection of
Near-Miss Intentional Clones Using Flexible Pretty-Printing
and Code Normalization, Proceedings of the 2008 The 16th
IEEE International Conference on Program Comprehension,
ICPC ’08, pp. 172–181 (2008).

のコードクローンの大きさなどの設定を変更することで検出結果は異なるため，それらのツールがより多くの修正漏れを検出できる可能性がある．また，この実験では，提案手法が検出した修正漏れをコードクローン検出ツールが検出可能か調査したのみである．しかし，提案手法では検出されないが，コードクローン検出ツールでは検出される修正漏れも存在するだろう．なぜなら，提案手法は，過去に同様の修正が行われていることを必要とするが，コードク
ローン検出ツールは必要としないからである．つまり，本実験の結果と合わせると，提案手法とコードクローン検出
ツールは相補的な関係にあるといえる．

7. おわりに
本論文では，ソースコード中から修正漏れを自動的に検出する手法を提案した．提案手法は，対象ソフトウェアの開発履歴情報を用いているため，検出されるためにはある
程度以上の大きな重複コードでなければならない，という既存手法の弱点を持たない．
提案手法をツールとして実装し，オープンソースソフト

c 2012 Information Processing Society of Japan

8