Skip to main content

Command Palette

Search for a command to run...

gdb查看unordered_map等stl容器内容

Published
4 min readView as Markdown

现象

在默认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
  },
......
2.0K views

More from this blog

新装Linux需进行的配置

但凡喜欢折腾虚拟机或者云服务器什么的,总是免不了重装1,2,3...n...次Linux系统,有些操作只是无情的体力活,做个总结对照着操作当然会快上很多。不过这方面的总结已经烂大街了,而且我也不觉得自己写出来的东西能够比其他人更出色,所以此处只是一个无情的优质链接归类,用以归档一些新装Linux系统总是会执行的一些操作 磁盘 磁盘的格式化和分区:Linux 磁盘分区、格式化、目录挂载 磁盘的UUID与开机自动挂载:Linux磁盘分区UUID的获取及其UUID的作用 国内源 Linux自带的系...

Sep 10, 20211 min read72

PostgreSQL中的VFD机制

概述 通常来说,操作系统对于单个进程中能打开的文件数是有限制的,而数据库需要频繁的操作文件。为了方便使用,pg实现了VFD(Virtual File Description,虚拟文件描述符)机制,本质是对与底层文件操作的一层封装,这样所有需要直接操作文件的地方可以调用VFD,避免上层还需要管理文件操作符。 这层封装主要是采用了一个LRU(Leaset Recently Used)缓存池来管理本进程中打开的所有VFD。当LRU池未满时,进程可以直接申请一个VFD用来打开一个物理文件;而当LRU池已...

Aug 29, 20212 min read113

PostgreSQL中的pg_stat

pg_stat(包括pg_stat_xx)这一系列视图及其功能,在官方手册里都被划归在Postgresql统计收集器下面,用于收集信息和报告服务器的活跃性。各个视图的具体作用可以主要参照官方手册中的相应介绍 下述的分析内容皆为pg9.2版本源码 整体分析 pg_stat作为PostgreSQL数据库的状态统计和信息收集的作用,其触发点有多处: autovacuum launcher process stats collector process 手动vacuum和analyze 其中手动...

Aug 29, 20214 min read57

C和Cpp编译链接过程

以下介绍中有2个约定: 下面介绍中使用的编译器为gcc/g++,所有执行命令中gcc可以与g++互换 gcc/g++编译命令允许跳过中间文件的生成,而直接得到所需的输出文件。但为了逻辑连贯,默认每一阶段将以上一阶段的输出文件作为源文件,后续不在赘述 整体介绍 C和Cpp代码编译链接的整体过程如下: 狭义上来说,编译就是指上图中从预处理文件到汇编语言文件的这个阶段,但是广义上来说,编译是链接之前的所有阶段。每个人的叫法并不相同,需要具体看待。不过下面的分析中,为了更详细的介绍,所以遵循狭义上...

Aug 29, 20212 min read60
L

LemonTea

5 posts

以书识温养体悟,以时间见心明性