zoukankan      html  css  js  c++  java
  • 使用GDB调试STL容器

    GDB中print方法并不能直接打印STL容器中保存的变量,想知道STL容器保存的变量,使用如下办法:

    1. 创建文件~/.gdbinit:

    #                                                                                                        
    #   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 pvector
    	if $argc == 0
    		help pvector
    	else
    		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
    	end
    	if $argc == 1
    		set $i = 0
    		while $i < $size
    			printf "elem[%u]: ", $i
    			p *($arg0._M_impl._M_start + $i)
    			set $i++
    		end
    	end
    	if $argc == 2
    		set $idx = $arg1
    		if $idx < 0 || $idx > $size_max
    			printf "idx1, idx2 are not in acceptable range: [0..%u].
    ", $size_max
    		else
    			printf "elem[%u]: ", $idx
    			p *($arg0._M_impl._M_start + $idx)
    		end
    	end
    	if $argc == 3
    	  set $start_idx = $arg1
    	  set $stop_idx = $arg2
    	  if $start_idx > $stop_idx
    	    set $tmp_idx = $start_idx
    	    set $start_idx = $stop_idx
    	    set $stop_idx = $tmp_idx
    	  end
    	  if $start_idx < 0 || $stop_idx < 0 || $start_idx > $size_max || $stop_idx > $size_max
    	    printf "idx1, idx2 are not in acceptable range: [0..%u].
    ", $size_max
    	  else
    	    set $i = $start_idx
    		while $i <= $stop_idx
    			printf "elem[%u]: ", $i
    			p *($arg0._M_impl._M_start + $i)
    			set $i++
    		end
    	  end
    	end
    	if $argc > 0
    		printf "Vector size = %u
    ", $size
    		printf "Vector capacity = %u
    ", $capacity
    		printf "Element "
    		whatis $arg0._M_impl._M_start
    	end
    end
    
    document 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
    end 
    
    #
    # std::list<>
    #
    
    define plist
    	if $argc == 0
    		help plist
    	else
    		set $head = &$arg0._M_impl._M_node
    		set $current = $arg0._M_impl._M_node._M_next
    		set $size = 0
    		while $current != $head
    			if $argc == 2
    				printf "elem[%u]: ", $size
    				p *($arg1*)($current + 1)
    			end
    			if $argc == 3
    				if $size == $arg2
    					printf "elem[%u]: ", $size
    					p *($arg1*)($current + 1)
    				end
    			end
    			set $current = $current._M_next
    			set $size++
    		end
    		printf "List size = %u 
    ", $size
    		if $argc == 1
    			printf "List "
    			whatis $arg0
    			printf "Use plist <variable_name> <element_type> to see the elements in the list.
    "
    		end
    	end
    end
    
    document plist
    	Prints std::list<T> information.
    	Syntax: plist <list> <T> <idx>: Prints list size, if T defined all elements or just element at idx
    	Examples:
    	plist l - prints list size and definition
    	plist l int - prints all elements and list size
    	plist l int 2 - prints the third element in the list (if exists) and list size
    end
    
    define plist_member
    	if $argc == 0
    		help plist_member
    	else
    		set $head = &$arg0._M_impl._M_node
    		set $current = $arg0._M_impl._M_node._M_next
    		set $size = 0
    		while $current != $head
    			if $argc == 3
    				printf "elem[%u]: ", $size
    				p (*($arg1*)($current + 1)).$arg2
    			end
    			if $argc == 4
    				if $size == $arg3
    					printf "elem[%u]: ", $size
    					p (*($arg1*)($current + 1)).$arg2
    				end
    			end
    			set $current = $current._M_next
    			set $size++
    		end
    		printf "List size = %u 
    ", $size
    		if $argc == 1
    			printf "List "
    			whatis $arg0
    			printf "Use plist_member <variable_name> <element_type> <member> to see the elements in the list.
    "
    		end
    	end
    end
    
    document plist_member
    	Prints std::list<T> information.
    	Syntax: plist <list> <T> <idx>: Prints list size, if T defined all elements or just element at idx
    	Examples:
    	plist_member l int member - prints all elements and list size
    	plist_member l int member 2 - prints the third element in the list (if exists) and list size
    end
    
    
    #
    # std::map and std::multimap
    #
    
    define pmap
    	if $argc == 0
    		help pmap
    	else
    		set $tree = $arg0
    		set $i = 0
    		set $node = $tree._M_t._M_impl._M_header._M_left
    		set $end = $tree._M_t._M_impl._M_header
    		set $tree_size = $tree._M_t._M_impl._M_node_count
    		if $argc == 1
    			printf "Map "
    			whatis $tree
    			printf "Use pmap <variable_name> <left_element_type> <right_element_type> to see the elements in the map.
    "
    		end
    		if $argc == 3
    			while $i < $tree_size
    				set $value = (void *)($node + 1)
    				printf "elem[%u].left: ", $i
    				p *($arg1*)$value
    				set $value = $value + sizeof($arg1)
    				printf "elem[%u].right: ", $i
    				p *($arg2*)$value
    				if $node._M_right != 0
    					set $node = $node._M_right
    					while $node._M_left != 0
    						set $node = $node._M_left
    					end
    				else
    					set $tmp_node = $node._M_parent
    					while $node == $tmp_node._M_right
    						set $node = $tmp_node
    						set $tmp_node = $tmp_node._M_parent
    					end
    					if $node._M_right != $tmp_node
    						set $node = $tmp_node
    					end
    				end
    				set $i++
    			end
    		end
    		if $argc == 4
    			set $idx = $arg3
    			set $ElementsFound = 0
    			while $i < $tree_size
    				set $value = (void *)($node + 1)
    				if *($arg1*)$value == $idx
    					printf "elem[%u].left: ", $i
    					p *($arg1*)$value
    					set $value = $value + sizeof($arg1)
    					printf "elem[%u].right: ", $i
    					p *($arg2*)$value
    					set $ElementsFound++
    				end
    				if $node._M_right != 0
    					set $node = $node._M_right
    					while $node._M_left != 0
    						set $node = $node._M_left
    					end
    				else
    					set $tmp_node = $node._M_parent
    					while $node == $tmp_node._M_right
    						set $node = $tmp_node
    						set $tmp_node = $tmp_node._M_parent
    					end
    					if $node._M_right != $tmp_node
    						set $node = $tmp_node
    					end
    				end
    				set $i++
    			end
    			printf "Number of elements found = %u
    ", $ElementsFound
    		end
    		if $argc == 5
    			set $idx1 = $arg3
    			set $idx2 = $arg4
    			set $ElementsFound = 0
    			while $i < $tree_size
    				set $value = (void *)($node + 1)
    				set $valueLeft = *($arg1*)$value
    				set $valueRight = *($arg2*)($value + sizeof($arg1))
    				if $valueLeft == $idx1 && $valueRight == $idx2
    					printf "elem[%u].left: ", $i
    					p $valueLeft
    					printf "elem[%u].right: ", $i
    					p $valueRight
    					set $ElementsFound++
    				end
    				if $node._M_right != 0
    					set $node = $node._M_right
    					while $node._M_left != 0
    						set $node = $node._M_left
    					end
    				else
    					set $tmp_node = $node._M_parent
    					while $node == $tmp_node._M_right
    						set $node = $tmp_node
    						set $tmp_node = $tmp_node._M_parent
    					end
    					if $node._M_right != $tmp_node
    						set $node = $tmp_node
    					end
    				end
    				set $i++
    			end
    			printf "Number of elements found = %u
    ", $ElementsFound
    		end
    		printf "Map size = %u
    ", $tree_size
    	end
    end
    
    document pmap
    	Prints 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 definition
    	pmap m int int - prints all elements and map size
    	pmap m int int 20 - prints the element(s) with left-value = 20 (if any) and map size
    	pmap m int int 20 200 - prints the element(s) with left-value = 20 and right-value = 200 (if any) and map size
    end
    
    
    define pmap_member
    	if $argc == 0
    		help pmap_member
    	else
    		set $tree = $arg0
    		set $i = 0
    		set $node = $tree._M_t._M_impl._M_header._M_left
    		set $end = $tree._M_t._M_impl._M_header
    		set $tree_size = $tree._M_t._M_impl._M_node_count
    		if $argc == 1
    			printf "Map "
    			whatis $tree
    			printf "Use pmap <variable_name> <left_element_type> <right_element_type> to see the elements in the map.
    "
    		end
    		if $argc == 5
    			while $i < $tree_size
    				set $value = (void *)($node + 1)
    				printf "elem[%u].left: ", $i
    				p (*($arg1*)$value).$arg2
    				set $value = $value + sizeof($arg1)
    				printf "elem[%u].right: ", $i
    				p (*($arg3*)$value).$arg4
    				if $node._M_right != 0
    					set $node = $node._M_right
    					while $node._M_left != 0
    						set $node = $node._M_left
    					end
    				else
    					set $tmp_node = $node._M_parent
    					while $node == $tmp_node._M_right
    						set $node = $tmp_node
    						set $tmp_node = $tmp_node._M_parent
    					end
    					if $node._M_right != $tmp_node
    						set $node = $tmp_node
    					end
    				end
    				set $i++
    			end
    		end
    		if $argc == 6
    			set $idx = $arg5
    			set $ElementsFound = 0
    			while $i < $tree_size
    				set $value = (void *)($node + 1)
    				if *($arg1*)$value == $idx
    					printf "elem[%u].left: ", $i
    					p (*($arg1*)$value).$arg2
    					set $value = $value + sizeof($arg1)
    					printf "elem[%u].right: ", $i
    					p (*($arg3*)$value).$arg4
    					set $ElementsFound++
    				end
    				if $node._M_right != 0
    					set $node = $node._M_right
    					while $node._M_left != 0
    						set $node = $node._M_left
    					end
    				else
    					set $tmp_node = $node._M_parent
    					while $node == $tmp_node._M_right
    						set $node = $tmp_node
    						set $tmp_node = $tmp_node._M_parent
    					end
    					if $node._M_right != $tmp_node
    						set $node = $tmp_node
    					end
    				end
    				set $i++
    			end
    			printf "Number of elements found = %u
    ", $ElementsFound
    		end
    		printf "Map size = %u
    ", $tree_size
    	end
    end
    
    document pmap_member
    	Prints 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.member2
    	pmap_member m class1 member1 class2 member2 lvalue - prints class1.member1 : class2.member2 where class1 == lvalue
    end
    
    
    #
    # std::set and std::multiset
    #
    
    define pset
    	if $argc == 0
    		help pset
    	else
    		set $tree = $arg0
    		set $i = 0
    		set $node = $tree._M_t._M_impl._M_header._M_left
    		set $end = $tree._M_t._M_impl._M_header
    		set $tree_size = $tree._M_t._M_impl._M_node_count
    		if $argc == 1
    			printf "Set "
    			whatis $tree
    			printf "Use pset <variable_name> <element_type> to see the elements in the set.
    "
    		end
    		if $argc == 2
    			while $i < $tree_size
    				set $value = (void *)($node + 1)
    				printf "elem[%u]: ", $i
    				p *($arg1*)$value
    				if $node._M_right != 0
    					set $node = $node._M_right
    					while $node._M_left != 0
    						set $node = $node._M_left
    					end
    				else
    					set $tmp_node = $node._M_parent
    					while $node == $tmp_node._M_right
    						set $node = $tmp_node
    						set $tmp_node = $tmp_node._M_parent
    					end
    					if $node._M_right != $tmp_node
    						set $node = $tmp_node
    					end
    				end
    				set $i++
    			end
    		end
    		if $argc == 3
    			set $idx = $arg2
    			set $ElementsFound = 0
    			while $i < $tree_size
    				set $value = (void *)($node + 1)
    				if *($arg1*)$value == $idx
    					printf "elem[%u]: ", $i
    					p *($arg1*)$value
    					set $ElementsFound++
    				end
    				if $node._M_right != 0
    					set $node = $node._M_right
    					while $node._M_left != 0
    						set $node = $node._M_left
    					end
    				else
    					set $tmp_node = $node._M_parent
    					while $node == $tmp_node._M_right
    						set $node = $tmp_node
    						set $tmp_node = $tmp_node._M_parent
    					end
    					if $node._M_right != $tmp_node
    						set $node = $tmp_node
    					end
    				end
    				set $i++
    			end
    			printf "Number of elements found = %u
    ", $ElementsFound
    		end
    		printf "Set size = %u
    ", $tree_size
    	end
    end
    
    document pset
    	Prints 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 val
    	Examples:
    	pset s - prints set size and definition
    	pset s int - prints all elements and the size of s
    	pset s int 20 - prints the element(s) with value = 20 (if any) and the size of s
    end
    
    
    
    #
    # std::dequeue
    #
    
    define pdequeue
    	if $argc == 0
    		help pdequeue
    	else
    		set $size = 0
    		set $start_cur = $arg0._M_impl._M_start._M_cur
    		set $start_last = $arg0._M_impl._M_start._M_last
    		set $start_stop = $start_last
    		while $start_cur != $start_stop
    			p *$start_cur
    			set $start_cur++
    			set $size++
    		end
    		set $finish_first = $arg0._M_impl._M_finish._M_first
    		set $finish_cur = $arg0._M_impl._M_finish._M_cur
    		set $finish_last = $arg0._M_impl._M_finish._M_last
    		if $finish_cur < $finish_last
    			set $finish_stop = $finish_cur
    		else
    			set $finish_stop = $finish_last
    		end
    		while $finish_first != $finish_stop
    			p *$finish_first
    			set $finish_first++
    			set $size++
    		end
    		printf "Dequeue size = %u
    ", $size
    	end
    end
    
    document pdequeue
    	Prints std::dequeue<T> information.
    	Syntax: pdequeue <dequeue>: Prints dequeue size, if T defined all elements
    	Deque 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 pstack
    	if $argc == 0
    		help pstack
    	else
    		set $start_cur = $arg0.c._M_impl._M_start._M_cur
    		set $finish_cur = $arg0.c._M_impl._M_finish._M_cur
    		set $size = $finish_cur - $start_cur
            set $i = $size - 1
            while $i >= 0
                p *($start_cur + $i)
                set $i--
            end
    		printf "Stack size = %u
    ", $size
    	end
    end
    
    document pstack
    	Prints std::stack<T> information.
    	Syntax: pstack <stack>: Prints all elements and size of the stack
    	Stack 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 pqueue
    	if $argc == 0
    		help pqueue
    	else
    		set $start_cur = $arg0.c._M_impl._M_start._M_cur
    		set $finish_cur = $arg0.c._M_impl._M_finish._M_cur
    		set $size = $finish_cur - $start_cur
            set $i = 0
            while $i < $size
                p *($start_cur + $i)
                set $i++
            end
    		printf "Queue size = %u
    ", $size
    	end
    end
    
    document pqueue
    	Prints std::queue<T> information.
    	Syntax: pqueue <queue>: Prints all elements and the size of the queue
    	Queue 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 ppqueue
    	if $argc == 0
    		help ppqueue
    	else
    		set $size = $arg0.c._M_impl._M_finish - $arg0.c._M_impl._M_start
    		set $capacity = $arg0.c._M_impl._M_end_of_storage - $arg0.c._M_impl._M_start
    		set $i = $size - 1
    		while $i >= 0
    			p *($arg0.c._M_impl._M_start + $i)
    			set $i--
    		end
    		printf "Priority queue size = %u
    ", $size
    		printf "Priority queue capacity = %u
    ", $capacity
    	end
    end
    
    document ppqueue
    	Prints std::priority_queue<T> information.
    	Syntax: ppqueue <priority_queue>: Prints all elements, size and capacity of the priority_queue
    	Priority_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 pbitset
    	if $argc == 0
    		help pbitset
    	else
            p /t $arg0._M_w
    	end
    end
    
    document pbitset
    	Prints std::bitset<n> information.
    	Syntax: pbitset <bitset>: Prints all bits in bitset
    	Example:
    	pbitset b - prints all bits in b
    end
    
    
    
    #
    # std::string
    #
    
    define pstring
    	if $argc == 0
    		help pstring
    	else
    		printf "String 			= "%s"
    ", $arg0._M_data()
    		printf "String size/length 	= %u
    ", $arg0._M_rep()._M_length
    		printf "String capacity 	= %u
    ", $arg0._M_rep()._M_capacity
    		printf "String ref-count 	= %d
    ", $arg0._M_rep()._M_refcount
    	end
    end
    
    document pstring
    	Prints std::string information.
    	Syntax: pstring <string>
    	Example:
    	pstring s - Prints content, size/length, capacity and ref-count of string s
    end 
    
    #
    # std::wstring
    #
    
    define pwstring
    	if $argc == 0
    		help pwstring
    	else
    		call printf("WString 		= "%ls"
    ", $arg0._M_data())
    		printf "WString size/length 	= %u
    ", $arg0._M_rep()._M_length
    		printf "WString capacity 	= %u
    ", $arg0._M_rep()._M_capacity
    		printf "WString ref-count 	= %d
    ", $arg0._M_rep()._M_refcount
    	end
    end
    
    document pwstring
    	Prints 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

    2.若正处于gdb中,运行命令: (gdb)source ~/.gdbinit

    例如,如下代码:bugging.cpp

    #include<vector>
    using namespace std;
    
    int main()
    {
        vector <int> vec;
        vec.push_back(2);
        vec.push_back(3);
        vec.push_back(4);
        return 0;
    }

    编译:g++ -o bugging -g bugging.cpp

    gdb 调试:



    想知道STL容器中保存的变量,命令汇总:

    Data type	GDB command
    std::vector<T>	pvector stl_variable
    std::list<T>	plist stl_variable T
    std::map<T,T>	pmap stl_variable
    std::multimap<T,T>	pmap stl_variable
    std::set<T>	pset stl_variable T
    std::multiset<T>	pset stl_variable
    std::deque<T>	pdequeue stl_variable
    std::stack<T>	pstack stl_variable
    std::queue<T>	pqueue stl_variable
    std::priority_queue<T>	ppqueue stl_variable
    std::bitset<n>td>	pbitset stl_variable
    std::string	pstring stl_variable
    std::widestring	pwstring stl_variable
    

  • 相关阅读:
    POJ 1840 Eqs 二分+map/hash
    【vijos】P1514天才的记忆
    函数介绍
    函数参数和函数返回值
    函数参数和函数返回值
    前端项目里常见的十种报错及其解决办法
    前端项目里常见的十种报错及其解决办法
    BootstrapTable的使用教程
    BootstrapTable的使用教程
    前端js实现打印(导出)excel表格
  • 原文地址:https://www.cnblogs.com/wangfengju/p/6172360.html
Copyright © 2011-2022 走看看