LLDB not printing contents of std::vector on code compiled with gcc/g++

Viewed 559

I am trying to use a debugger with VScode on my mac. For some reason gdb won't work even after code-signing. It exits with error 134. However, it seems to work fine on command line. VScode will work fine with lldb and clang compiler and would display the contents of STL containers properly.

However, I need to use GCC compilers for some reason. As I already told, GDB is not working with VScode so I am trying to get LLDB working. However, LLDB is not displaying stl containers properly. When I compile with "-g" flag lldb does not display the contents of stl containers properly at all. It shows raw contents of the containers without any pretty printing. When i compile with "-gdwarf-3" or "-gdwarf-4" flag, it is able to display strings properly. But not the contents of vectors. It just says vector with size=0 and doesn't update as i push elements into vector. Is there any way/solution to get any of the debuggers (lldb/gdb) to work properly with pretty printing to debug files compiled with gcc compilers.

I have tried gcc versions 11 and 9, as well gdb versions 8 and 10 without any success.

1 Answers

As you saw from the raw printing, the native layout of a std::vector isn't very helpful, and the debugger needs to process the data to make it more user-friendly. lldb uses "synthetic child providers" to do that job (more on those here: https://lldb.llvm.org/use/variable.html#synthetic-children).

Since the internal details of the GNU & clang STL implementations, they need their own separate synthetic child providers.

lldb ships with a fairly complete set of built-in data formatters for the clang STL implementation. It also has a small set of gnu libstdc++ formatters, in the sources here:

https://github.com/llvm/llvm-project/blob/main/lldb/examples/synthetic/gnu_libstdcpp.py

They also ship with the LLDB distribution (on macOS in LLDB.framework/Resources/Python/lldb/formatters/cpp) and should be registered by lldb. There is one for std::vectors there. The formatters are assigned by a type matching.

You can tell whether a given variable has matches a synthetic provider by doing:

(lldb) type synthetic info myVec
synthetic applied to (std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >) myVec is:  libc++ std::vector synthetic children

That's the output for a libc++ std::vector. You should see something similar for the GUN std::vector, which is registered with a type matching expression:

^std::vector<.+>(( )?&)?$:  Python class lldb.formatters.cpp.gnu_libstdcpp.StdVectorSynthProvider

(that's the output of type synthetic list). The first element is the match pattern for the type. You might check what the actual demangled name of the std::vector class is, maybe something is changing the name so that we are't matching it anymore?

One caveat about type synthetic list the type formatter lists are built lazily so you have to try to print something C++ before you will see the full list.

Related