Should clang++ -g produce debugging info for all types?

On Fedora 30, "clang++ -g main.cc" does not emit debugging information
for types such as std::string. I can only get complete debugging
information by including "-fno-limit-debug-info".

On Ubuntu 19.04, "clang++ -g" emits debugging info for std::string as expected.

Which behavior of "-g" is correct? Can anyone explain why each
platform behaves differently?

No, it shouldn’t - clang attempts to avoid emitting duplicate debug info across the program (it assumes you built the whole program and all libraries with debug info), gcc assumes the same thing though in slightly different/fewer ways.

The solution is to install the -dbg build of your libstdc++ package (assuming you’re using libstdc++), it will include debug info for the standard library, including std::string.

To see a case where GCC does the same thing - try a variable of type std::fstream. GCC, similarly, will produce only a declaration for the basic_fstream type, not the definition.

(& here’s a lightning talk that discusses, briefly, some of this: https://www.youtube.com/watch?v=XvkLHIASlp8 )

Thanks for the pointer. Based on what you told me, I was able to dig
deeper and found these relevant links:

https://bugs.llvm.org/show_bug.cgi?id=24202#c1
https://stackoverflow.com/questions/41745527/cannot-view-stdstring-when-compiled-with-clang

I installed the debug version of libstd++ on my Fedora system with
"dnf debuginfo-install libstdc++" and I now see a debug version of
libstdc++:

$ file /usr/lib/debug/lib64/libstdc++.so.6.0.26-9.1.1-1.fc30.x86_64.debug
/usr/lib/debug/lib64/libstdc++.so.6.0.26-9.1.1-1.fc30.x86_64.debug:
ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux),
dynamically linked,
BuildID[sha1]=3b2e1aaafd0cb7e1ebd75627d4cde2504c927159, with
debug_info, not stripped

I don't have things working though. I still don't see std::string
info when debugging. My executable is linked against the non-debug
version:

$ ldd a.out
    linux-vdso.so.1 (0x00007ffec03fe000)
    libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f2fccd31000)
    libm.so.6 => /lib64/libm.so.6 (0x00007f2fccbeb000)
    libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f2fccbd1000)
    libc.so.6 => /lib64/libc.so.6 (0x00007f2fcca0b000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f2fccf45000)

Is that my problem? Or does LLDB somehow know to use the version in
/usr/lib/debug/lib64?

I'm also puzzled about why the debug version was put in /usr/lib and
not /usr/lib64.

Does it work with gdb? I’m guessing maybe lldb doesn’t support the build-id feature that redhat uses ( https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/developer_guide/intro.debuginfo ) ?

I’d try gdb + gcc + binutils ld (or gold) + libstdc++ (use std::fstream as an example of something that gcc will home to the libstdc++ debug info - dwarfdump your executable and you’ll see it doesn’t contain the definition of basic_fstream, but verify the debugger can still render the full definition). If that works, swap out various parts of that & see where it falls apart.

Does it work with gdb?

It works with gdb. More info:

g++ & gdb -- works, even without debuginfo for libstdc++
clang++ & gdb -- works
g++ & lldb -- works
clang++ & lldb -- fails

I now notice these warnings in lldb after installing the debuginfo packages:

warning: (x86_64) /lib64/libstdc++.so.6 unsupported DW_FORM values:
0x1f20 0x1f21
warning: (x86_64) /lib64/libgcc_s.so.1 unsupported DW_FORM values: 0x1f20 0x1f21

I searched the web for details on that error, but came up empty.
Could it be that the debuginfo packages are just not compatible with
lldb?

I'd try gdb + gcc + binutils ld (or gold) + libstdc++ (use std::fstream as an example of something that gcc will home to the libstdc++ debug info - dwarfdump your executable and you'll see it doesn't contain the definition of basic_fstream, but verify the debugger can still render the full definition). If that works, swap out various parts of that & see where it falls apart.

Good strategy. I don't quite have the hang of dwarfdump yet though,
but I'll continue to investigate.

Does it work with gdb?

It works with gdb. More info:

g++ & gdb – works, even without debuginfo for libstdc++

^ for std::string I’d expect this. For std::fstream, I expect you’d see the same problem/failure (gcc and clang both rely on fstream being homed in the standard library’s debug info (because of vtables/key functions), but clang takes it a step further and does this for std::string too (because of template explicit instantiation decl/def))

clang++ & gdb – works
g++ & lldb – works

^ again, I expect that would fail with std::fstream, demonstrating that the same problem exists for both clang and GCC, just clang takes it a bit further - but it’s not fundamentally different between the two.

clang++ & lldb – fails

I now notice these warnings in lldb after installing the debuginfo packages:

warning: (x86_64) /lib64/libstdc++.so.6 unsupported DW_FORM values:
0x1f20 0x1f21
warning: (x86_64) /lib64/libgcc_s.so.1 unsupported DW_FORM values: 0x1f20 0x1f21

I searched the web for details on that error, but came up empty.
Could it be that the debuginfo packages are just not compatible with
lldb?

Ooh, yeah, that’s possible/likely. Unknown forms can’t be ignored because forms dictate the encoding, so without recognizing the form, the DWARF can’t be parsed (unknown /attributes/ using known forms are fine - because they can be parsed and the values ignored).

Yeah, looks like 1f20 (DW_FORM_GNU_ref_alt) and 1f21 (DW_FORM_GNU_strp_alt) are results of the ‘dwz’ tool that compacts DWARF debug info.

Not sure if it’d be enough to teach lldb how to parse but ignore any attribute using these forms - I would guess not, I suspect that would result in holes in the debug info where these forms are used. So you’d probably have to modify/fix/patch lldb to actually be able to understand these forms - which might not be too hard. Hmm, nope, probably fairly involved, since it means reading a new/different file (judging by this patch and the link to the DWARF standards proposal in it: http://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20150518/277186.html ).

Summary:
Yeah, short of making some relatively significant changes to lldb, I think you’ll probably just have to stick with larger debug info by using -fstandalone-debug, since the debug info provided by your distribution uses GNU extensions that lldb doesn’t currently support. :confused: