[Lldb-commits] [lldb] 8b80e8e - [lldb] Disable looking at pointee types to find synthetic value for non-ObjC

Arthur Eubanks via lldb-commits lldb-commits at lists.llvm.org
Mon Nov 21 09:30:49 PST 2022


Author: Arthur Eubanks
Date: 2022-11-21T09:30:29-08:00
New Revision: 8b80e8ee1fca660a5ea58cf701c2af8bba0dd89b

URL: https://github.com/llvm/llvm-project/commit/8b80e8ee1fca660a5ea58cf701c2af8bba0dd89b
DIFF: https://github.com/llvm/llvm-project/commit/8b80e8ee1fca660a5ea58cf701c2af8bba0dd89b.diff

LOG: [lldb] Disable looking at pointee types to find synthetic value for non-ObjC

After D134378, we started seeing crashes with incomplete types (in the
context of shared libraries).

When trying to print a `std::vector<int> &` with only debug info for a
declaration, we now try to use the formatter after D134378. With an
incomplete type, this somehow goes into infinite recursion with the
frames

```
lldb_private::ValueObject::Dereference
lldb_private::ValueObjectSynthetic::CreateSynthFilter
lldb_private::ValueObjectSynthetic::ValueObjectSynthetic
lldb_private::ValueObject::CalculateSyntheticValue
lldb_private::ValueObject::HasSyntheticValue
```

This has to do with `FrontEndWantsDereference` that some STL formatters
set, causing recursion between the formatter (which tries to dereference),
and dereferencing (which wants to know if there's a formatter to avoid dereferencing).

The reason this only started appearing after D134378 was because
previously with incomplete types, for names with `<`, lldb would attempt
to parse template parameter DIEs, which were empty, then create an empty
`ClassTemplateSpecializationDecl` which overrode the name used to lookup
a formatter in `FormattersMatchData()` to not include template
parameters (e.g. `std::vector<> &`). After D134378 we don't create a
`ClassTemplateSpecializationDecl` when there are no template parameters
and the name to lookup a formatter is the original name (e.g.
`std::vector<int> &`).

The code to try harder with incomplete child compiler types was added in
D79554 for ObjC purposes.

Reviewed By: labath

Differential Revision: https://reviews.llvm.org/D137983

Added: 
    lldb/test/API/lang/cpp/incomplete-stl-types/Makefile
    lldb/test/API/lang/cpp/incomplete-stl-types/TestStlIncompleteTypes.py
    lldb/test/API/lang/cpp/incomplete-stl-types/f.cpp
    lldb/test/API/lang/cpp/incomplete-stl-types/main.cpp

Modified: 
    lldb/source/Core/ValueObject.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp
index 19d86bee40e1f..081f9c2cf5dcf 100644
--- a/lldb/source/Core/ValueObject.cpp
+++ b/lldb/source/Core/ValueObject.cpp
@@ -2673,7 +2673,10 @@ ValueObjectSP ValueObject::Dereference(Status &error) {
     // In case of incomplete child compiler type, use the pointee type and try
     // to recreate a new ValueObjectChild using it.
     if (!m_deref_valobj) {
-      if (HasSyntheticValue()) {
+      // FIXME(#59012): C++ stdlib formatters break with incomplete types (e.g.
+      // `std::vector<int> &`). Remove ObjC restriction once that's resolved.
+      if (Language::LanguageIsObjC(GetPreferredDisplayLanguage()) &&
+          HasSyntheticValue()) {
         child_compiler_type = compiler_type.GetPointeeType();
 
         if (child_compiler_type) {

diff  --git a/lldb/test/API/lang/cpp/incomplete-stl-types/Makefile b/lldb/test/API/lang/cpp/incomplete-stl-types/Makefile
new file mode 100644
index 0000000000000..2fd1763a62bb6
--- /dev/null
+++ b/lldb/test/API/lang/cpp/incomplete-stl-types/Makefile
@@ -0,0 +1,9 @@
+CXX_SOURCES := main.cpp f.cpp
+
+include Makefile.rules
+
+# Force main.cpp to be built with no debug information
+main.o: CFLAGS = $(CFLAGS_NO_DEBUG)
+
+# And force -flimit-debug-info on the rest.
+f.o: CFLAGS_EXTRAS += $(LIMIT_DEBUG_INFO_FLAGS)

diff  --git a/lldb/test/API/lang/cpp/incomplete-stl-types/TestStlIncompleteTypes.py b/lldb/test/API/lang/cpp/incomplete-stl-types/TestStlIncompleteTypes.py
new file mode 100644
index 0000000000000..06d960cd5c9f3
--- /dev/null
+++ b/lldb/test/API/lang/cpp/incomplete-stl-types/TestStlIncompleteTypes.py
@@ -0,0 +1,18 @@
+"""
+Test situations where the debug info only has a declaration, no definition, for
+an STL container with a formatter.
+"""
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class TestStlIncompleteTypes(TestBase):
+    def test(self):
+        self.build()
+        lldbutil.run_to_source_breakpoint(self, "// break here", lldb.SBFileSpec("f.cpp"))
+
+        var = self.frame().GetValueForVariablePath("v")
+        self.assertIn("set", var.GetDisplayTypeName())

diff  --git a/lldb/test/API/lang/cpp/incomplete-stl-types/f.cpp b/lldb/test/API/lang/cpp/incomplete-stl-types/f.cpp
new file mode 100644
index 0000000000000..af330d7db7709
--- /dev/null
+++ b/lldb/test/API/lang/cpp/incomplete-stl-types/f.cpp
@@ -0,0 +1,5 @@
+#include <set>
+
+void f(std::set<int> &v) {
+  // break here
+}

diff  --git a/lldb/test/API/lang/cpp/incomplete-stl-types/main.cpp b/lldb/test/API/lang/cpp/incomplete-stl-types/main.cpp
new file mode 100644
index 0000000000000..22409c87a0f69
--- /dev/null
+++ b/lldb/test/API/lang/cpp/incomplete-stl-types/main.cpp
@@ -0,0 +1,8 @@
+#include <set>
+
+void f(std::set<int> &v);
+
+int main() {
+  std::set<int> v;
+  f(v);
+}


        


More information about the lldb-commits mailing list