DWARF debug info version on macOS and 'std::' namespace (and pretty-printers)

Philippe Blain levraiphilippeblain@gmail.com
Sun Mar 7 04:34:04 GMT 2021


Hi Jonathan,

Le 2021-03-05 à 13:19, Jonathan Wakely a écrit :
> 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.

Yes, I also tried on Ubuntu 18 and couldn't reproduce either (sorry
for not mentioning!).

>> 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.
I would think it's what GCC emits though, since LLDB acts similarly (although
I could be wrong...)

>>
>> 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'll try to have a look into that.

> 
> I wonder if this affects Windows too, and other targets that don't use
> the ELF library naming scheme.

I'm new to Windows, but I just installed MinGW-w64 (that includes GDB)
to check. The *-gdb.py file for libstdc++ is actually at the following path:

$installdir\lib\gcc\x86_64-w64-mingw32\8.1.0\libstdc++.dll.a-gdb.py

but the actual dynamic library used in compiled programs (checked with
"info shared" in GDB) is $installdir\bin\libstdc++-6.dll.
However, the pretty printers do work because they install a global gdbinit
at $installdir\etc\gdbinit with the following content:

python
import sys
sys.path.insert(0, sys.path[0] + '/../../gcc-8.1.0/python')
from libstdcxx.v6.printers import register_libstdcxx_printers
register_libstdcxx_printers (None)
end

So I guess they are always loaded... I did not check other Windows
distributions of GDB/GCC.

Thanks for answering,

Philippe.



More information about the Libstdc++ mailing list