C や C++ でプログラムの書いたことのある多くの人は、「プログラムを高速化したいけれど、どこが一番のボトルネックか分からない」とか、「メモリリークがあるようだけれど、どこで発生しているか分からない」といった問題で苦しめられた経験が一度くらいはあると思います。もちろん、こうした問題の解決策として、アドホックにプログラムをチューニングしたり、目でプログラムを追ってメモリリークの発生箇所を突き詰めることも可能ですが、時間がかかってしまうことが多々ありますし、あまり楽しい作業でもないと思います。
アドレスを関数名に変換する。 ステップ 1 で取得したスタックトレースは生のアドレスのリストです。アドレスだけでは不便なので、アドレスを関数名に変換してやります。この処理はバイナリフォーマットに依存します。 google-glog では、 ELF というバイナリフォーマットの場合は自力でシンボルテーブルをスキャンして変換、 Mac OS X の場合はシステムライブラリが提供する dladdr() という関数を使って変換を行います。
C++ の関数名を読みやすくする。 C++ の関数名はバイナリの中では Foo::Foo() → _ZN3FooC1Ev のように変換された形で記録されています (この変換はマングリングと呼ばれます)。_ZN3FooC1Ev は読みにくいので Foo::Foo() に変換してやります (この変換はデマングリングと呼ばれます)。名前を変換する方式にはいろいろありますが、 google-glog では GCC バージョン 3 から使われている Itanium C++ ABI にのみ対応しています。
シグナルハンドラ内で処理するという性質上、できるだけすべての処理を async signal safe (たとえば malloc は使わない) に行うようにがんばっています。将来的にはステップ 4 として「アドレスからファイル名と行番号を取得する」を追加したいと考えています。
まとめ
C++ のプログラムのデバッグを楽にする方法として、 google-glog のスタックトレース表示機能を紹介しました。C++ のプログラムのデバッグは難しいケースも多いのですが、簡単なケースのデバッグはスタックトレース表示によって効率化できるのではないかと思います。
Google Summer of Code は、いくつかのオープンソース / フリーソフトウェアの開発プロジェクトに指導者(メンター)になってもらい、学生のみなさんに実践的なプログラミングを経験してもらおうという企画です。最終的に成果をあげたプロジェクトには Google から 5000 US ドル(学生に 4500 US ドル、メンター組織に 500 US ドル)が支払われます。
Google Summer of Code はプログラミングコンテストではないので、あたえられた課題をこなせるかどうかを問われているのではありません。
メンターや関連プロジェクトの開発者と一緒に、プロジェクトを完遂することが目標となります。成功しているプロジェクトは、チームで協力しあってソフトウェアの開発をすすめているものです。わからないからできないではなく、わからないところはメンターやプロジェクト開発者に聞いて目標を達成するというのが重要です。どのような目標を設定するかも、メンター組織の人と相談しつつ決めていくとよいでしょう。アイデアリストにはなくても、そのメンター組織に関連したすばらしいアイデアがあればぜひそれを提案していってください。今までの Google Summer of Code で成功したといわれる学生は自らプロジェクトアイデアを提案してきていたそうです。