gdb如何打印程序中的stl变量
2017-11-17 13:46
211 查看
GDB的自定义命令非常有用,通过自定义命令,直接操作容器中的数据,可以方便的查看STL容器中的数据。这个链接dbinit_stl_views是Dan C Marinescu写的查看STL容器的自定义命令(如果不适合你的STL版本的话,可以自行修改)。把它添加到你的.gdbinit中,就可以方便的查看STL容器了。它提供了查看vector,list,map,multimap,set,multiset,deque,stack,queue,priority_queue,bitset,string,widestring等对象的方法,非常好用!1. 下载 http://www.yolinux.com/TUTORIALS/src/dbinit_stl_views-1.03.txt2. #cat dbinit_stl_views-1.03.txt >> ~/.gdbinit3. 若正处于gdb中,运行命令:(gdb) source ~/.gdbinit4. 例如,如下代码:bugging.cpp[cpp] view plaincopy#include <vector> using namespace std; int main() { vector<int> vec; vec.push_back(2); vec.push_back(3); vec.push_back(4); return 0; } 编译:[cpp] view plaincopy#g++ -o bugging -g bugging.cpp gdb调试:.[cpp] view plaincopy# gdb bugging GNU gdb 6.8 Copyright (C) 2008 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "i486-slackware-linux"... (gdb) help pvector Prints 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 typedef pvector v 0 - Prints element[idx] from vector pvector v 1 2 - Prints elements in range [idx1..idx2] from vector (gdb) break main Breakpoint 1 at 0x80485c6: file bugging.cpp, line 6. (gdb) run Starting program: /root/learn/c++/bugging Breakpoint 1, main () at bugging.cpp:6 6 vector<int> vec; (gdb) n 7 vec.push_back(2); (gdb) 8 vec.push_back(3); (gdb) pvector Prints 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 typedef pvector v 0 - Prints element[idx] from vector pvector v 1 2 - Prints elements in range [idx1..idx2] from vector (gdb) pvector vec elem[0]: $1 = 2 Vector size = 1 Vector capacity = 1 Element type = int * (gdb) n 9 vec.push_back(4); (gdb) 10 return 0; (gdb) pvector vec elem[0]: $2 = 2 elem[1]: $3 = 3 elem[2]: $4 = 4 Vector size = 3 Vector capacity = 4 Element type = int * (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_startendenddocument 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 vectorend## 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"endendenddocument 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 sizeenddefine 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"endendenddocument 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 sizeend## 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_sizeendenddocument 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 sizeenddefine 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_sizeendenddocument 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 == lvalueend## 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_sizeendenddocument 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 send## 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", $sizeendenddocument 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 dend## 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", $sizeendenddocument 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 send## 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", $sizeendenddocument 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 qend## 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", $capacityendenddocument 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 pqend## std::bitset#define pbitsetif $argc == 0help pbitsetelsep /t $arg0._M_wendenddocument pbitsetPrints std::bitset<n> information.Syntax: pbitset <bitset>: Prints all bits in bitsetExample:pbitset b - prints all bits in bend## 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_refcountendenddocument pstringPrints std::string information.Syntax: pstring <string>Example:pstring s - Prints content, size/length, capacity and ref-count of string send## 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_refcountendenddocument pwstringPrints std::wstring information.Syntax: pwstring <wstring>Example:pwstring s - Prints content, size/length, capacity and ref-count of wstring send## C++ related beautifiers (optional)#set print pretty onset print object onset print static-members onset print vtbl onset print demangle onset demangle-style gnu-v3set print sevenbit-strings off
相关文章推荐
- 如何使用arm-eabi-gdb调试android c/c++程序
- gdb:不退出程序的情况下打印函数中的局部变量
- 如何让程序crash时生成coredump文件并用gdb调试
- 如何解决Linux下Qt Creator调试C/C++程序出现Debugging starts &"warning: GDB: Failed to set controlling terminal警告
- 如何使用GDB调试PHP程序
- 如何利用gdb调试程序?
- GDB如何打印长xml串
- 陈皓专栏 --- 如何用GDB调试程序
- 如何在程序中写log日志(定义log级别:error,warn, info, debug; 宏定义打印不同级别的日志; 程序中引用宏定义即可)
- linux下如何用GDB调试c++程序
- 在_Linux_中如何使用_gdb_调试_C_程序
- gdb-如何在gdb里自动打印一个链表的方法:写一小段执行嵌套脚本
- 如何使用arm-eabi-gdb调试android c/c++程序
- Linux:如何使用gdb调试多进程多线程程序
- 如何利用gdb调试程序之细节(info reg命令以及寄存器地址)
- 如何用程序自动打印Int类型十进制负数的二进制码?
- 在Linux系统下,如果程序中出现segment fault,如何可以让系统产生core dump文件?如何用gdb来跟踪出错的地方?
- 闲谈程序中如何打印log
- 餐饮外卖小程序如何对接小票打印机自动接单打印
- 如何使用gdb调试C程序