在 gdb 中打印流值 - C++

问题描述 投票:0回答:8

我正在尝试查看流的价值(ifstream,但我猜它应该适用于所有类型的流)。 示例代码可能如下所示:

stringstream in("One Two Three Four Five");
while(in)
cout << in;

我试图通过以下方式做到这一点,但似乎都不起作用:

(gdb) print in
(gdb) call cout << in
(gdb) call in.getline()

...等等。

有什么办法可以看到流的价值吗?

c++ stream gdb
8个回答
15
投票

您必须确保您拥有带有使用调试标志编译的

libstdc++
库的包。

我安装了

libstdc++6-8-dbg
软件包,现在我可以在
gdb
中查看所有流对象数据。


4
投票

我通过使用

-D_GLIBCXX_DEBUG
重新编译所有内容(不仅仅是一两个翻译单元)得到了我需要的东西。那我就可以了

(gdb) p is.tellg()
$21 = {_M_off = 0, _M_state = {__count = 0, __value = {__wch = 0, __wchb = "\000\000\000"}}}
(gdb) 

其中

is
std::istream&
。以前我得到

(gdb) p is.tellg()
Couldn't find method std::istream::tellg
(gdb) p is

另外,当我只重建一个编译单元时,它运行但崩溃了

...
305d85d000-305d85e000 r--p 0005d000 fd:01 1180082                        /lib64/libfreebl3.so
305d85e000-305d85f000 rw-p 0005e000 fd:01 118
Program received signal SIGABRT, Aborted.
0x0000003052e35215 in raise () from /lib64/libc.so.6
(gdb)

另请参阅:http://gcc.gnu.org/onlinedocs/libstdc++/manual/debug_mode_using.html#debug_mode.using.mode


2
投票

快速解决方案

要了解哪个版本的 libstdc++-dbg 软件包适用:在终端中输入

apt-cache search libstdc++ | grep dbg
。找到最新版本包,格式为
libstdc++6-5-dbg
.

在我的一台机器上

libstdc++6-5-dbg
可以工作,而在另一台机器上
libstdc++6-8-dbg
可以。

安装

libstdc++6-8-dbg
也对我有用。我有一只 18.04 仿生海狸。早些时候,我尝试安装与我的 libstdc++-dev 版本匹配的 dbg 版本,但这不起作用。

彻底的解决方案:

  1. 如果您在尝试在 gdb 中打印字符串时看到
    <incomplete type>
    ,那么您需要安装类似于您所在地区可用的
    libstdc++6-8-dbg
    的软件包。运行
    ldd <executable>
    。您将看到如下输出:
    linux-vdso.so.1 =>  (0x00007ffe4cbea000)
    libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/debug/libstdc++.so.6 (0x00007f523eab1000)
    libmpi.so.12 => /opt/mpich-3.2/lib/libmpi.so.12 (0x00007f523e36c000)

如果您在

libstdc++.so.6
链接中没有看到调试版本,请尝试使用
locate libstdc++.so.6
查找相应的库。在可执行文件的链接阶段,包含带有
-L
标志的调试目录。还要在
-rpath
中包含相同的目录,以将其包含在运行时库中。重新编译您的可执行文件。再次运行
ldd <executable>
以验证是否包含调试目录。这可以解决不完整的类型。

  1. 现在,在尝试打印字符串时,如果您看到如下输出:
$1 = {static npos = 18446744073709551615, 
  _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, 
    _M_p = 0x7fffffffda70 "dump-000"}, _M_string_length = 8, {_M_local_buf = "dump-000\000\000\000\000\000\000\000", 
    _M_allocated_capacity = 3472328284420535652}}

那么你的 gdb 版本需要一个漂亮的打印机。首先验证gdb是否安装了python支持,可以通过在gdb中输入

show configuration
来找到:

(gdb) show configuration
This GDB was configured as follows:
   configure --host=x86_64-pc-linux-gnu --target=x86_64-pc-linux-gnu
             --with-auto-load-dir=$debugdir:$datadir/auto-load
             --with-auto-load-safe-path=$debugdir:$datadir/auto-load
             --with-expat
             --with-gdb-datadir=/home/zephyr/utils/gdb-8.3-install/share/gdb (relocatable)
             --with-jit-reader-dir=/home/zephyr/utils/gdb-8.3-install/lib/gdb (relocatable)
             --without-libunwind-ia64
             --without-lzma
             --without-babeltrace
             --without-intel-pt
             --disable-libmcheck
             --without-mpfr
             --without-python
             --without-guile
             --disable-source-highlight
             --with-separate-debug-dir=/home/zephyr/utils/gdb-8.3-install/lib/debug (relocatable)

通过输入

gdb-datadir
查看内部
ls /home/zephyr/utils/gdb-8.3-install/share/gdb
。如果您没有看到 python 文件夹,则您的
gdb
需要安装
python
支持。在配置、编译和安装
python-dev
之前,请确保已安装
gdb
。现在按照本页给出的说明安装漂亮的打印机:https://sourceware.org/gdb/wiki/STLSupport

恭喜!您现在已经安装了漂亮的打印机。


0
投票

不。流的整个想法是,它在数据可用时读取数据,无论是从硬盘驱动器、从网络还是从其他任何地方。例如,我可以编写一个支持流的类,它无限期地发出字符“a”。

如果您想这样做,您只需在自己的程序中编写一个辅助函数,该函数从流中读取所需的数据。


0
投票

你尝试过吗

print in.str()
甚至
print in.str().c_str()

因为

stringstream
有一个
str
方法
给出
std::string
,并且
string
有一个
c_str
方法
给出
char*


0
投票

(gdb) call 'operator<<'(_ZSt4cout, your_object)


0
投票

我从 gdb std::ifstream::is_open 方法未找到时收到错误。我对答案的寻找将我引向了这个话题。如果您在 Cygwin 中工作,则 libstdc++6-8-dbg 包不存在。我发现安装 Cygwin 包 gcc-debuginfo 有效。


0
投票

使用此处描述的方法,我无法获取 istream 流的内容。也许有某种使用 python 的选项?

© www.soinside.com 2019 - 2024. All rights reserved.