【问题标题】:How to dump STL container data in gdb?如何在 gdb 中转储 STL 容器数据?
【发布时间】:2017-05-05 14:46:34
【问题描述】:

我无法在 gdb 中转储 STL 无序映射容器值。变量类型是 std::unordered_map 变量;

我的 gdb 版本 - 7.7.1 gdb 配置:

 configure --host=x86_64-linux-gnu --target=x86_64-linux-gnu
             --with-auto-load-dir=$debugdir:$datadir/auto-load
             --with-auto-load-safe-path=$debugdir:$datadir/auto-load
             --with-expat
             --with-gdb-datadir=/usr/local/share/gdb (relocatable)
             --with-jit-reader-dir=/usr/local/lib/gdb (relocatable)
             --without-libunwind-ia64
             --with-lzma
             --with-separate-debug-dir=/usr/local/lib/debug (relocatable)
             --with-system-gdbinit=/etc/gdb/gdbinit
             --with-zlib
             --without-babeltrace

g++ (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4

打印 STL 容器值 n gdb 的正确方法是什么?

地图容器的gdb输出:

p 变量

$3 = {<std::__allow_copy_cons<true>> = {<No data fields>},                                                                                                                          [13/5219]
  _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<ch
ar> > const, Metrics_s*>, std::__detail::_Select1st, std::equal_to<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::hash<std::basic_string<char, std::ch
ar_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, Metric
s_s*>, std::__detail::_Select1st, std::hash<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >

【问题讨论】:

  • 正确地向我们展示您的尝试。此输出表明不是std::map
  • 这表明它是一个 std::unordered_map,虽然
  • 我怀疑 OP 的 libstdc++ 太旧了,无法使用漂亮的打印机。我花了一段时间将 gcc/libstdc++-v3/python/libstdcxx/v6/printers.py 的 libstdc++ 存储库一分为二,但是 github 用户界面非常糟糕,我放弃了尝试想出一个版本号来关闭。无论如何,OP 需要提供更多细节。
  • ptype /tm your_variable 的输出是什么?
  • info pretty-printer 的输出是什么?是否正确安装了漂亮的打印机?

标签: c++ stl gdb containers


【解决方案1】:

试试看这个:https://gcc.gnu.org/svn/gcc/trunk/libstdc++-v3/python/

并将这些行添加到您的:~/.gdbinit

python
import sys
sys.path.insert(0, '<Path to SVN Checkout Directory>')
from libstdcxx.v6.printers import register_libstdcxx_printers
register_libstdcxx_printers (None)
end

如果它不起作用,您可以从 SVN 签出更接近您正在使用的 GDB 版本的旧版本。

注意:假设您的 GDB 启用了 python 后端。

更新:如果您使用 Ubuntu 软件包中的 gdb 软件包,您可以尝试安装以下软件包以添加对 “STL 漂亮打印” 的支持:@ 987654324@.
有了这个更新,gdb 应该会自动支持 STL 容器的漂亮打印。

【讨论】:

    【解决方案2】:

    您的gdb --configuration 输出缺少--with-python 子句,所以我认为您的gdb 确实不能使用python 扩展。根据这个 SO 回答 gdb pretty printing is not working 似乎有必要让漂亮的打印工作。

    我在 docker 中的 ubuntu 14.04 带有漂亮的打印功能,并且 gdb 是使用 --with-python 配置的。看来,您的 gdb 安装是以某种方式定制的。您可以使用正确的选项从源重新编译 gdb,或者尝试从您的分发包中清除重新安装 gdb。

    【讨论】:

      【解决方案3】:

      1) 旧版本的 gdb 不需要 Python 来打印 STL 对象。 python的错误与您的配置有关。

      gdbinit 不是 gdb 配置

      2) 无论如何都有一个可行的解决方案:卸载并重新安装旧的(在你的发行版中寻找 stl 漂亮的打印包) gdb dbg 包还检查你的用户的 .bashrc (你可以在那里用 gdb 做一些你不做的事情'不想要),清除它,重新启动终端,它会工作。

      请注意,最近的 gdb 版本需要 只有特定版本和风格的 python,它们有很多错误,一些 Linux 发行版默认包含它们,这是它们的问题,gdb 不是一件事 - 这是一棵树。确保你得到正确的,在我看来它应该与 python 无关。

      这是描述 gdb 何时引入这个坏主意以及为什么人们似乎喜欢它的链接https://bbs.archlinux.org/viewtopic.php?id=87299

      【讨论】:

        【解决方案4】:

        我的猜测是您的系统中安装了 2 个 gdb 二进制文件:

        • Ubuntu 14.04 自带的一款
        • 您自己打造的一款

        根据gdb --configure 输出,您自己构建的打印机不支持python 漂亮打印机,因为它没有配置--with-python 选项。当您在命令提示符下键入 gdb 时,将调用此 gdb 二进制文件。

        但是应该从 Ubuntu dpkg 包中安装另一个二进制文件。它应该位于/usr/bin/gdb 并且应该支持漂亮的打印。尝试使用完整路径调用它:

        /usr/bin/gdb
        

        【讨论】:

          【解决方案5】:
          define dump_map
              #arg0 is  your unordered map address
              set $map = $arg0
              set $i = 0
              set $itr = $map._M_h._M_buckets[0]->_M_nxt
              while $i < $map._M_h._M_element_count
                  printf "Object name = [ %s ] and Object address = [0x%llx]\n", ((char *)((<give your map name> *)($itr))->_name) , $itr
                  set $itr  = $itr->_M_nxt
                  set $i = ($i + 1)
              end 
          end
          

          【讨论】:

          • 感谢您提供此代码 sn-p,它可能会提供一些有限的短期帮助。一个正确的解释would greatly improve 其长期价值,通过展示为什么这是解决问题的好方法,并将使其对未来有其他类似问题的读者更有用。请edit您的回答添加一些解释,包括您所做的假设。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-07-21
          • 2012-07-20
          • 1970-01-01
          • 2011-01-30
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多