DWARF debug info version on macOS and 'std::' namespace (and pretty-printers)
Jonathan Wakely
jwakely@redhat.com
Fri Mar 5 18:19:46 GMT 2021
On 04/03/21 17:51 -0500, Philippe Blain via Libstdc++ wrote:
>Hello,
>
>I'm trying to understand why a 'std::vector<double>' appears in GDB as
>'type = vector<double, std::allocator<double> >' instead of 'std::vector<...>'
>
>I have this simple program:
>~~~cpp
>#include <vector>
>
>void here() {};
>
>int main() {
> std::vector<double> array(4);
> here();
>
> return 0;
>}
>~~~
>
>I'm using GCC 7.3 from Homebrew on my macOS 10.11.6 system, but I have similar
>behaviour with GCC 10.2 on macOS 10.15.7 in GitHub Actions.
>
>I compile with:
>
> g++-7 -g -O0 -std=c++11 test.cpp -o test
>
>and run GDB (self-compiled, 11.0.50.20210223-git) with:
>
> gdb test --batch -ex 'b here' -ex run -ex up -ex 'whatis array'
>
>I get 'type = vector<double, std::allocator<double> >'.
>If I compile with '-gdwarf-3' instead of just '-g', then I get
>'type = std::vector<double>'.
>
>From the documentation [1], I understand that '-g' defaults to dwarf-2 on macOS,
>but I do not understand what the DWARF version has to do with the fact that 'vector'
>is seen by GDB in the global or 'std::' namespace...
I can't reproduce this using -gdwarf-2 on GNU/Linux, so it seems to be
a peculiarity of DWARF 2 on MacOS. Either what GCC emits, or what GDB
consumes.
>The behaviour is similar when debugging with LLDB:
>
> lldb --batch -o 'b 7' -o r -o 'p array' test
>
>shows '(vector<double, allocator<double> >) $0 = { ...' for DWARF-2
>and '(std::vector<double, std::allocator<double> >) $0 = ...' for DWARF-3.
>
>Incidentally, it seems that defaulting to DWARF-2 on macOS is a decision taken in 2009
>(stemming from 047a3193bd729475182a438d9929ec923f484481, From-SVN: r152127 [2])
>and I'm wondering if it's still the best thing to do ?
>
>Finally, I was dragged down this hole trying to understand why the Python pretty-printers
>were not working on my machine. Having 'vector' correctly identified in the 'std::' namespace
>was one part of the solution, but I also had to create a symlink named
>/usr/local/Cellar/gcc/7.3.0_1/lib/gcc/7/libstdc++.6.dylib-gdb.py
>pointing to the existing /usr/local/Cellar/gcc/7.3.0_1/lib/gcc/7/libstdc++.a-gdb.py
>for the pretty printers to be loaded automatically. Looking at gcc/libstdc++-v3/python/Makefile.am
>it seems that a file named 'libstdc++.6.dylib-gdb.py' *should* have been created
>(at least from what I understand), but it seems this is not the case...
>I'm not sure why either. I also verified that on the GitHub Actions VM, for
>GCC 8, 9 and 10, only libstdc++.a-gdb.py exists...
I think we only install it with one name. For ELF targets that is the
shared library name:
/usr/bin/install -c -m 644 gdb.py /home/jwakely/gcc/11/lib/../lib64/libstdc++.so.6.0.29-gdb.py
The code loops over libstdc++.* (i.e. using the shell's sorting rules)
and takes the last name that isn't a symlink and isn't a .la or .py
file. For ELF targets where we have these names, the last one is the
one we want to use:
libstdc++.a
libstdc++.so
libstdc++.so.6
libstdc++.so.6.0.29
But if you have these names:
libstdc++.6.dylib
libstdc++.a
then the last one is going to be the .a not the dylib.
It shouldn't be *too* hard to fix that.
I wonder if this affects Windows too, and other targets that don't use
the ELF library naming scheme.
More information about the Libstdc++
mailing list