Linuxに代表されるオープンソースソフトウェア
一方、
今回取りあげるソフトウェアはfile-rollerという GNOME用の書庫ソフトウェアです。
file-rollerとは
file-roller とは、
書庫ソフトウェアとは、
file-rollerはGNOME環境の標準的な書庫ソフトウェアで、

もう少し具体的なエラーメッセージが表示されないかと、

書庫ファイル名が日本語でなければ大丈夫そうなのでLinux環境だけで使う場合はそれほど困らないし、
ソースファイルの構成調査
ソフトウェアの不具合を調べる作業をデバッグ
デバッグでは、
ソースコードのないバイナリファイルはブラックボックスのようなもので、
このような規模のソースコードを追いかける場合、
まず、
% 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のソースコード
まず、
一方、
今回のトラブルは、
dlg-XXXやfr-command-XXXというファイルを除いて、
そこで少し視点を変えて、
メッセージ出力箇所の調査
今回出力されているメッセージは図1のように
ソフトウェアが出力するメッセージは全てソースコードの中に書かれています。そのため、
国際化機能に対応したソフトウェアでは、
ソースコードをコンパイルすると、
それではこのja.
# file-roller ja.po.
# Copyright (C) 2001-2009 Free Software Foundation, Inc.
# Takeshi AIHANA <[email protected]>, 2001-2009.
#
msgid ""
msgstr ""
"Project-Id-Version: file-roller trunk\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2009-02-22 10:38+0900\n"
"PO-Revision-Date: 2009-02-22 10:28+0900\n"
"Last-Translator: Takeshi AIHANA <[email protected]>\n"
"Language-Team: Japanese <[email protected]>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: ../copy-n-paste/eggdesktopfile.c:165
#, c-format
msgid "File is not a valid .desktop file"
msgstr "妥当な .desktop ファイルではありません"
#: ../copy-n-paste/eggdesktopfile.c:188
#, c-format
msgid "Unrecognized desktop file Version '%s'"
msgstr "バージョン '%s' の .desktop ファイルはサポートしていません"
このように、
#: ../src/fr-archive.c:1225
#, c-format
msgid "The file doesn't exist"
msgstr "ファイルが見つかりませんでした。"
...
#: ../src/fr-window.c:2908
#, c-format
msgid "Could not open \"%s\""
msgstr "\"%s\" を開けませんでした"
この結果から、
src/
1217 static void
1218 copy_remote_file (FrArchive *archive,
1219 const char *password)
1220 {
1221 XferData *xfer_data;
1222
1223 if (! g_file_query_exists (archive->file, NULL)) {
1224 GError *error;
1225 error = g_error_new (G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("The file doesn't exist"));
1226 fr_archive_copy_done (archive, FR_ACTION_LOADING_ARCHIVE, error);
1227 g_error_free (error);
1228 return;
1229 }
src/
2917 case FR_ACTION_LOADING_ARCHIVE:
2918 dialog_parent = window->priv->load_error_parent_window;
2919 utf8_name = g_uri_display_basename (window->priv->archive_uri);
2920 msg = g_strdup_printf (_("Could not open \"%s\""), utf8_name);
2921 g_free (utf8_name);
2922 break;
このコードを眺めると、
po/
これらのファイルの名前がどうなっているかを調べるために、
1221 XferDataxfer_data;
1222
1223 printf("my_debug/fr-archive.c: archive->file:%s\n", archive->file);
1224 if (! g_file_query_exists (archive->file, NULL)) {
2919 utf8_name = g_uri_display_basename (window->priv->archive_uri);
2920 printf("my_debug/fr-window.c: utf8_name:%s\n", utf8_name);
2921 msg = g_strdup_printf (_("Could not open \"%s\""), utf8_name);
デバッグメッセージを追加したソースコードをコンパイルし直して、

コマンドは2度実行しており、
この結果を見ると、
そこで、
関数の呼び出し関係の追跡
まず、
% grep 'copy_remote_file ' *.c
fr-archive.c:copy_remote_file (FrArchive *archive,
fr-archive.c: copy_remote_file (archive, password);
この結果を見ると copy_
1255 gboolean
1256 fr_archive_load (FrArchive *archive,
1257 const char *uri,
1258 const char *password)
1259 {
1260 g_return_val_if_fail (archive != NULL, FALSE);
1261
1262 g_signal_emit (G_OBJECT (archive),
1263 fr_archive_signals[START],
1264 0,
1265 FR_ACTION_LOADING_ARCHIVE);
1266
1267 fr_archive_set_uri (archive, uri);
1268 copy_remote_file (archive, password);
1269
1270 return TRUE;
1271 }
この部分にもprintf()文を入れて調べると、
リストは省きますが、
907 int i = 0;
908 while ((filename = remaining_args[i++]) != NULL) {
909 GtkWidget *window;
910 GFile *file;
911 char *uri;
912
913 window = fr_window_new ();
914 gtk_widget_show (window);
915
916 file = g_file_new_for_commandline_arg (filename);
917 uri = g_file_get_uri (file);
918 fr_window_archive_open (FR_WINDOW (window), uri, GTK_WINDOW (window));
919 g_free (uri);
このコードを見ると、
917 uri = g_file_get_uri (file);
918 printf("my_debug/main.c: filename:%s, file:%s, uri:%s\n", filename, file, uri);
919 fr_window_archive_open (FR_WINDOW (window), uri, GTK_WINDOW (window));
再度コンパイルし直して動かしてみると、

Google等で調べると、
出力結果にfileは正しく表示されていませんが、
ここで気になるのはfilenameがUTF-8形式で表示されていることです。g_
Creates a GFile with the given argument from the command line. The value of arg can be either a URI,
an absolute path or a relative path resolved relative to the current working directory. This operation
never fails, but the returned object might not support any I/O operation if arg points to a malformed path.
この関数が引数に取るのはURIか絶対パス、
どうやらファイル名のエンコーディングの扱いに齟齬が生じている気配なので、
916 gchar *tmpname = g_filename_from_utf8(filename, -1, NULL, NULL, NULL);
917 file = g_file_new_for_commandline_arg (tmpname);
918 uri = g_file_get_uri (file);
919 printf("my_debug/main.c: filename:%s, file:%s, tmpname:%s, uri:%s\n", filename, file, tmpname, uri);
920 fr_window_archive_open (FR_WINDOW (window), uri, GTK_WINDOW (window));
UTF-8化されているfilenameをg_
g_
このように修正すると、

どうやら今回のバグは、
後日談
これらの内容を簡単に整理してPlamo Linuxのメンテナ日記に書いてみたら、
改めてmain.
173 static const GOptionEntry options[] = {
174 { "add-to", 'a', 0, G_OPTION_ARG_STRING, &add_to,
175 N_("Add files to the specified archive and quit the program"),
176 N_("ARCHIVE") },
177
178 { "add", 'd', 0, G_OPTION_ARG_NONE, &add,
179 N_("Add files asking the name of the archive and quit the program"),
180 NULL },
181
182 { "extract-to", 'e', 0, G_OPTION_ARG_STRING, &extract_to,
....
198 { "force", '\0', 0, G_OPTION_ARG_NONE, &ForceDirectoryCreation,
199 N_("Create destination folder without asking confirmation"),
200 NULL },
201
202 { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &remaining_args,
203 NULL,
204 NULL },
205
206 { NULL }
207 };
ここで"add-to"や"extract-to"はfile-roller コマンドに与えることができるオプションパラメータです。それらあらかじめ指定されたオプション以外の部分は、
一方、
そこで、
結論として、
今回の記事だけを見れば、
先にデバッグ作業には探偵のような推理力が必要と述べましたが、
デバッグ作業は、
与えられたソフトウェアを、