gdb always prints lots of useless stuffs from a container.
$ g++ -std=c++11 foo.cc -g
$ gdb -q ./a.out
Reading symbols from ./a.out...done.
(^q^) l
1 #include <vector>
2
3 int main (void) {
4 std::vector<int> v = {1, 2, 3, 4, 5};
5 return 0;
6 }
(^q^) b 5
Breakpoint 1 at 0x40082c: file foo.cc, line 5.
(^q^) r
Starting program: /tmp/a.out
Breakpoint 1, main () at foo.cc:5
5 return 0;
(^q^) p
$2 = {
<std::_Vector_base<int, std::allocator<int> >> = {
_M_impl = {
<std::allocator<int>> = {
<__gnu_cxx::new_allocator<int>> = {<No data fields>}, <No data fields>},
members of std::_Vector_base<int, std::allocator<int> >::_Vector_impl:
_M_start = 0x602010,
_M_finish = 0x602024,
_M_end_of_storage = 0x602024
}
}, <No data fields>}
(^q^)
And we're able to use a very tricky way to print that out.
(^q^) p *(v._M_impl._M_start)@(v._M_impl._M_finish - v._M_impl._M_start)
$22 = {[0] = 1,
[1] = 2,
[2] = 3,
[3] = 4,
[4] = 5}
(^q^)
A container is a "container", we don't care the implementation details, what we care about is the data.
With the pretty printer, we're able to print a container out like this:
(^q^) p v
$1 = std::vector of length 5, capacity 5 = {
[0] = 1,
[1] = 2,
[2] = 3,
[3] = 4,
[4] = 5
}
Download the latest python script from gcc.gnu.org
---
mkdir ~/.gdb
cd ~/.gdb
svn co svn://gcc.gnu.org/svn/gcc/trunk/libstdc++-v3/python
---
put the following stuffs appended to your ~/.gdbinit
---
python
import sys
sys.path.insert(0, '/home/xatier/.gdb/python')
import libstdcxx.v6
end
---
Note, we only need to import the lib, let __init__.py do the magic ;-)
Done!
If you really want to dig up the implementation details, use " p /r "
(^q^) p /r v
$1 = {
<std::_Vector_base<int, std::allocator<int> >> = {
_M_impl = {
<std::allocator<int>> = {
<__gnu_cxx::new_allocator<int>> = {<No data fields>}, <No data fields>},
members of std::_Vector_base<int, std::allocator<int> >::_Vector_impl:
_M_start = 0x602010,
_M_finish = 0x602024,
_M_end_of_storage = 0x602024
}
}, <No data fields>}
(^q^)
Actually this python script will be installed and automatically loaded in Archlinux once you install gcc/gcc-multilib.
$ pacman -Ql gcc-multilib | grep libstd
gcc-multilib /usr/lib/libstdc++.a
gcc-multilib /usr/lib32/libstdc++.a
gcc-multilib /usr/share/gcc-4.9.2/python/libstdcxx/
gcc-multilib /usr/share/gcc-4.9.2/python/libstdcxx/__init__.py
gcc-multilib /usr/share/gcc-4.9.2/python/libstdcxx/v6/
gcc-multilib /usr/share/gcc-4.9.2/python/libstdcxx/v6/__init__.py
gcc-multilib /usr/share/gcc-4.9.2/python/libstdcxx/v6/printers.py
gcc-multilib /usr/share/gdb/auto-load/usr/lib/libstdc++.so.6.0.20-gdb.py
If you're using other distros like Debian, that should be here, but not auto-loaded by default :(
$ apt-file list gcc | grep libstd
gcc-snapshot: /usr/lib/gcc-snapshot/share/gcc-4.9.0/python/libstdcxx/__init__.py
gcc-snapshot: /usr/lib/gcc-snapshot/share/gcc-4.9.0/python/libstdcxx/v6/__init__.py
gcc-snapshot: /usr/lib/gcc-snapshot/share/gcc-4.9.0/python/libstdcxx/v6/printers.py
Happy debugging C++! (^q^)
No comments:
Post a Comment