12月11日~13日、ベルサール汐留にて「RubyKaigi 2015 」が開催されました。今年も基調講演が毎日一つずつ行われました。その模様をレポートします。
RubyKaigi 2015 2日目の基調講演は、世界で唯一の、LinuxのコミッタでありRubyのコミッタでもある小崎資広 さんです。今回、小崎さんは「Linux loves Ruby. Ruby Loves Linux - How to debug your linux box」と題して、発表しました。
Linux portメンテナのお仕事
小崎さんは、Ruby Core Teamでの自分の役割を「Linux Portメンテナ」と称し、これまでの仕事の内容を紹介しました。
Linux Portメンテナは、Rubyのバグ管理サイトにLinuxに関するバグが登録されたきに活躍するそうです。
TCPをcloseしたソケットにselectするとGNU/LinuxのみでRubyがハングする というバグが登録されたときは、Rubyを直すのではなくLinuxのカーネル開発者側にコードの変更をお願いしたそうです。「 1アプリケーションであるRubyの挙動のために、何故カーネル側を修正しないといけないのか」という意見も出たようですが、無事修正されました。
また、RubyはLinuxの新しいファイルシステムのデバッグにも役だったと話します。これは、Rubyの本体にはテストコードが豊富に書かれているため、Rubyのテストが新しいファイルシステムでは動かないということがあったためだそうです。
このように、Rubyのようなアプリケーション開発陣が、Linuxカーネルの挙動に対して意見を言うというのはLinuxカーネルコミュニティにとってよい影響を与えると説明しました。
もしアプリケーションのバグがカーネルの挙動のため発生したときに、アプリケーション開発陣がカーネルの挙動を避けるために場当たり的な処置ばかりをいれられてしまうと、カーネルの開発を進める際にそのアプリケーションの挙動を守るためにコードが書き辛くなってしまいます。そのため、場当たり的な処置をいれるより、フィードバックを返してくれたほうがよいとのことです。
OSSにパッチを送るのはテトリスのようにやる
小崎さんの同僚は「OSSにパッチを送り、いれてもらうのはテトリスのようなもの」と述べているそうです。
その理由は、問題を一度に片付けれる大きな固まりとなっているパッチや、きたないパッチは問題を解決できるからといって取り込まれることは少ないそうです。しかし、テトリスのように小さいピースを少しずつ積んでいき、最後に綺麗に全体を消すやり方、つまり問題を分割して一個一個丁寧に議論と綺麗なパッチを重ね大きな問題を解決するというやり方が好まれると言います。そしてこれは、OSSだけでなく、一般的にどこでも通用する考え方だと、小崎さんは述べています。
Linux のデバッグツール
さて、Linuxコミッタでもある小崎さんはRubyistがたくさんいる会場で、Linuxのデバッグツールを紹介し布教したいと言い、次の3つのツールを紹介しました。
Ftrace
perf tools
SystemTap
これらのツールを紹介している際、小崎さんはなぜ今回デバッグのツールを紹介するのか、その理由を次のように話しました。
「デバッグという作業は何も生産しないためすぐ終わるべきだが、この作業は慣れと直感で作業する人が多い。その人依存になってしまうのはよいことではないため、人に依存しない道具の使い方を知ってほしい」( 小崎さん)
Ftrace
今回紹介したツールの中でFtraceが一番使いやすく、簡単なツールです。Ftraceを使うと、すべてのプロセスで発生するカーネルでのイベントを取得できるそうです。使い方は簡単で、sysfs上の特定のファイルに1を書き込むことでFtraceによるロギングが可能になります。Red Hat Enterprise Linux 7では、Ftraceで取得できるイベントが1,500程度用意されているそうです。
Ftraceは、一度有効にするとずっとログを取得しつづけるそうです。Ftraceのログが書き込まれるバッファは、リングバッファとなっており一定の量が書き込まれると、古いものが消えていくようになる仕組みになっています。そのため、Linuxやアプリケーションがクラッシュすることはなく、スローダウンが発生するような状況のデバッグに有効だと言います。
Ftraceの使い方は、作者のSteven Rostedtが作成した入門ガイド がとても詳しいと薦めていました。
perfコマンド
2つ目のツールとして挙げたperfは、マシンのパフォーマンスについて様々な情報を取得できるコマンドです。いくつかのサブコマンドが実装されています。
まず紹介したのはperf topです。perf topは、プロセスの状況を見るtopコマンドのような見た目になっています。topコマンドはプロセスが主役となる見た目になっていますが、perf topコマンドは プロセスで使われているライブラリの関数が主役となる見た目になっています。そのため、システムがスローダウンしているときに実行し、その犯人探しをすることに使われるそうです。
次に、すべてのプロセスが呼んだシステムコールを全部ロギングしてくれるツールである、perf traceを紹介しました。このツールは、ネットワークやI/Oが原因で問題が発生したとわかるときに、その原因となっているプログラムを探すのに使われるそうです。
最後に紹介したのはperf recordとperf reportです。pref recordは実行している間、ずっとperfの情報を取得してくれます。perf recordを終了後、perf reportで結果を確認できます。perf recordを実行すると関数名の一覧が表示され、画面を操作していくことでより詳細な情報を見ていくことができることを示しました。
SystemTap
3つ目のツールがSystemTapです。SystemTapは、デバッグのためのスクリプト言語です。SystemTapの言語仕様は貧弱で使いづらさはあるそうです。これはSystemTapのスクリプトがコンパイルされるとカーネル空間で動くツールとなるため、あまりシステムを負荷かけれてしまうスクリプトを組むのが難しいような言語設計にされていると言われている、と説明しました。
SystemTapはカーネルの関数をプローブすることで、その関数が実行されるときにフックしたりコールグラフを作成したりできるそうです。
そして見つけたバグ
小崎さんは、SystemTapのデモを作成しているときにRubyのSystemTap対応にバグを2つ見つけたそうです。
1つ目は、disable-gemsを有効にしてRubyを実行した際、SystemTap機能が正しく動かないというバグです。こちらは、関数名のミスタイプが原因だったようです。SystemTap対応の元となったDtrace対応のころから入っていて、その後その箇所が何度か触られていたにもかかわらず残っているというのが今回初めてわかったとのことです。
2つ目は、SystemTapではRubyの行番号を取得きるのですが、Cで書かれた箇所については取得できないというものです。この問題に対し、小崎さんはまつもとゆきひろさんが言っていた「RubyでできることはCでもできる」という言葉をだし対応したそうです。しかし、対応したもののRubyGemsの呼び出しが大量に表示されてしまうので、使うには不便という問題がわかったとのこと。この問題に対し、
kernel.#requireにオプションでファイル名と行番号を渡す
rubygemsがDTRACEHOOKを代わりに呼ぶ
という解決案を提案し、近日中にRuby Core Teamで議論したいと述べました。
まとめ
最後に、本日話した内容を次のようにまとめました。
Linux Portメンテナの役割について
Linuxのデバッグツール御三家の使い方紹介
発表資料を作るとバグを見つけて作業が進まない
バグがたくさん直った
また、最後にRubyのDtrace、SystemTap対応には足りてない機能がまだまだあるので、フィードバックがほしいと話を締めくくりました。