Debugging C++ with less pain
by Leandro Lucarella on 2010- 05- 14 23:52 (updated on 2010- 05- 14 23:52)- with 0 comment(s)
It turns out GDB 7.0+ can be extended through Python scripts, for instance, to add pretty-printers. And it turns out GCC 4.5 comes with some good pretty-printers for GDB.
Do you want to see the result of that combination?
$ cat -n p.cpp 1 2 #include <string> 3 #include <vector> 4 #include <map> 5 6 int main() 7 { 8 std::string s = "hello world"; 9 std::vector<std::string> v; 10 v.push_back(s); 11 v.push_back("nice"); 12 std::map<std::string, std::vector<std::string> > m; 13 m[s] = v; 14 v.push_back("yeah"); 15 m["lala"] = v; 16 return 1; 17 } 18 $ g++ -g -o p p.cpp $ gdb -q ./p (gdb) break 16 Breakpoint 1 at 0x400f86: file p.cpp, line 16. (gdb) run Starting program: /tmp/p Breakpoint 1, main () at p.cpp:16 16 return 1; (gdb) print m $1 = std::map with 2 elements = { ["hello world"] = std::vector of length 2, capacity 2 = {"hello world", "nice"}, ["lala"] = std::vector of length 3, capacity 3 = {"hello world", "nice", "yeah"} } (gdb)
Nice, ugh?
The only missing step is configuration, because most distribution don't do the integration themselves yet (or don't have packages with the scripts).
Here are 3 quick steps to make it all work:
$ mkdir ~/.gdb # can be stored anywhere really $ svn co svn://gcc.gnu.org/svn/gcc/trunk/libstdc++-v3/python ~/.gdb/python $ cat << EOT > ~/.gdbinit python import sys sys.path.insert(0, '/home/$HOME/.gdb/python') from libstdcxx.v6.printers import register_libstdcxx_printers register_libstdcxx_printers (None) end EOT
That's it!
If like to suffer once in a while you can get the raw values using /r:
(gdb) print /r m $2 = {_M_t = { _M_impl = {<std::allocator<std::_Rb_tree_node<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > > >> = {<__gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > > >> = {<No data fields>}, <No data fields>}, _M_key_compare = {<std::binary_function<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool>> = {<No data fields>}, <No data fields>}, _M_header = { _M_color = std::_S_red, _M_parent = 0x6070b0, _M_left = 0x6070b0, _M_right = 0x607190}, _M_node_count = 2}}}
Looks more familiar? I guess you won't miss it! =P
TestDisk
by Leandro Lucarella on 2010- 05- 14 19:56 (updated on 2010- 05- 14 19:56)- with 0 comment(s)
I accidentaly removed a couple of files from a FAT partition, and even when undeleting files from a FAT patition is possible from ancient times, it took me some time to find a tool that worked in Linux and was packaged.
So in case you find yourself with this very same need, search no more: meet TestDisk.