Print stream value in gdb - C++
Asked Answered
W

7

15

I'm trying to see the value of stream (ifstream, but it should work for all kind of streams I guess). The example code could look like this:

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

I was trying to do it in following ways but none of them seems to work:

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

... and so on.

Is there any way, to see the value of the stream?

Wanettawanfried answered 4/12, 2011 at 21:25 Comment(1)
Is it a stringstream or an ifstream? There is no way to get a file's content this way!Fawn
A
15

You have to make sure that you have the package with the libstdc++ library compiled with the debugging flags.

I have the libstdc++6-8-dbg package installed and now I can view all the stream object data in gdb.

Armpit answered 6/9, 2012 at 5:36 Comment(3)
Sorry but this caused further problems for me. I'm using WSL(Windows Subsystem for Windows) Debian btw.Calicle
I downloaded libstdc++6-10-dbg and it doesn't workHellas
@Hellas try export LD_PRELOAD=<your path to the debug libstdc++.so> before debugging your program, e.g. export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/debug/libstdc++.soGailgaile
L
4

I got what I needed by recompiling everything (not just one or two translation units) with -D_GLIBCXX_DEBUG. Then I can just do

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

where is is a std::istream&. Previously I was getting

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

Also, when I only rebuilt one compilation unit, it ran but crashed with

...
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)

See also: http://gcc.gnu.org/onlinedocs/libstdc++/manual/debug_mode_using.html#debug_mode.using.mode

Literalminded answered 18/9, 2013 at 12:19 Comment(0)
S
2

Quick Solution

To find out which version of libstdc++-dbg package will work: type apt-cache search libstdc++ | grep dbg in the terminal. Find the latest version package, which is in the format libstdc++6-5-dbg.

On one of my machines libstdc++6-5-dbg works, while on the other one libstdc++6-8-dbg does.

Installing libstdc++6-8-dbg worked for me too. I have a 18.04 bionic beaver. Earlier I tried installing a dbg version that matched my libstdc++-dev version, but that did not work.

Thorough Solution:

  1. If you see <incomplete type> when trying to print a string inside gdb, then you need to install a packages similar to libstdc++6-8-dbg available for your dist. Run ldd <executable> . You will see an output like:
    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)

If you do not see a debug version in the libstdc++.so.6 link, then try to locate the corresponding library using locate libstdc++.so.6. Include that debug directory with the -L flag during linking stage of your executable. Also include the same directory in -rpath to include it in the runtime library. Recompile your executable. Run again ldd <executable> to verify if the debug directory is included or not. This takes care of the incomplete type.

  1. Now while trying to print a string if you see an output like this:
$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}}

then your gdb version needs a pretty printer. First verify that the gdb is installed with python support, which can be found out by typing show configuration in gdb:

(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)

Look inside gdb-datadir by typing ls /home/zephyr/utils/gdb-8.3-install/share/gdb. If you do not see a python folder, then your gdb needs to be installed with python support. Ensure that python-dev is installed before configuring, compiling and installing your gdb. Now install the pretty printers by following the instructions given on this page: https://sourceware.org/gdb/wiki/STLSupport.

Congratulations! you now have pretty printers installed.

Soft answered 7/11, 2019 at 18:22 Comment(4)
This answer has been given before. Upvote if you agree, do not repeat the answerDegroot
I do not have enough reputations either to comment or to upvote. I am only pointing out that this particular package worked for me even though I have a different version of libstdc++.Soft
Shared a more general answer that works on different machines.Soft
This helped me. In my case just installing sudo apt install libstdc++6-8-dbg did not work. I forced LD_LIBRARY_PATH=/lib/x86_64-linux-gnu/debug before running gdb and the debug version of the library was correctly loaded.Jellybean
F
0

Did you try print in.str() or even print in.str().c_str()

because stringstream has a str method giving a std::string, and string has a c_str method giving a char*

Fawn answered 4/12, 2011 at 21:29 Comment(2)
Yes, in both cases I get: "Couldn't find method std::ifstream::str" Did I missed some options for gdb to include c++ libraries?Wanettawanfried
ifstream doesn't have a method named strSnowden
B
0

No. The entire idea of a stream is that it reads data as it becomes available, be it from a hard drive, from the network, or from whatever. For example, I could write a class supporting streams that just indefinitely emitted the character 'a'.

If you want to do this, you're going to just have to write a helper function in your own program which reads the required data from the stream.

Beheld answered 4/12, 2011 at 22:2 Comment(3)
but it is a stringstream not an ordinary file based ifstream !Fawn
In the top of the question, he mentions using ifstream!Beheld
When I'm debugging stringstream I try things like this: print in.str() and I get Couldn't find method std::stringstream::str. How come? It is stringstream method. And when I use ifstrem, i do: call cout << in.get() and again I get Couldn't find method std::ifstream::getWanettawanfried
N
0

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

Nevil answered 18/12, 2017 at 2:57 Comment(0)
V
0

I was getting error from gdb std::ifstream::is_open method not found. My search for an answer led me to this thread. If you are working in Cygwin, package libstdc++6-8-dbg doesn't exist. I found that installing Cygwin package gcc-debuginfo worked.

Varhol answered 9/9, 2021 at 16:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.