玩式草子─ソフトウェアとたわむれる日々

第3回みんなでテスト、みんなでデバッグ。あるいはLinusの法則

前回紹介したfile-rollerのデバッグでは、ソースコードにデバッグ用のメッセージを追加しながら動作を逐一追いかけてみました。最近ではgdb(GNU debugger)DDD(Data Display Debugger)などの便利なデバッグ用ツールやEclipseのような統合開発環境もあり、デバッグ作業もずいぶん便利になりましたが、⁠デバッグ」という作業がソフトウェアの振舞いを地道に追いかける孤独な作業であることは変わりありません。

一方、最近ではインターネット上に膨大な情報が蓄積されており、Google等で検索すれば、たいていのバグはすでに報告され、パッチ等の対策も提案されており、一人でコツコツとソースコードを追いかける必要はほとんど無くなっていることも事実です。

今回はそのような例として、totemのYouTube検索モジュールのトラブル対策の例を紹介しましょう。

totemのYouTube検索モジュール

totemはGNOMEデスクトップ環境の標準的なマルチメディアプレイヤーで、GStreamerを用いてさまざまな形式の動画・音声ファイルに対応しています。

GStreamerは、統一したAPIでさまざまな形式のファイルを処理できるように設計されたマルチメディアフレームワーク(ライブラリ集)で、プラグイン形式で新しいフォーマットを追加できるようになっています。

totem は以前からさまざまな形式のファイルに対応していて便利だったのですが、GNOME-2.26に含まれている totem-2.26 系では totem 自身にさまざまな機能を追加できるプラグイン機能が装備されました。

その中でも便利だな、と思ったのがYouTubeの動画ファイルを閲覧できる機能です。この機能は ⁠編集⁠⁠→⁠plugin]から[YouTube ブラウザ]を選択することで利用可能になります。この機能を使えば、サイドバーのYouTubeコラムからキーワード検索もできますし、ある動画に関連づけられた動画を芋づる式に見てゆくことも可能です。

図1 totemでYouTubeの動画が見えている例
図1 totemでYouTubeの動画が見えている例

この機能を使えば、ブラウザを起動しなくてもYouTube上の動画を見ることができて便利なので、⁠Plamo-4.7の新機能」に紹介してもいいな、と思っていましたが、ある時期から急にYouTubeにアクセスできなくなりました。

厳密に言うと、YouTubeにアクセスしてキーワードから動画を検索することはできるものの、見つかった動画を再生しようとすると「エラーが発生しました」というメッセージが表示されます。totemを起動したターミナルにも"Not Found"なエラーが表示されています。

図2 ある日、totemでYouTubeを見れなくなった。
図2 ある日、totemでYouTubeを見れなくなった。

当初はYouTubeにメンテナンスでも入っているのかな、と思って放置していましたが、数日経っても復旧しないようなので、少し調べてみることにしました。

トラブル状況の確認

トラブル解決の第一歩は、どのような問題が起きているのかをできるだけ正確に把握することです。今回のように YouTube というインターネット上のサービスを利用する際に生じた問題では、原因がこちら側にあるのか、サーバの側にあるのか、あるいは途中のネットワーク接続にあるのか、さまざまな可能性を考慮しなければなりません。

原因把握の一例として、今回のトラブルで「あれれ?」と思った時に、私が頭の中で考えたことを、やや誇張ぎみですが自問自答風に紹介してみましょう。

  • 「ネットワークの問題?」
    「いや、他のWebアプリもメールも読めているからネットワークではないだろう」

  • 「YouTubeの側の問題?」
    「可能性はある。totem以外でどうなるかを調べないと」

  • 「Pythonの問題?」
    「Python-2.6に更新した影響はありうるが、他は問題ないので可能性は低そう」

  • 「GNOME環境の問題?」⁠GNOMEというよりはGStreamerのレベルだろうな。GStreamの新しいの出てたかな?」

  • 「totem自身の問題?」
    「totem を更新したのはいつだっけ?」

  • 「設定ファイルの問題?」
    「totemが参照している設定ファイルに古い情報が残っていたりするのかな?」

  • 「キャッシュの問題?」
    「以前にアクセスした際のキャッシュがイタズラしてるのかな?」

ここではざっと7つほど可能性を考えてみました。トラブル調査の最初の段階では、思いつく限りの可能性を考えておくことが重要になります。この段階で特定の可能性のみに固執してしまうと視野狭窄におちいって、目の前にある事実が見えなくなったり、事実をねじまげて都合よく解釈してしまうことすらあります。

トラブルの原因となる可能性をさまざまに考えると共に、それらを検証する方法も考えていきます。YouTube側の問題かどうかは、totem以外のブラウザでどうなるかを確認すべきでしょう。設定ファイルやキャッシュの問題は自分のホームディレクトリ下に残っているそれらのファイルを消して再起動すれば確認できるでしょう。一方、PythonやGStreamerの問題は、パッケージのバージョン等を調べたり、インストールやバージョンアップした時期、新しいバージョンの有無を確認する必要もあるので後回しにしておきましょう。

合わせてtotem自身が出力しているエラーメッセージも確認しておきます。図2のようにコンソール(端末)ソフトウェアから⁠totem⁠というコマンドを直接起動してやると、totem自身が表示する「エラーが発生しました。場所を開けませんでした(そのファイルを開く権限がありません)。」というメッセージ以外にも

% totem
/usr/lib/python2.6/site-packages/gdata/tlslite/utils/cryptomath.py:9: DeprecationWarning: the sha module is deprecated; use the hashlib module instead
  import sha
** Message: Error: "http://www.youtube.com/get_video?video_id=hqH43tDiHjE&t=vjVQa1PpcFNgUxX5nlJZ9DZyEmTCbTr79SR0l8R_SWY%253D": Not Found
gstsouphttpsrc.c(1084): gst_soup_http_src_parse_status (): /GstPlayBin:play/GstSoupHTTPSrc:source:
404 Not Found

というエラーメッセージが表示されていることがわかります。

メッセージの前半はモジュールが古くなっていることの警告なので無視してもよさそうですが、後半のYouTube上の動画ファイルのURIが見つからない旨のメッセージは、今回のトラブルの直接原因と考えてよさそうです。

指定された URI が見つからない、というのは YouTube 側の問題のような印象が強いですが、gst_soup_http_src_parse_status() がエラーになっているのを見ると GStreamer や libsoup がらみの可能性も捨て切れないところです。

さまざまな可能性(仮説)を考えたら、どれが正しいかを実験(テスト)しながら絞りこんで行きます。

原因の絞り込み

まずYouTube側の問題かどうかを確認するために、firefox-3.5.3 + flashplayerプラグインでYouTubeに接続し、totemでエラーになった動画を表示させてみたところ、特に問題なく表示されました。どうやらYouTube側の問題ではなさそうです。

図3 firefox+flashplayerでYouTubeを見ている例
図3 firefox+flashplayerでYouTubeを見ている例

次に、totemが使う設定ファイルやキャッシュファイルを消してみます。

totemに限らず、Linux/UNIX用のたいていのアプリケーションでは、ユーザのホームディレクトリに設定用のファイルやディレクトリを保存しています。これらのファイルやディレクトリは先頭に "."(ピリオド)を付けた隠しファイルやディレクトリとして配置されるので、存在を確認するにはls-aオプションやファイルマネージャのオプション設定で「隠しファイルを表示」させる必要があります。

どこにあるかよくわからない隠しファイルをコマンドラインで消すのはちょっとメンドウですし、GUI環境用の設定ファイル類をGUI環境の中からイジるのも少々気持ち悪いところです。このような作業の場合、手元ではFDというCUI版のファイルマネージャをよく使います。

図4 ターミナルソフトウェア上のFD
図4 ターミナルソフトウェア上のFD

FDは、昔日のMS-DOS用のツールをモデルに開発されたファイルマネージャで、見た目こそ地味ですが、ターミナル上で利用できるのでリモートマシンのメンテナンスにも便利だし、ファイルを一覧しながら操作できるので、この種の作業には最適です。

今回は~/.config/totem/~/.gconf/apps/totem/を削除し、合わせて多少関係するかと思って~/.gstreamer-0/~/.thumbnails/などのディレクトリを消してみましたが、totemのエラーは変りませんでした。

その他、GStreamerを調べてみると新しいバージョンが出ていたのでパッケージ化して更新したり、HTTPのサーバ/クライアント機能を実装したlibsoupのバージョンをチェックしてみたりと、思いついた可能性をさまざまに検証してみましたが解決せず、どうやらtotem自身の問題だろう、というところにまで絞り込めてきました。

インターネットでの調査

ある程度問題点が絞り込めてきたので、"totem" "gst_soup_http_src_parse_status()" "404 Not Found"をキーワードにGoogleで調べてみました。

最近では、⁠エラーが出たらまずググれ」とばかりに、エラーメッセージをGoogleで直接検索するような例がよく紹介されていますが、個人的な経験では、ある程度可能性を推測した上で検索する方が、必要な情報を効率よく見つけることができるようです。自分の探しているものが何なのかを知らないと、たとえGoogleが優れた検索結果を返してくれても、そこから必要な情報を選り分けるのにむしろ時間がかかりがちです。

Googleの検索結果に示されたページを見ると、⁠YouTube側がインターフェイスをイジったのでは?」⁠プレイリスト機能が関係しそう」⁠むしろ無線LANが問題っぽい」等々、情報が錯綜していましたが、9月の上旬に調べた際は、Ubuntu等の環境でも同じ問題が発生しており、バグ情報のページにもこの問題が登録されていることがわかっただけでした。

前回紹介したfile-rollerのように、特定の環境(ファイルシステムのlocaleがGTK/GDKの内部表現であるUTF-8と異なる環境)でしか発現しない問題はその環境のユーザ自身が何とかしないと解決しませんが、今回の問題は特定の環境に依存する類いのものではなさそうなので、とりあえずしばらく様子を見ることにしました。

YouTube が見れないのは残念だけど、totem自身が動かないわけではないのだし……。

しばらく Plamo Linux 4.7 のリリースに向けた作業で忙しい日々が続き、10日ほど経ってから改めて検索したところ、Ubuntuのバグ情報のページに以下のような投稿がありました(なお、この記事中の"forward slash"は"%"の間違いだった、と投稿者自身が修正投稿しています⁠⁠。

lightpriest  wrote on 2009-09-15:  	  #10

    * Patch to totem-plugins-2.26.1-0ubuntu5/youtube.py (565 bytes, text/plain)

This problem apparently because youtube uses a forward slash in their
"t" param.  On the youtube.py (the plugin itself), the url is built
with a urllib.quote of pythin which escapes this forward slash with a
%25.  I guess gst's API shouldn't "unescape" these URL's and this is
a youtube plugin bug.

I've noticed this plugin was replaced with a C one (in gnome's git
repo) and they had the same escape method there.

Attached a suggested patch.

この報告によると、totemのYouTube用プラグインが、本来クォートすべきでないパラメータを余計にURIクォートしているのが原因、とのことです。添付されたパッチで修正するのは1ヵ所のみで、動画ファイルの位置を示す mrl を生成する際に &t= で渡すパラメータをurllib.quote() しないように変更する、というものでした。

337c337
< 			mrl = "http://www.youtube.com/get_video?video_id=" + urllib.quote (youtube_id) + "&t=" + urllib.quote (t_param) + self.get_fmt_string ()
---
> 			mrl = "http://www.youtube.com/get_video?video_id=" + urllib.quote (youtube_id) + "&t=" + t_param + self.get_fmt_string ()

さっそく手元でも/usr/lib/totem/plugins/youtube/youtube.pyにこの変更を加えてみたところ、再びtotemからYouTubeの動画が見れるようになりました。

図5 totemからYouTubeへの接続が復活
図5 totemからYouTubeへの接続が復活

確か8月の上旬くらいまではurllib.quote()していた古いコードでも見えていたはずなのに、なぜ急に見えなくなったのかは釈然としませんが、そのあたりは恐らくYouTube側の問題なので、外部からあれこれ推測しても無駄でしょう。

とりあえずこの修正を適用してPlamo-4.7用のtotemパッケージを修正、更新することにしました。

インターネットとLinusの法則

Linuxの急速な成長と発展を分析し、⁠伽藍とバザール」という論文にまとめたエリック・レイモンドは、⁠Linusの法則」としてこう述べています。

“given enough eyeballs, all bugs are shallow”

(目玉の数さえ十分あれば、あらゆるバグは解決可能)

事実、Linux はこの法則に従って、ソフトウェア工学の伝統的な常識を打ち破って成長してきました。Linuxが広めた開発スタイルは「バザールモデル」として認知され、⁠Web2.0」的な考え方とともに、ユーザ参加型の開発スタイルとしてさまざまな場面で利用されるようになってきました。

今回はUbuntuのバグ報告システムで解決できましたが、バグ報告システムのような形式を取らなくても、最近では世界中の開発者が自らのブログでオープンソースソフトウェア(OSS)のさまざまな問題を分析、報告し、解決方法を紹介してくれています。それらの情報は、Google等の検索エンジンによって休むことなく収集、整理され、膨大なデータベースとして利用できるようになっています。OSSの世界では、インターネットを通じて世界中の無数の目玉がソースコードを見つめて、日夜テストやデバッグにいそしんでいる、と言っても過言ではないでしょう。

現実世界では決して触れあう機会のないどこかの誰かが、自分と同じ問題に苦しんでいたり、自分では気づかなかった解決策を報告してくれてたりするのを見ると、時間と空間を超えた不思議な親近感を感じてしまいます。

この大海のような知を使わせてもらうお礼に、自分の知を一滴なりとも加えることができれば……と、サボりがちなブログの更新に向けて自らを叱咤している今日このごろです。

おすすめ記事

記事・ニュース一覧