我已将此作为第一步:用于 gdb 的简单 stl 容器检查器。我没有设法pmap
直接使用,但我利用它并创建了自己的 scrupt my_pmap:
>cat my.txt
define my_pmap
set $my_obj = *((std::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::string*, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::string*> > >*) $arg0)
print $my_obj
set $i = 0
set $node = $my_obj._M_t._M_impl._M_header._M_left
set $end = $my_obj._M_t._M_impl._M_header
set $tree_size = $my_obj._M_t._M_impl._M_node_count
while $i < $tree_size
set $value = (void *)($node + 1)
printf "elem[%u].left: ", $i
p *( std::basic_string<char, std::char_traits<char>, std::allocator<char> >*)$value
set $value = $value + sizeof(std::basic_string<char, std::char_traits<char>, std::allocator<char> >)
printf "elem[%u].right: ", $i
p **((std::basic_string<char, std::char_traits<char>, std::allocator<char> >**)$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=$i+1
end
printf "Map size = %u\n", $tree_size
end
然后我写了一个简短的 C++ 测试程序:
#include <map>
#include <string>
#include <iostream>
int main()
{
std::string local_s1 = "Local1";
std::string local_s2= "Local2";
typedef std::map<std::string, std::string*> my_type_t;
my_type_t my_map;
my_map.insert(std::make_pair("Key-string-1", &local_s1));
my_map.insert(std::make_pair("Key-string-2", &local_s2));
my_map.insert(std::make_pair("Key-string-3", &local_s2));
return 0;
}
然后我测试了我的脚本:
>gdb -q ./a.out
Reading symbols from /import/home/sergey.kurenkov/src/linux.x64.6.0/tests/test.gdb_map/a.out...done.
(gdb) start
Temporary breakpoint 1 at 0x400c7c: file main.cpp, line 7.
Starting program: /import/home/sergey.kurenkov/src/linux.x64.6.0/tests/test.gdb_map/a.out
Temporary breakpoint 1, main () at main.cpp:7
7 std::string local_s1 = "Local1";
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.80.el6.x86_64
(gdb) source my.txt
(gdb) n
8 std::string local_s2= "Local2";
(gdb)
11 my_type_t my_map;
(gdb)
12 my_map.insert(std::make_pair("Key-string-1", &local_s1));
(gdb)
13 my_map.insert(std::make_pair("Key-string-2", &local_s2));
(gdb)
14 my_map.insert(std::make_pair("Key-string-3", &local_s2));
(gdb)
16 return 0;
(gdb) p &my_map
$1 = (my_type_t *) 0x7fffffffe040
(gdb) my_pmap 0x7fffffffe040
elem[0].left: $2 = {static npos = 18446744073709551615, _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x603088 "Key-string-1"}}
elem[0].right: $3 = {static npos = 18446744073709551615, _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x603028 "Local1"}}
elem[1].left: $4 = {static npos = 18446744073709551615, _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x6030f8 "Key-string-2"}}
elem[1].right: $5 = {static npos = 18446744073709551615, _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x603058 "Local2"}}
elem[2].left: $6 = {static npos = 18446744073709551615, _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x603168 "Key-string-3"}}
elem[2].right: $7 = {static npos = 18446744073709551615, _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x603058 "Local2"}}
Map size = 3
(gdb)