gdb查看unordered_map等stl容器内容

现象

在默认gdb操作下,查看unordered_map时,输出信息中只包含了很多STL库内部数据结构,但无法直观查看其中的节点数据。如下所示:

p m_trace_map
$1 = {
  _M_h = {
    <std::__detail::_Hashtable_base<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, msrpi::TraceFlowInfo_T<std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >, std::__detail::_Select1st, std::equal_to<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::hash<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Hashtable_traits<true, false, true> >> = {
      <std::__detail::_Hash_code_base<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, msrpi::TraceFlowInfo_T<std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >, std::__detail::_Select1st, std::hash<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, true>> = {
        <std::__detail::_Hashtable_ebo_helper<0, std::__detail::_Select1st, true>> = {
          <std::__detail::_Select1st> = {<No data fields>}, <No data fields>},
        <std::__detail::_Hashtable_ebo_helper<1, std::hash<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, true>> = {
          <std::hash<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >> = {
            <std::__hash_base<unsigned long, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >> = {<No data fields>}, <No data fields>}, <No data fields>},
        <std::__detail::_Hashtable_ebo_helper<2, std::__detail::_Mod_range_hashing, true>> = {
          <std::__detail::_Mod_range_hashing> = {<No data fields>}, <No data fields>}, <No data fields>},
      <std::__detail::_Hashtable_ebo_helper<0, std::equal_to<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, true>> = {
        <std::equal_to<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >> = {
          <std::binary_function<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool>> = {<No data fields>}, <No data fields>}, <No data fields>}, <No data fields>},
    <std::__detail::_Map_base<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, msrpi::TraceFlowInfo_T<std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<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, msrpi::TraceFlowInfo_T<std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > > >, std::__detail::_Select1st, std::equal_to<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::hash<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true>, true>> = {<No data fields>},
    <std::__detail::_Insert<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, msrpi::TraceFlowInfo_T<std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<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, msrpi::TraceFlowInfo_T<std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > > >, std::__detail::_Select1st, std::equal_to<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::hash<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true>, false>> = {
      <std::__detail::_Insert_base<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, msrpi::TraceFlowInfo_T<std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<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, msrpi::TraceFlowInfo_T<std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > > >, std::__detail::_Select1st, std::equal_to<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::hash<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true> >> = {<No data fields>}, <No data fields>},
    <std::__detail::_Rehash_base<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, msrpi::TraceFlowInfo_T<std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<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, msrpi::TraceFlowInfo_T<std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > > >, std::__detail::_Select1st, std::equal_to<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::hash<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true>, std::integral_constant<bool, true> >> = {<No data fields>},
    <std::__detail::_Equality<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, msrpi::TraceFlowInfo_T<std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<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, msrpi::TraceFlowInfo_T<std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > > >, std::__detail::_Select1st, std::equal_to<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::hash<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true>, true>> = {<No data fields>},
    <std::__detail::_Hashtable_alloc<std::allocator<std::__detail::_Hash_node<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, msrpi::TraceFlowInfo_T<std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >, true> > >> = {
      <std::__detail::_Hashtable_ebo_helper<0, std::allocator<std::__detail::_Hash_node<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, msrpi::TraceFlowInfo_T<std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >, true> >, true>> = {
        <std::allocator<std::__detail::_Hash_node<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, msrpi::TraceFlowInfo_T<std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >, true> >> = {
          <__gnu_cxx::new_allocator<std::__detail::_Hash_node<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, msrpi::TraceFlowInfo_T<std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >, true> >> = {<No data fields>}, <No data fields--Type <RET> for more, q to quit, c to continue without paging--
>}, <No data fields>}, <No data fields>},
    members of std::_Hashtable<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, msrpi::TraceFlowInfo_T<std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<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, msrpi::TraceFlowInfo_T<std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > > >, std::__detail::_Select1st, std::equal_to<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::hash<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<true, false, true> >:
    _M_buckets = 0x2ba0f9891e50,
    _M_bucket_count = 62233,
    _M_before_begin = {
      _M_nxt = 0x2ba0a81e2560
    },
    _M_element_count = 25000,
    _M_rehash_policy = {
      static _S_growth_factor = 2,
      _M_max_load_factor = 1,
      _M_next_resize = 62233
    },
    _M_single_bucket = 0x0
  }
}
(gdb)

修改

  • 执行如下命令查看libstdcxx路径

    find / -name "libstdcxx*" 2>/dev/null
    
  • 结果类似如下。需注意,该美化必须具有gcc7.3.0及以上版本的支持,如果gcc版本过低,需要先进行升级

    /usr/share/gcc-4.8/python/libstdcxx
    /usr/local/share/gcc-7.3.0/python/libstdcxx
    
  • 用户根路径下新建.gdbinit文件

    pekphisprb09546:~ # vi .gdbinit
    
  • .gdbinit文件中输入如下内容并保存(只需修改sys.path.insert中的路径信息)

    python
    import sys
    sys.path.insert(0, '/usr/local/share/gcc-7.3.0/python/libstdcxx')
    from v6.printers import register_libstdcxx_printers
    register_libstdcxx_printers (None)
    end
    

效果

重新运行gdb后,查看到的效果如下。需注意使用set print pretty on命令打开美化开关

(gdb) f 3
#3  0x00000000005562dc in msrpi::Statistic::print_svc_trace_flow (this=0x134bed80, flowinfo=..., is_start=false) at stat/Statistic.cpp:173
173                 if (m_trace_map.size() > 50000)
(gdb) set print pretty on
(gdb) p m_trace_map
$1 = std::unordered_map with 25000 elements = {
  ["C13212172021236352159536342613900150065-MO"] = {
    errorCode = 0,
    flowFlag = 0,
    appSeq = 1046,
    id = "C13212172021236352159536342613900150065-MO",
    caller = "sip:+8613900150065@rcs.ims.mnc000.mcc460.3gppnetwork.org",
    callee = "sip:+8613900151065@rcs.ims.mnc000.mcc460.3gppnetwork.org",
    flowErrorDesc = "",
    flowDescs = std::vector of length 6, capacity 8 = {"GetSession:1595363462", "TCP-CONNECT:1595363462", "OnNotify<Connected>:1595363462", "W-XSTORE-OK:1595363462",
      "OnNotify<TransferSuccess>:1595363462", "OnNotify<ConnectClose>:1595363462"},
    lastTime = 1595363462
  },
  ["C13212071471236352159536342513900150011-MO"] = {
    errorCode = 0,
    flowFlag = 0,
    appSeq = 1275,
    id = "C13212071471236352159536342513900150011-MO",
    caller = "sip:+8613900150011@rcs.ims.mnc000.mcc460.3gppnetwork.org",
    callee = "sip:+8613900151011@rcs.ims.mnc000.mcc460.3gppnetwork.org",
    flowErrorDesc = "",
    flowDescs = std::vector of length 6, capacity 8 = {"GetSession:1595363461", "TCP-CONNECT:1595363461", "OnNotify<Connected>:1595363461", "W-XSTORE-OK:1595363461",
      "OnNotify<TransferSuccess>:1595363461", "OnNotify<ConnectClose>:1595363461"},
    lastTime = 1595363461
  },
......