背景:
当我们用gdb调试stl时候,往往看到的是stl内部变量的值,比如打印一个string a
输出:
(gdb) p a
$1 = {
static npos = 18446744073709551615,
_M_dataplus = {
<std::allocator<char>> = {
<__gnu_cxx::new_allocator<char>> = {<No data fields>},<No data fields>},
members ofstd::basic_string<char,std::char_traits<char>,std::allocator<char>>::_Alloc_hider:
_M_p = 0x50b028 "test"
}
}
打印一个vector v:
(gdb) p v
$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 ofstd::_Vector_base<int,std::allocator<int> >::_Vector_impl:
_M_start = 0x50b060,
_M_finish = 0x50b068,
_M_end_of_storage = 0x50b068
}
}, <No datafields>}
打印其中的某个元素:
(gdb) p v[0]
One of the arguments you tried to pass to operator[] couldnot be converted to what the function wants.
(gdb) p v.at(0)
Cannot evaluate function -- may be inlined
当我们不熟悉stl内部实现的时候,这给我们调试问题带来了一些麻烦。
解决方案:
1) 使用gdb user define command
其实就是一些gdb语法实现一些宏,一个比较常用的是writen by Dan Marinescu 的dbinit_stl_views。内容参考如下:
http://www.yolinux.com/TUTORIALS/src/dbinit_stl_views-1.03.txt
把上面文件写入.gdbinit,gdb启动的时候自动加载;一般来说这样就可以按照上面文档的说明接口调试stl,比如pvector pstring,但当我使用这些接口的时候,遇到下面的情况:
原因:我的gcc貌似不支持 $argc (所在的版本应该是支持的,可能是没有加某些编译选项,未找到原因),没想到更好的方案,如果不升级gcc,只能自己修改上面的接口,为多参数增加更多的宏定义;参考下面的源码:
#
# STL GDB evaluators/views/utilities - 1.03
#
# The new GDB commands:
# are entirely non instrumental
# do not depend on any "inline"(s) - e.g. size(), [], etc
# are extremely tolerant to debugger settings
#
# This file should be "included" in .gdbinit as following:
# source stl-views.gdb or just paste it into your .gdbinit file
#
# The following STL containers are currently supported:
#
# std::vector<T> -- via pvector command
# std::list<T> -- via plist or plist_member command
# std::map<T,T> -- via pmap or pmap_member command
# std::multimap<T,T> -- via pmap or pmap_member command
# std::set<T> -- via pset command
# std::multiset<T> -- via pset command
# std::deque<T> -- via pdequeue command
# std::stack<T> -- via pstack command
# std::queue<T> -- via pqueue command
# std::priority_queue<T> -- via ppqueue command
# std::bitset<n> -- via pbitset command
# std::string -- via pstring command
# std::widestring -- via pwstring command
#
# The end of this file contains (optional) C++ beautifiers
# Make sure your debugger supports $argc
#
# Simple GDB Macros writen by Dan Marinescu (H-PhD) - License GPL
# Inspired by intial work of Tom Malnar,
# Tony Novac (PhD) / Cornell / Stanford,
# Gilad Mishne (PhD) and Many Many Others.
# Contact: dan_c_marinescu@yahoo.com (Subject: STL)
#
# Modified to work with g++ 4.3 by Anders Elton
# Also added _member functions, that instead of printing the entire class in map, prints a member.
#
# std::vector<>
#
# 输出vector中的全部元素,size, capacity, 元素类型
define pvector
set $size = $arg0._M_impl._M_finish - $arg0._M_impl._M_start
set $capacity = $arg0._M_impl._M_end_of_storage - $arg0._M_impl._M_start
set $size_max = $size - 1
set $i = 0
while $i < $size
printf "elem[%u]: ", $i
p *($arg0._M_impl._M_start + $i)
set $i++
end
printf "Vector size = %u\n", $size
printf "Vector capacity = %u\n", $capacity
printf "Element "
whatis $arg0._M_impl._M_start
end
#输出vector中指定索引位置的元素
define pvector_index
set $idx = $arg1
set $size = $arg0