Linuxに代表されるオープンソースソフトウェア(OSS)は,文字通りソースコードを公開していることが最大の特徴です。ソースコードが企業秘密のベールに覆われている伝統的な商用ソフトウェアでは,ソースコードにアクセスできる開発者とコンパイル済みのバイナリファイルしか利用できないユーザは厳格に区別され,ユーザがソフトウェアに不具合を見つけても,開発者がそれに対応してくれるまでは指をくわえて待つしかありませんでした。
一方,ソースコードが公開されているOSSの世界では,ユーザと開発者がソースコードという同じ土俵の上で互いに切磋琢磨することができます。今回はそのような例として,ソースコードの不具合を見つけて修正した例を紹介しましょう。
今回取りあげるソフトウェアはfile-rollerという GNOME用の書庫ソフトウェアです。
file-rollerとは
file-roller とは,GNOMEデスクトップ環境で標準となっている書庫ソフトウェアです。
書庫ソフトウェアとは,複数のファイルを一つにまとめて圧縮した書庫(アーカイブ)ファイルを操作するためのソフトウェアで,file-roller はLinux環境で標準的な tar.gz(tar+gzip),tar.bz2(tar+bzip2)といった形式だけではなく,Windowsで標準的なzipやrarの形式にも対応した,高機能な書庫ソフトウェアです。
file-rollerはGNOME環境の標準的な書庫ソフトウェアで,書庫ファイルのアイコンをダブルクリックすると自動的に起動され,そのファイルの中身を表示してくれます。しかしながら,Windowsなユーザから流れてきたファイル名が日本語になっている書庫ファイルを,GNOMEのファイルマネージャであるnautilus経由で開こうとすると,「ファイルが見つからない」旨のエラーになってしまいます。
もう少し具体的なエラーメッセージが表示されないかと,コマンドラインからfile-rollerを起動しても同じ結果になりました。一方,同じファイルを英語名にシンボリックリンクしたり,file-rollerをあらかじめ起動しておいて,メニューから書庫ファイルを指定して開いてみると,日本語のファイル名を持つ書庫ファイルも問題なく開けるようです。
書庫ファイル名が日本語でなければ大丈夫そうなのでLinux環境だけで使う場合はそれほど困らないし,いったん file-roller を起動してからファイル名を指定すれば日本語のファイル名でも開けるのでそれほど致命的な問題ではなさそうですが,Windowsな環境とファイルをやりとりする際にファイルマネージャから直接file-rollerを使えないのは不便です。そこで,なぜ日本語のファイル名を持つファイルが開けないのかを調べてみることにしました。
ソースファイルの構成調査
ソフトウェアの不具合を調べる作業をデバッグ(de-bug)と言います。
デバッグでは,どのような条件で,どのような現象が生じているかをきちんと把握することが重要で,さまざまな状況証拠を積みあげて問題箇所を見つけ出すには,推理小説に出てくる探偵のような推理力が必要になります。
ソースコードのないバイナリファイルはブラックボックスのようなもので,内部でどのような処理をしているかは入出力の関係から推測するしかありませんが,ソースコードも手に入るOSSでは,実際の処理の流れを追いかけて問題点を特定することができます。しかしながら,最近の多機能化したソフトウェアではソースコードも大規模になっており,ソースコードを追いかけるのもかなり大変です。今回扱おうとしているfile-rollerも,ソースコードに含まれているファイルは413,全体で11Mバイトほどもあります。
このような規模のソースコードを追いかける場合,いかに効率よく問題箇所を絞り込むかが重要で,そのためにはさまざまな視点からソースコードを見ていく必要があります。
まず,file-rollerのソースコードの構成を見てみましょう。
% ls
AUTHORS MAINTAINERS TODO configure* file-roller.spec intltool-extract.in mkinstalldirs*
COPYING Makefile.am aclocal.m4 configure.ac file-roller.spec.in intltool-merge.in nautilus/
ChangeLog Makefile.in config.guess* copy-n-paste/ gnome-doc-utils.make intltool-update.in po/
HACKING NEWS config.h.in data/ help/ ltmain.sh* src/
INSTALL README config.sub* depcomp* install-sh* missing*
実際のソースコードはsrc/以下のディレクトリにありそうなので,このディレクトリの中身を見てみます。
% ls src
Makefile.am dlg-prop.c fr-command-cfile.c fr-command.c glib-utils.h
Makefile.in dlg-prop.h fr-command-cfile.h fr-command.h gtk-utils.c
actions.c dlg-update.c fr-command-cpio.c fr-enum-types.c gtk-utils.h
actions.h dlg-update.h fr-command-cpio.h fr-enum-types.h java-utils.c
dlg-add-files.c eggtreemultidnd.c fr-command-iso.c fr-error.c java-utils.h
dlg-add-files.h eggtreemultidnd.h fr-command-iso.h fr-error.h main.c
dlg-add-folder.c file-data.c fr-command-jar.c fr-list-model.c main.h
dlg-add-folder.h file-data.h fr-command-jar.h fr-list-model.h mkdtemp.c
dlg-ask-password.c file-utils.c fr-command-lha.c fr-marshal.c mkdtemp.h
dlg-ask-password.h file-utils.h fr-command-lha.h fr-marshal.h open-file.c
dlg-batch-add.c fr-archive.c fr-command-rar.c fr-marshal.list open-file.h
dlg-batch-add.h fr-archive.h fr-command-rar.h fr-process.c preferences.c
dlg-delete.c fr-command-7z.c fr-command-rpm.c fr-process.h preferences.h
dlg-delete.h fr-command-7z.h fr-command-rpm.h fr-stock.c sexy-icon-entry.c
dlg-extract.c fr-command-ace.c fr-command-tar.c fr-stock.h sexy-icon-entry.h
dlg-extract.h fr-command-ace.h fr-command-tar.h fr-window.c sh/
dlg-new.c fr-command-alz.c fr-command-unstuff.c fr-window.h typedefs.h
dlg-new.h fr-command-alz.h fr-command-unstuff.h gconf-utils.c ui.h
dlg-open-with.c fr-command-ar.c fr-command-zip.c gconf-utils.h
dlg-open-with.h fr-command-ar.h fr-command-zip.h gio-utils.c
dlg-password.c fr-command-arj.c fr-command-zoo.c gio-utils.h
dlg-password.h fr-command-arj.h fr-command-zoo.h glib-utils.c
このディレクトリに限ればCのソースコード(拡張子が .c のファイル)が50,ヘッダファイル(拡張子が .h のファイル)が52ほどあります。果してこれらのファイルのどこに問題が潜んでいるのでしょうか?
まず,上記のsrc/以下のファイルの名前を見ると,これらのファイルはdlg-XXXというグループとfr-XXXというグループ,それ以外のグループの3種に分かれてることに気づきます。それぞれのグループのファイル名を詳しく見てみると,dlg-XXX系のファイルはadd-filesとかask-password,deleteといった操作コマンドの系列のようです。ということは,接頭辞のdlgはdialogの略で,どうやら各種操作の時のダイアログ・ボックスを作る処理をしてそうです。
一方,fr-XXX系のコマンドのほとんどはfr-command-XXで,commandの後ろはarとかlha,tar,zipといった圧縮コマンドが並んでいるので,これらはファイルの圧縮形式に応じた処理を担っているのでしょう。
今回のトラブルは,file-rollerの起動時に引数として指定した日本語ファイル名の処理がうまくいかない,というものなので,ダイアログボックス経由の操作や,それぞれの圧縮形式の操作用のファイルは無関係でしょう。それらのファイルを除外すると,対象となるファイルは絞り込めそうです。
dlg-XXXやfr-command-XXXというファイルを除いて,ファイル処理に関連しそうな名前のファイル(file-utils.cやopen-file.cなど)を眺めてみましたが,それぞれのファイルで定義されている関数は小さな機能に分割されており,なかなか処理の流れはつかめません。
そこで少し視点を変えて,エラーメッセージが出力されている場所から探してみることにしました。

