# | |
# 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].\n", $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].\n", $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\n", $size | |
printf "Vector capacity = %u\n", $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 \n", $size | |
if $argc == 1 | |
printf "List " | |
whatis $arg0 | |
printf "Use plist <variable_name> <element_type> to see the elements in the list.\n" | |
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 \n", $size | |
if $argc == 1 | |
printf "List " | |
whatis $arg0 | |
printf "Use plist_member <variable_name> <element_type> <member> to see the elements in the list.\n" | |
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.\n" | |
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\n", $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\n", $ElementsFound | |
end | |
printf "Map size = %u\n", $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.\n" | |
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\n", $ElementsFound | |
end | |
printf "Map size = %u\n", $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.\n" | |
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\n", $ElementsFound | |
end | |
printf "Set size = %u\n", $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\n", $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\n", $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\n", $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\n", $size | |
printf "Priority queue capacity = %u\n", $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 \t\t\t= \"%s\"\n", $arg0._M_data() | |
printf "String size/length \t= %u\n", $arg0._M_rep()._M_length | |
printf "String capacity \t= %u\n", $arg0._M_rep()._M_capacity | |
printf "String ref-count \t= %d\n", $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 \t\t= \"%ls\"\n", $arg0._M_data()) | |
printf "WString size/length \t= %u\n", $arg0._M_rep()._M_length | |
printf "WString capacity \t= %u\n", $arg0._M_rep()._M_capacity | |
printf "WString ref-count \t= %d\n", $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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment