2008年の3月にリリースされたgdb-6.8の目玉機能の一つに「C++サポートの強化」があります*1。この機能を使うと、STLやboostのようなテンプレートを使ったコードのデバッグがかなり楽になります。C++使いの方は、是非gdbを6.8にupgradeしましょう。
具体的に、以下のようなコードを使って、「C++サポートの強化」について説明します。
#include <iostream> using namespace std; template <typename T> class A { public: void func() { cout << sizeof(T) << endl; } }; int main() { A<int> integer; A<double> real; integer.func(); real.func(); return 0; }
このコードに対して、6.7以前のgdbで func() にブレークポイントを設定します。test.cppの9行目なので以下のようになります
(gdb) break test.cpp:9 Breakpoint 1 at 0x80486fc: file test.cpp, line 9.
- func()の行にカーソルをおいた状態で、c-x SPACE を押す
- func()の行の左側をマウスでクリック
のような操作でブレークポイントが設定できます。
ところが従来のgdbではここで問題が生じます。恐ろしいことに、この状態では func() でプログラムがブレークしない場合があるのです。ブレークポイントを設定したのにも関わらずです。
どういうことかというと、それは次のように info breakpoints でブレークポイントの一覧を見るとわかります。
(gdb) info breakpoints Num Type Disp Enb Address What 1 breakpoint keep y 0x080486fc in A<int>::func() at test.cpp:9
このように、func()には実体が二つ、つまりA
gdb-6.8の「C++サポートの強化」とは、この問題を解決するものです。具体的には gdb-6.8 では、同じようにブレークポイントを設定するだけで
(gdb) b test.cpp:9 Breakpoint 1 at 0x80486fc: file test.cpp, line 9. (2 locations)
自動的に、実体のある関数すべてにブレークポイントを設定してくれます。
(gdb) i b Num Type Disp Enb Address What 1 breakpoint keep y <MULTIPLE> 0x080486fc 1.1 y 0x080486fc in A<int>::func() at test.cpp:9 1.2 y 0x08048728 in A<double>::func() at test.cpp:9
この機能のおかげで、何も考えずとも毎回ちゃんとfunc()でブレークしてくれます。実に直感的な挙動です。
ついでに、A
(gdb) disable 1.2
とします。詳細は本家のマニュアルをどうぞ。
http://sourceware.org/gdb/current/onlinedocs/gdb_6.html#SEC33