Search on the blog

2013年11月11日月曜日

GDBでC++デバッグするときはpretty-printersが便利

pretty-printersというツールを使うと、GDBデバッグ時にSTLコンテナの中身を”人間にも読める形”で表示させることが出来ます。

Before --pretty-printersを使わない場合
以下のソースをサンプルとして使います。
int main(int argc, char **argv) {
    int buf[] = {1,2,3,4,5};
    vector<int> vec(buf, buf+5);

    cout << accumulate(buf, buf+5, 0) << endl;
    cout << accumulate(vec.begin(), vec.end(), 0) << endl;

    return 0;
}
デバッグ中に、bufおよびvecの中身を表示すると以下のようになります。

(gdb) p buf
$1 = {1, 2, 3, 4, 5}
(gdb) p vec
$2 = {<std::_Vector_base<int, std::allocator<int> >> = {_M_impl = {<std::allocator<int>> = {<__gnu_cxx::new_allocator<int>> = {<No data fields>}, <No data fields>}, _M_start = 0x804c008, _M_finish = 0x804c01c, _M_end_of_storage = 0x804c01c}}, <No data fields>}

配列は中身が表示されますが、vectorはコンテナに格納した値が表示されません。
p *(vec._M_impl._M_start)@5とすれば中身が見れますが、毎回タイプするのは面倒です。

After --pretty-printersを使った場合
pretty-printersを使うと、先ほどの例がこうなります。

(gdb) p buf
$1 = {1, 2, 3, 4, 5}
(gdb) p vec
$2 = std::vector of length 5, capacity 5 = {1, 2, 3, 4, 5}

きちんと欲しい情報が表示されました。
他にもいろいろ試してみましたが、vector<vector<int> >やset<pair<int, int> >などの複雑な型にも対応しているようです。

インストール方法
1. svnからチェックアウト
svn co svn://gcc.gnu.org/svn/gcc/trunk/libstdc++-v3/python

2. ~/.gdbinitに以下を追記
python
import sys
sys.path.insert(0, '/home/maude/gdb_printers/python')
from libstdcxx.v6.printers import register_libstdcxx_printers
register_libstdcxx_printers (None)
end

※赤字のところは、チェックアウトしたディレクトリに置き換えてください。

参考URL
[1] debugging - How do I print the elements of a C++ vector in GDB? - Stack Overflow
[2] STLSupport - GDB Wiki

0 件のコメント:

コメントを投稿