使用GDB 调试STL方法

背景:

当我们用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
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值