Author: teemperor
Date: Fri Oct 11 01:42:22 2019
New Revision: 374525

URL: http://llvm.org/viewvc/llvm-project?rev=374525&view=rev
Log:
[lldb] Fix crash in CxxModuleHandler when std module is empty

We currently don't handle the error in the Expected we get
when searching for an equal local DeclContext. Usually this can't
happen as this would require that we have a STL container and
we can find libc++'s std module, but when we load the module in
the expression parser the module doesn't even contain the 'std'
namespace. The only way I see to test this is by having a fake
'std' module that requires a special define to actually provide
its contents, while it will just be empty (that is, it doesn't
even contain the 'std' namespace) without that define. LLDB currently
doesn't know about that define in the expression parser, so it
will load the wrong 'empty' module which should trigger this error.

Also removed the 'auto' for that variable as the function name
doesn't make it obvious that this is an expected and not just
a optional/ptr (which is how this slipped in from the start).

Added:
    
lldb/trunk/packages/Python/lldbsuite/test/commands/expression/import-std-module/empty-module/
    
lldb/trunk/packages/Python/lldbsuite/test/commands/expression/import-std-module/empty-module/Makefile
    
lldb/trunk/packages/Python/lldbsuite/test/commands/expression/import-std-module/empty-module/TestEmptyStdModule.py
    
lldb/trunk/packages/Python/lldbsuite/test/commands/expression/import-std-module/empty-module/main.cpp
    
lldb/trunk/packages/Python/lldbsuite/test/commands/expression/import-std-module/empty-module/root/
    
lldb/trunk/packages/Python/lldbsuite/test/commands/expression/import-std-module/empty-module/root/usr/
    
lldb/trunk/packages/Python/lldbsuite/test/commands/expression/import-std-module/empty-module/root/usr/include/
    
lldb/trunk/packages/Python/lldbsuite/test/commands/expression/import-std-module/empty-module/root/usr/include/c++/
    
lldb/trunk/packages/Python/lldbsuite/test/commands/expression/import-std-module/empty-module/root/usr/include/c++/v1/
    
lldb/trunk/packages/Python/lldbsuite/test/commands/expression/import-std-module/empty-module/root/usr/include/c++/v1/algorithm
    
lldb/trunk/packages/Python/lldbsuite/test/commands/expression/import-std-module/empty-module/root/usr/include/c++/v1/module.modulemap
    
lldb/trunk/packages/Python/lldbsuite/test/commands/expression/import-std-module/empty-module/root/usr/include/libc_header.h
Modified:
    lldb/trunk/source/Symbol/CxxModuleHandler.cpp

Added: 
lldb/trunk/packages/Python/lldbsuite/test/commands/expression/import-std-module/empty-module/Makefile
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/commands/expression/import-std-module/empty-module/Makefile?rev=374525&view=auto
==============================================================================
--- 
lldb/trunk/packages/Python/lldbsuite/test/commands/expression/import-std-module/empty-module/Makefile
 (added)
+++ 
lldb/trunk/packages/Python/lldbsuite/test/commands/expression/import-std-module/empty-module/Makefile
 Fri Oct 11 01:42:22 2019
@@ -0,0 +1,9 @@
+# We don't have any standard include directories, so we can't
+# parse the test_common.h header we usually inject as it includes
+# system headers.
+NO_TEST_COMMON_H := 1
+
+CXXFLAGS_EXTRAS = -I $(SRCDIR)/root/usr/include/c++/v1/ -I 
$(SRCDIR)/root/usr/include/ -nostdinc -nostdinc++ -DENABLE_STD_CONTENT=1
+CXX_SOURCES := main.cpp
+
+include Makefile.rules

Added: 
lldb/trunk/packages/Python/lldbsuite/test/commands/expression/import-std-module/empty-module/TestEmptyStdModule.py
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/commands/expression/import-std-module/empty-module/TestEmptyStdModule.py?rev=374525&view=auto
==============================================================================
--- 
lldb/trunk/packages/Python/lldbsuite/test/commands/expression/import-std-module/empty-module/TestEmptyStdModule.py
 (added)
+++ 
lldb/trunk/packages/Python/lldbsuite/test/commands/expression/import-std-module/empty-module/TestEmptyStdModule.py
 Fri Oct 11 01:42:22 2019
@@ -0,0 +1,35 @@
+"""
+Test that LLDB doesn't crash if the std module we load is empty.
+"""
+
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+import os
+
+class ImportStdModule(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    @skipIf(compiler=no_match("clang"))
+    def test(self):
+        self.build()
+
+        sysroot = os.path.join(os.getcwd(), "root")
+
+        # Set the sysroot.
+        self.runCmd("platform select --sysroot '" + sysroot + "' host", 
CURRENT_EXECUTABLE_SET)
+
+        lldbutil.run_to_source_breakpoint(self,
+            "// Set break point at this line.", lldb.SBFileSpec("main.cpp"))
+
+        self.runCmd("settings set target.import-std-module true")
+        self.runCmd("log enable lldb expr")
+
+        # Use the typedef that is only defined in our 'empty' module. If this 
fails, then LLDB
+        # somehow figured out the correct define for the header and compiled 
the right
+        # standard module that actually contains the std::vector template.
+        self.expect("expr MissingContent var = 3; var", substrs=['$0 = 3'])
+        # Try to access our mock std::vector. This should fail but not crash 
LLDB as the
+        # std::vector template should be missing from the std module.
+        self.expect("expr (size_t)v.size()", substrs=["Couldn't lookup 
symbols"], error=True)

Added: 
lldb/trunk/packages/Python/lldbsuite/test/commands/expression/import-std-module/empty-module/main.cpp
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/commands/expression/import-std-module/empty-module/main.cpp?rev=374525&view=auto
==============================================================================
--- 
lldb/trunk/packages/Python/lldbsuite/test/commands/expression/import-std-module/empty-module/main.cpp
 (added)
+++ 
lldb/trunk/packages/Python/lldbsuite/test/commands/expression/import-std-module/empty-module/main.cpp
 Fri Oct 11 01:42:22 2019
@@ -0,0 +1,8 @@
+#include <algorithm>
+
+int main(int argc, char **argv) {
+  // Makes sure we have the mock libc headers in the debug information.
+  libc_struct s;
+  std::vector<int> v;
+  return 0; // Set break point at this line.
+}

Added: 
lldb/trunk/packages/Python/lldbsuite/test/commands/expression/import-std-module/empty-module/root/usr/include/c++/v1/algorithm
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/commands/expression/import-std-module/empty-module/root/usr/include/c%2B%2B/v1/algorithm?rev=374525&view=auto
==============================================================================
--- 
lldb/trunk/packages/Python/lldbsuite/test/commands/expression/import-std-module/empty-module/root/usr/include/c++/v1/algorithm
 (added)
+++ 
lldb/trunk/packages/Python/lldbsuite/test/commands/expression/import-std-module/empty-module/root/usr/include/c++/v1/algorithm
 Fri Oct 11 01:42:22 2019
@@ -0,0 +1,22 @@
+// This is only defined when building, but LLDB is missing this flag when 
loading the standard
+// library module so the actual contents of the module are missing.
+#ifdef ENABLE_STD_CONTENT
+
+#include "libc_header.h"
+
+namespace std {
+  inline namespace __1 {
+    // Pretend to be a std::vector template we need to instantiate
+    // in LLDB.
+    template<typename T>
+    struct vector { T i; int size() { return 2; } };
+  }
+}
+#else
+// Unused typedef we can use to check that we actually loaded
+// an empty module. Will be missing if LLDB somehow can get the
+// ENABLE_STD_CONTENT define right and break this test silently
+// (as with the define the module isn't empty anymore and this
+// test always succeeds).
+typedef int MissingContent;
+#endif // ENABLE_STD_CONTENT

Added: 
lldb/trunk/packages/Python/lldbsuite/test/commands/expression/import-std-module/empty-module/root/usr/include/c++/v1/module.modulemap
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/commands/expression/import-std-module/empty-module/root/usr/include/c%2B%2B/v1/module.modulemap?rev=374525&view=auto
==============================================================================
--- 
lldb/trunk/packages/Python/lldbsuite/test/commands/expression/import-std-module/empty-module/root/usr/include/c++/v1/module.modulemap
 (added)
+++ 
lldb/trunk/packages/Python/lldbsuite/test/commands/expression/import-std-module/empty-module/root/usr/include/c++/v1/module.modulemap
 Fri Oct 11 01:42:22 2019
@@ -0,0 +1,3 @@
+module std {
+  module "algorithm" { header "algorithm" export * }
+}

Added: 
lldb/trunk/packages/Python/lldbsuite/test/commands/expression/import-std-module/empty-module/root/usr/include/libc_header.h
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/commands/expression/import-std-module/empty-module/root/usr/include/libc_header.h?rev=374525&view=auto
==============================================================================
--- 
lldb/trunk/packages/Python/lldbsuite/test/commands/expression/import-std-module/empty-module/root/usr/include/libc_header.h
 (added)
+++ 
lldb/trunk/packages/Python/lldbsuite/test/commands/expression/import-std-module/empty-module/root/usr/include/libc_header.h
 Fri Oct 11 01:42:22 2019
@@ -0,0 +1 @@
+struct libc_struct {};

Modified: lldb/trunk/source/Symbol/CxxModuleHandler.cpp
URL: 
http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/CxxModuleHandler.cpp?rev=374525&r1=374524&r2=374525&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/CxxModuleHandler.cpp (original)
+++ lldb/trunk/source/Symbol/CxxModuleHandler.cpp Fri Oct 11 01:42:22 2019
@@ -175,6 +175,8 @@ T *createDecl(ASTImporter &importer, Dec
 }
 
 llvm::Optional<Decl *> CxxModuleHandler::tryInstantiateStdTemplate(Decl *d) {
+  Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS);
+
   // If we don't have a template to instiantiate, then there is nothing to do.
   auto td = dyn_cast<ClassTemplateSpecializationDecl>(d);
   if (!td)
@@ -196,9 +198,15 @@ llvm::Optional<Decl *> CxxModuleHandler:
 
   // Find the local DeclContext that corresponds to the DeclContext of our
   // decl we want to import.
-  auto to_context = getEqualLocalDeclContext(*m_sema, td->getDeclContext());
-  if (!to_context)
+  llvm::Expected<DeclContext *> to_context =
+      getEqualLocalDeclContext(*m_sema, td->getDeclContext());
+  if (!to_context) {
+    LLDB_LOG_ERROR(log, to_context.takeError(),
+                   "Got error while searching equal local DeclContext for decl 
"
+                   "'{1}':\n{0}",
+                   td->getName());
     return {};
+  }
 
   // Look up the template in our local context.
   std::unique_ptr<LookupResult> lookup =
@@ -215,8 +223,6 @@ llvm::Optional<Decl *> CxxModuleHandler:
   // Import the foreign template arguments.
   llvm::SmallVector<TemplateArgument, 4> imported_args;
 
-  Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS);
-
   // If this logic is changed, also update templateArgsAreSupported.
   for (const TemplateArgument &arg : foreign_args.asArray()) {
     switch (arg.getKind()) {


_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to