[lldb][NFC] Add test for iterator invalidation during code completion.
authorRaphael Isemann <teemperor@gmail.com>
Tue, 14 Jan 2020 17:58:17 +0000 (18:58 +0100)
committerRaphael Isemann <teemperor@gmail.com>
Mon, 20 Jan 2020 14:01:39 +0000 (15:01 +0100)
lldb/packages/Python/lldbsuite/test/commands/expression/completion-crash-invalid-iterator/Makefile [new file with mode: 0644]
lldb/packages/Python/lldbsuite/test/commands/expression/completion-crash-invalid-iterator/TestInvalidIteratorCompletionCrash.py [new file with mode: 0644]
lldb/packages/Python/lldbsuite/test/commands/expression/completion-crash-invalid-iterator/main.cpp [new file with mode: 0644]

diff --git a/lldb/packages/Python/lldbsuite/test/commands/expression/completion-crash-invalid-iterator/Makefile b/lldb/packages/Python/lldbsuite/test/commands/expression/completion-crash-invalid-iterator/Makefile
new file mode 100644 (file)
index 0000000..3d0b98f
--- /dev/null
@@ -0,0 +1,2 @@
+CXX_SOURCES := main.cpp
+include Makefile.rules
diff --git a/lldb/packages/Python/lldbsuite/test/commands/expression/completion-crash-invalid-iterator/TestInvalidIteratorCompletionCrash.py b/lldb/packages/Python/lldbsuite/test/commands/expression/completion-crash-invalid-iterator/TestInvalidIteratorCompletionCrash.py
new file mode 100644 (file)
index 0000000..999a15c
--- /dev/null
@@ -0,0 +1,21 @@
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class TestCase(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+
+    @skipIf # rdar://problem/53931074
+    def test(self):
+        self.build()
+        exe = self.getBuildArtifact("a.out")
+        target = self.dbg.CreateTarget(exe)
+        callee_break = target.BreakpointCreateByName(
+            "SomeClass::SomeClass(ParamClass)", None)
+        self.assertTrue(callee_break.GetNumLocations() > 0)
+        self.runCmd("run", RUN_SUCCEEDED)
+
+        to_complete = "e ParamClass"
+        self.dbg.GetCommandInterpreter().HandleCompletion(to_complete, len(to_complete), 0, -1, lldb.SBStringList())
diff --git a/lldb/packages/Python/lldbsuite/test/commands/expression/completion-crash-invalid-iterator/main.cpp b/lldb/packages/Python/lldbsuite/test/commands/expression/completion-crash-invalid-iterator/main.cpp
new file mode 100644 (file)
index 0000000..225b41f
--- /dev/null
@@ -0,0 +1,22 @@
+class LoadedByParamClass {};
+struct ParamClass {
+  LoadedByParamClass some_func();
+};
+struct SomeClass {
+  // LLDB stops in the constructor and then requests
+  // possible expression completions. This will iterate over the
+  // declarations in the translation unit.
+  // The unnamed ParamClass parameter causes that LLDB will add
+  // an incomplete ParamClass decl to the translation unit which
+  // the code completion will find. Upon inspecting the ParamClass
+  // decl to see if it can be used to provide any useful completions,
+  // Clang will complete it and load all its members.
+  // This causes that its member function some_func is loaded which in turn
+  // loads the LoadedByParamClass decl. When LoadedByParamClass
+  // is created it will be added to the translation unit which
+  // will invalidate all iterators that currently iterate over
+  // the translation unit. The iterator we use for code completion
+  // is now invalidated and LLDB crashes.
+  SomeClass(ParamClass) {}
+};
+int main() { ParamClass e; SomeClass y(e); }