]> git.llucax.com Git - personal/website.git/blob - source/blog/posts/2010/05/14-debugging-c++-with-less-pain.rst
More https fixes
[personal/website.git] / source / blog / posts / 2010 / 05 / 14-debugging-c++-with-less-pain.rst
1 Title: Debugging C++ with less pain
2 Tags: en, gdb, c++, stl, debug, python
3
4 It turns out GDB__ 7.0+ can be extended through Python__ scripts, for instance,
5 to add pretty-printers. And it turns out GCC__ 4.5 comes with some good
6 pretty-printers for GDB.
7
8 __ http://www.gnu.org/software/gdb/
9 __ http://www.python.org/
10 __ http://gcc.gnu.org/
11
12 Do you want to see the result of that combination?
13
14 ::
15
16    $ cat -n p.cpp
17         1
18         2  #include <string>
19         3  #include <vector>
20         4  #include <map>
21         5
22         6  int main()
23         7  {
24         8          std::string s = "hello world";
25         9          std::vector<std::string> v;
26        10          v.push_back(s);
27        11          v.push_back("nice");
28        12          std::map<std::string, std::vector<std::string> > m;
29        13          m[s] = v;
30        14          v.push_back("yeah");
31        15          m["lala"] = v;
32        16          return 1;
33        17  }
34        18
35    $ g++ -g -o p p.cpp
36    $ gdb -q ./p
37    (gdb) break 16
38    Breakpoint 1 at 0x400f86: file p.cpp, line 16.
39    (gdb) run
40    Starting program: /tmp/p
41
42    Breakpoint 1, main () at p.cpp:16
43    16              return 1;
44    (gdb) print m
45    $1 = std::map with 2 elements = {
46      ["hello world"] = std::vector of length 2, capacity 2 = {"hello world", "nice"},
47      ["lala"] = std::vector of length 3, capacity 3 = {"hello world", "nice", "yeah"}
48    }
49    (gdb)
50
51 **Nice**, ugh?
52
53 The only missing step is configuration, because most distribution don't do the
54 integration themselves yet (or don't have packages with the scripts).
55
56 Here are 3 quick steps to make it all work::
57
58    $ mkdir ~/.gdb # can be stored anywhere really
59    $ svn co svn://gcc.gnu.org/svn/gcc/trunk/libstdc++-v3/python ~/.gdb/python
60    $ cat << EOT > ~/.gdbinit
61    python
62    import sys
63    sys.path.insert(0, '/home/$HOME/.gdb/python')
64    from libstdcxx.v6.printers import register_libstdcxx_printers
65    register_libstdcxx_printers (None)
66    end
67    EOT
68
69 That's it!
70
71 If like to suffer once in a while you can get the raw values using ``/r``::
72
73    (gdb) print /r m
74    $2 = {_M_t = {
75        _M_impl = {<std::allocator<std::_Rb_tree_node<std::pair<std::basic_string<char, std::char_traits<char>,
76    std::allocator<char> > const, std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >,
77    std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > > >> =
78    {<__gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char>
79    > const, std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >,
80    std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > > >> = {<No data fields>}, <No
81    data fields>},
82          _M_key_compare = {<std::binary_function<std::basic_string<char, std::char_traits<char>, std::allocator<char> >,
83    std::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool>> = {<No data fields>}, <No data fields>},
84    _M_header = {
85            _M_color = std::_S_red, _M_parent = 0x6070b0, _M_left = 0x6070b0,
86            _M_right = 0x607190}, _M_node_count = 2}}}
87
88 Looks more familiar? I guess you won't miss it! =P
89
90
91 .. vim: set et sw=3 sts=3 :