1. gdb打印C++ STL容器

原生gdb通过p打印C++容器,打印出的内容往往难以理解,通过以下的脚本可以实现常用容器的打印。

  1. 拷贝以下内容到新文件stl_views_1.0.3.gdb
#
#   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<>
#define pvectorif $argc == 0help pvectorelseset $size = $arg0._M_impl._M_finish - $arg0._M_impl._M_startset $capacity = $arg0._M_impl._M_end_of_storage - $arg0._M_impl._M_startset $size_max = $size - 1endif $argc == 1set $i = 0while $i < $sizeprintf "elem[%u]: ", $ip *($arg0._M_impl._M_start + $i)set $i++endendif $argc == 2set $idx = $arg1if $idx < 0 || $idx > $size_maxprintf "idx1, idx2 are not in acceptable range: [0..%u].\n", $size_maxelseprintf "elem[%u]: ", $idxp *($arg0._M_impl._M_start + $idx)endendif $argc == 3set $start_idx = $arg1set $stop_idx = $arg2if $start_idx > $stop_idxset $tmp_idx = $start_idxset $start_idx = $stop_idxset $stop_idx = $tmp_idxendif $start_idx < 0 || $stop_idx < 0 || $start_idx > $size_max || $stop_idx > $size_maxprintf "idx1, idx2 are not in acceptable range: [0..%u].\n", $size_maxelseset $i = $start_idxwhile $i <= $stop_idxprintf "elem[%u]: ", $ip *($arg0._M_impl._M_start + $i)set $i++endendendif $argc > 0printf "Vector size = %u\n", $sizeprintf "Vector capacity = %u\n", $capacityprintf "Element "whatis $arg0._M_impl._M_startend
enddocument pvectorPrints std::vector<T> information.Syntax: pvector <vector> <idx1> <idx2>Note: idx, idx1 and idx2 must be in acceptable range [0..<vector>.size()-1].Examples:pvector v - Prints vector content, size, capacity and T typedefpvector v 0 - Prints element[idx] from vectorpvector v 1 2 - Prints elements in range [idx1..idx2] from vector
end #
# std::list<>
#define plistif $argc == 0help plistelseset $head = &$arg0._M_impl._M_nodeset $current = $arg0._M_impl._M_node._M_nextset $size = 0while $current != $headif $argc == 2printf "elem[%u]: ", $sizep *($arg1*)($current + 1)endif $argc == 3if $size == $arg2printf "elem[%u]: ", $sizep *($arg1*)($current + 1)endendset $current = $current._M_nextset $size++endprintf "List size = %u \n", $sizeif $argc == 1printf "List "whatis $arg0printf "Use plist <variable_name> <element_type> to see the elements in the list.\n"endend
enddocument plistPrints std::list<T> information.Syntax: plist <list> <T> <idx>: Prints list size, if T defined all elements or just element at idxExamples:plist l - prints list size and definitionplist l int - prints all elements and list sizeplist l int 2 - prints the third element in the list (if exists) and list size
enddefine plist_memberif $argc == 0help plist_memberelseset $head = &$arg0._M_impl._M_nodeset $current = $arg0._M_impl._M_node._M_nextset $size = 0while $current != $headif $argc == 3printf "elem[%u]: ", $sizep (*($arg1*)($current + 1)).$arg2endif $argc == 4if $size == $arg3printf "elem[%u]: ", $sizep (*($arg1*)($current + 1)).$arg2endendset $current = $current._M_nextset $size++endprintf "List size = %u \n", $sizeif $argc == 1printf "List "whatis $arg0printf "Use plist_member <variable_name> <element_type> <member> to see the elements in the list.\n"endend
enddocument plist_memberPrints std::list<T> information.Syntax: plist <list> <T> <idx>: Prints list size, if T defined all elements or just element at idxExamples:plist_member l int member - prints all elements and list sizeplist_member l int member 2 - prints the third element in the list (if exists) and list size
end#
# std::map and std::multimap
#define pmapif $argc == 0help pmapelseset $tree = $arg0set $i = 0set $node = $tree._M_t._M_impl._M_header._M_leftset $end = $tree._M_t._M_impl._M_headerset $tree_size = $tree._M_t._M_impl._M_node_countif $argc == 1printf "Map "whatis $treeprintf "Use pmap <variable_name> <left_element_type> <right_element_type> to see the elements in the map.\n"endif $argc == 3while $i < $tree_sizeset $value = (void *)($node + 1)printf "elem[%u].left: ", $ip *($arg1*)$valueset $value = $value + sizeof($arg1)printf "elem[%u].right: ", $ip *($arg2*)$valueif $node._M_right != 0set $node = $node._M_rightwhile $node._M_left != 0set $node = $node._M_leftendelseset $tmp_node = $node._M_parentwhile $node == $tmp_node._M_rightset $node = $tmp_nodeset $tmp_node = $tmp_node._M_parentendif $node._M_right != $tmp_nodeset $node = $tmp_nodeendendset $i++endendif $argc == 4set $idx = $arg3set $ElementsFound = 0while $i < $tree_sizeset $value = (void *)($node + 1)if *($arg1*)$value == $idxprintf "elem[%u].left: ", $ip *($arg1*)$valueset $value = $value + sizeof($arg1)printf "elem[%u].right: ", $ip *($arg2*)$valueset $ElementsFound++endif $node._M_right != 0set $node = $node._M_rightwhile $node._M_left != 0set $node = $node._M_leftendelseset $tmp_node = $node._M_parentwhile $node == $tmp_node._M_rightset $node = $tmp_nodeset $tmp_node = $tmp_node._M_parentendif $node._M_right != $tmp_nodeset $node = $tmp_nodeendendset $i++endprintf "Number of elements found = %u\n", $ElementsFoundendif $argc == 5set $idx1 = $arg3set $idx2 = $arg4set $ElementsFound = 0while $i < $tree_sizeset $value = (void *)($node + 1)set $valueLeft = *($arg1*)$valueset $valueRight = *($arg2*)($value + sizeof($arg1))if $valueLeft == $idx1 && $valueRight == $idx2printf "elem[%u].left: ", $ip $valueLeftprintf "elem[%u].right: ", $ip $valueRightset $ElementsFound++endif $node._M_right != 0set $node = $node._M_rightwhile $node._M_left != 0set $node = $node._M_leftendelseset $tmp_node = $node._M_parentwhile $node == $tmp_node._M_rightset $node = $tmp_nodeset $tmp_node = $tmp_node._M_parentendif $node._M_right != $tmp_nodeset $node = $tmp_nodeendendset $i++endprintf "Number of elements found = %u\n", $ElementsFoundendprintf "Map size = %u\n", $tree_sizeend
enddocument pmapPrints std::map<TLeft and TRight> or std::multimap<TLeft and TRight> information. Works for std::multimap as well.Syntax: pmap <map> <TtypeLeft> <TypeRight> <valLeft> <valRight>: Prints map size, if T defined all elements or just element(s) with val(s)Examples:pmap m - prints map size and definitionpmap m int int - prints all elements and map sizepmap m int int 20 - prints the element(s) with left-value = 20 (if any) and map sizepmap m int int 20 200 - prints the element(s) with left-value = 20 and right-value = 200 (if any) and map size
enddefine pmap_memberif $argc == 0help pmap_memberelseset $tree = $arg0set $i = 0set $node = $tree._M_t._M_impl._M_header._M_leftset $end = $tree._M_t._M_impl._M_headerset $tree_size = $tree._M_t._M_impl._M_node_countif $argc == 1printf "Map "whatis $treeprintf "Use pmap <variable_name> <left_element_type> <right_element_type> to see the elements in the map.\n"endif $argc == 5while $i < $tree_sizeset $value = (void *)($node + 1)printf "elem[%u].left: ", $ip (*($arg1*)$value).$arg2set $value = $value + sizeof($arg1)printf "elem[%u].right: ", $ip (*($arg3*)$value).$arg4if $node._M_right != 0set $node = $node._M_rightwhile $node._M_left != 0set $node = $node._M_leftendelseset $tmp_node = $node._M_parentwhile $node == $tmp_node._M_rightset $node = $tmp_nodeset $tmp_node = $tmp_node._M_parentendif $node._M_right != $tmp_nodeset $node = $tmp_nodeendendset $i++endendif $argc == 6set $idx = $arg5set $ElementsFound = 0while $i < $tree_sizeset $value = (void *)($node + 1)if *($arg1*)$value == $idxprintf "elem[%u].left: ", $ip (*($arg1*)$value).$arg2set $value = $value + sizeof($arg1)printf "elem[%u].right: ", $ip (*($arg3*)$value).$arg4set $ElementsFound++endif $node._M_right != 0set $node = $node._M_rightwhile $node._M_left != 0set $node = $node._M_leftendelseset $tmp_node = $node._M_parentwhile $node == $tmp_node._M_rightset $node = $tmp_nodeset $tmp_node = $tmp_node._M_parentendif $node._M_right != $tmp_nodeset $node = $tmp_nodeendendset $i++endprintf "Number of elements found = %u\n", $ElementsFoundendprintf "Map size = %u\n", $tree_sizeend
enddocument pmap_memberPrints std::map<TLeft and TRight> or std::multimap<TLeft and TRight> information. Works for std::multimap as well.Syntax: pmap <map> <TtypeLeft> <TypeRight> <valLeft> <valRight>: Prints map size, if T defined all elements or just element(s) with val(s)Examples:pmap_member m class1 member1 class2 member2 - prints class1.member1 : class2.member2pmap_member m class1 member1 class2 member2 lvalue - prints class1.member1 : class2.member2 where class1 == lvalue
end#
# std::set and std::multiset
#define psetif $argc == 0help psetelseset $tree = $arg0set $i = 0set $node = $tree._M_t._M_impl._M_header._M_leftset $end = $tree._M_t._M_impl._M_headerset $tree_size = $tree._M_t._M_impl._M_node_countif $argc == 1printf "Set "whatis $treeprintf "Use pset <variable_name> <element_type> to see the elements in the set.\n"endif $argc == 2while $i < $tree_sizeset $value = (void *)($node + 1)printf "elem[%u]: ", $ip *($arg1*)$valueif $node._M_right != 0set $node = $node._M_rightwhile $node._M_left != 0set $node = $node._M_leftendelseset $tmp_node = $node._M_parentwhile $node == $tmp_node._M_rightset $node = $tmp_nodeset $tmp_node = $tmp_node._M_parentendif $node._M_right != $tmp_nodeset $node = $tmp_nodeendendset $i++endendif $argc == 3set $idx = $arg2set $ElementsFound = 0while $i < $tree_sizeset $value = (void *)($node + 1)if *($arg1*)$value == $idxprintf "elem[%u]: ", $ip *($arg1*)$valueset $ElementsFound++endif $node._M_right != 0set $node = $node._M_rightwhile $node._M_left != 0set $node = $node._M_leftendelseset $tmp_node = $node._M_parentwhile $node == $tmp_node._M_rightset $node = $tmp_nodeset $tmp_node = $tmp_node._M_parentendif $node._M_right != $tmp_nodeset $node = $tmp_nodeendendset $i++endprintf "Number of elements found = %u\n", $ElementsFoundendprintf "Set size = %u\n", $tree_sizeend
enddocument psetPrints std::set<T> or std::multiset<T> information. Works for std::multiset as well.Syntax: pset <set> <T> <val>: Prints set size, if T defined all elements or just element(s) having valExamples:pset s - prints set size and definitionpset s int - prints all elements and the size of spset s int 20 - prints the element(s) with value = 20 (if any) and the size of s
end#
# std::dequeue
#define pdequeueif $argc == 0help pdequeueelseset $size = 0set $start_cur = $arg0._M_impl._M_start._M_curset $start_last = $arg0._M_impl._M_start._M_lastset $start_stop = $start_lastwhile $start_cur != $start_stopp *$start_curset $start_cur++set $size++endset $finish_first = $arg0._M_impl._M_finish._M_firstset $finish_cur = $arg0._M_impl._M_finish._M_curset $finish_last = $arg0._M_impl._M_finish._M_lastif $finish_cur < $finish_lastset $finish_stop = $finish_curelseset $finish_stop = $finish_lastendwhile $finish_first != $finish_stopp *$finish_firstset $finish_first++set $size++endprintf "Dequeue size = %u\n", $sizeend
enddocument pdequeuePrints std::dequeue<T> information.Syntax: pdequeue <dequeue>: Prints dequeue size, if T defined all elementsDeque elements are listed "left to right" (left-most stands for front and right-most stands for back)Example:pdequeue d - prints all elements and size of d
end#
# std::stack
#define pstackif $argc == 0help pstackelseset $start_cur = $arg0.c._M_impl._M_start._M_curset $finish_cur = $arg0.c._M_impl._M_finish._M_curset $size = $finish_cur - $start_curset $i = $size - 1while $i >= 0p *($start_cur + $i)set $i--endprintf "Stack size = %u\n", $sizeend
enddocument pstackPrints std::stack<T> information.Syntax: pstack <stack>: Prints all elements and size of the stackStack elements are listed "top to buttom" (top-most element is the first to come on pop)Example:pstack s - prints all elements and the size of s
end#
# std::queue
#define pqueueif $argc == 0help pqueueelseset $start_cur = $arg0.c._M_impl._M_start._M_curset $finish_cur = $arg0.c._M_impl._M_finish._M_curset $size = $finish_cur - $start_curset $i = 0while $i < $sizep *($start_cur + $i)set $i++endprintf "Queue size = %u\n", $sizeend
enddocument pqueuePrints std::queue<T> information.Syntax: pqueue <queue>: Prints all elements and the size of the queueQueue elements are listed "top to bottom" (top-most element is the first to come on pop)Example:pqueue q - prints all elements and the size of q
end#
# std::priority_queue
#define ppqueueif $argc == 0help ppqueueelseset $size = $arg0.c._M_impl._M_finish - $arg0.c._M_impl._M_startset $capacity = $arg0.c._M_impl._M_end_of_storage - $arg0.c._M_impl._M_startset $i = $size - 1while $i >= 0p *($arg0.c._M_impl._M_start + $i)set $i--endprintf "Priority queue size = %u\n", $sizeprintf "Priority queue capacity = %u\n", $capacityend
enddocument ppqueuePrints std::priority_queue<T> information.Syntax: ppqueue <priority_queue>: Prints all elements, size and capacity of the priority_queuePriority_queue elements are listed "top to buttom" (top-most element is the first to come on pop)Example:ppqueue pq - prints all elements, size and capacity of pq
end#
# std::bitset
#define pbitsetif $argc == 0help pbitsetelsep /t $arg0._M_wend
enddocument pbitsetPrints std::bitset<n> information.Syntax: pbitset <bitset>: Prints all bits in bitsetExample:pbitset b - prints all bits in b
end#
# std::string
#define pstringif $argc == 0help pstringelseprintf "String \t\t\t= \"%s\"\n", $arg0._M_data()printf "String size/length \t= %u\n", $arg0._M_rep()._M_lengthprintf "String capacity \t= %u\n", $arg0._M_rep()._M_capacityprintf "String ref-count \t= %d\n", $arg0._M_rep()._M_refcountend
enddocument pstringPrints std::string information.Syntax: pstring <string>Example:pstring s - Prints content, size/length, capacity and ref-count of string s
end #
# std::wstring
#define pwstringif $argc == 0help pwstringelsecall printf("WString \t\t= \"%ls\"\n", $arg0._M_data())printf "WString size/length \t= %u\n", $arg0._M_rep()._M_lengthprintf "WString capacity \t= %u\n", $arg0._M_rep()._M_capacityprintf "WString ref-count \t= %d\n", $arg0._M_rep()._M_refcountend
enddocument pwstringPrints std::wstring information.Syntax: pwstring <wstring>Example:pwstring s - Prints content, size/length, capacity and ref-count of wstring s
end #
# C++ related beautifiers (optional)
#set print pretty on
set print object on
set print static-members on
set print vtbl on
set print demangle on
set demangle-style gnu-v3
set print sevenbit-strings off
  1. 在启动gdb时,输入source [脚本所在位置]/stl_views_1.0.3.gdb来启用这个工具

我将文件放在了~/目录下,启动gdb后,输入以下内容:

source ~/stl_views_1.0.3.gdb


如果不想每次启动gdb都要手动输入source ~/stl_views_1.0.3.gdb读取脚本,可以将上面stl_views_1.0.3.gdb的内容直接拷贝到.gdbinit文件中,具体操作可以看后面的第二大点

  1. 例如,有一个std::vector类型的data,通过以下命令可以打印出vector的内容
pvector data


同样的,可以通过pmap,pset,plist…等等来打印STL容器的内容,方便调试。

2 .gdbinit文件

gdb在启动的时候,会在你的当前工作目录下查找 “.gdbinit” 这个文件,并把它的内容作为gdb命令进行解释

  1. /home/xxx下添加一个.gdbinit, gdb每次启动时,它都会执行这个文件中的命令来进行初始化。
  2. 下面有一个我认为比较好用的gdb,可以直接拷贝到用户目录下的./gdbinit文件中对gdb进行配置
# 保存历史命令
#set history filename ./.gdb_history
#set history save on# 记录执行gdb的过程
#set logging file ./.log.txt
#set logging on# 退出时不显示提示信息
#set confirm off# 将地址的颜色改成红色
#set style address foreground red# 打印数组的索引下标
set print array-indexes on# 每行打印一个结构体成员
set print pretty on# 退出并保留断点
define qbp
save breakpoints ./.gdb_bp
quit
end
document qbp
Exit and save the breakpoint
end# 保留历史工作断点
define downbp
save breakpoints ./.gdb_bp
end
document downbp
Save the historical work breakpoint
end# 加载历史工作断点
define loadbp
source ./.gdb_bp
end
document loadbp
Load the historical work breakpoint
end
  1. 保存退出后,在该用户下进行gdb调试,就会自动启用.gdbinit文件中的这些配置啦

【gdb配置】打印stl容器,.gdbinit文件相关推荐

  1. linux里gdb配置插件peda, gef, gdbinit

    准备环境 打开虚拟机,从主文件夹里打开终端 安装pwndbg $ git clone https://github.com/pwndbg/pwndbg $ cd pwndbg $ ./setup.sh ...

  2. GDB调试打印STL对象

    为什么80%的码农都做不了架构师?>>>    其实就gdb_stl_utils是定义的一些语句,就如同shell中的.bashrc一样,可以在启动gdb后把它source进取,也可 ...

  3. gdb 查看 stl容器 zz

    将下面文件作为 ~/.gdbinit的内容, 或者在已有的~/.gdbinit中source下面的文件, 然后可以以下列方式查看stl容器的数据:  容器类型 GDB 命令 std::vector&l ...

  4. NDK中C++标准库、STL的配置;Include其他头文件

    原文: Android学习笔记--NDK中C++标准库.STL的配置:Include其他头文件 1.STL的使用,以stlport为例 官方的说法是只需要在Application.mk文件中添加如下一 ...

  5. c++ stl容器vector删除(erase),遍历等基本用法介绍及头文件

    Vectors 包含着一系列连续存储的元素,其行为和数组类似.访问Vector中的任意元素或从末尾添加元素都可以在常量级时间复杂度内完成,而查找特定值的元素所处的位置或是在Vector中插入元素则是线 ...

  6. oracle erase,c++ stl容器vector删除(erase),遍历等基本用法介绍及头文件

    Vectors 包含着一系列连续存储的元素,其行为和数组类似.访问Vector中的任意元素或从末尾添加元素都可以在常量级时间复杂度内完成,而查找特定值的元素所处的位置或是在Vector中插入元素则是线 ...

  7. 复习笔记(九)——C++中的容器(STL容器)

    STL定义 STL(Standard Template Library),即标准模板库,是一个高效的C++程序库.被容纳于C++标准程序库(C++ Standard Library)中,是ANSI/I ...

  8. [Spring实战系列](6)配置Spring IOC容器的Bean

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/SunnyYoona/article/details/50619900 1. 简介 Spring提供了 ...

  9. STL容器板子(vector篇)

    一.STL的诞生 (1)长久以来,软件界一直希望建立一种可重复利用的东西 (2)C++的面向对象和泛型编程思想,日的就是复用性的提升 (3)大多情况下,数据结构和算法都未能有一套标准,导致被迫从事大量 ...

最新文章

  1. 8个开发必备的PHP功能
  2. .NET 中的对象序列化 (转载)
  3. JAX-RS(Java API for RESTful Web Services)常用注解
  4. idea创建xml文件 却没有xml模板
  5. Java实现swap交换(可能跟网上的一些方法不太一样)
  6. [云炬创业基础笔记]第二章创业者测试21
  7. java面试题七 char转int
  8. Android简单实现将手机图片上传到服务器中
  9. 【linux基础】关于ARM板子使用O3编译选项优化
  10. ffmpeg和SDL学习笔记
  11. 408数据结构:1.顺序表的定义
  12. 鼠标右键快速连接wifi
  13. openlayers2 开发如何判断一个marker所在的点是否在一个多边形内部
  14. JSP 页面实现一个计算器功能
  15. SwiftyJSON之使用分析
  16. 服务器硬盘检测系统,服务器RAID硬盘与日志主要检测方法
  17. Python3.7 安装Airflow 报错tenacity.async import AsyncRetrying
  18. afm原子力分析软件_【干货】原子力显微镜(AFM)的使用和成像技巧
  19. [译]不再对 MVVM 感到绝望
  20. K8s Kubectl基础命令的使用、滚动更新、以及回滚操作

热门文章

  1. 天池零基础入门NLP - 新闻文本分类Top1方案的bert4torch复现
  2. 码农Peter的悲惨故事,哈哈哈
  3. Halcon版权费、hdevelop和hdevelop xl的区别
  4. 楚留香手游电脑版不显示服务器,楚留香手游PC版无响应怎么办 电脑版无响应处理方法...
  5. 北林IPv6免流上网
  6. 职高学计算机怎么才能考本科,职业高中能考什么大学 可以考本科吗
  7. 算法笔记1926ProblemC Excel排序
  8. onnxruntime gpu 推理
  9. Morphia开发简介
  10. 小米的面试过程及面试题~