[Lldb-commits] [lldb] 095c3c9 - [LLDB] Fix crash in TypeSystemClang::GetIndexofChildMemberWithName. (#117808)

via lldb-commits lldb-commits at lists.llvm.org
Wed Dec 4 10:49:15 PST 2024


Author: cmtice
Date: 2024-12-04T10:49:12-08:00
New Revision: 095c3c9d6ec349815563d47f951d4590b3d18333

URL: https://github.com/llvm/llvm-project/commit/095c3c9d6ec349815563d47f951d4590b3d18333
DIFF: https://github.com/llvm/llvm-project/commit/095c3c9d6ec349815563d47f951d4590b3d18333.diff

LOG: [LLDB] Fix crash in TypeSystemClang::GetIndexofChildMemberWithName. (#117808)

LLDB can crash in TypeSystemClang::GetIndexOfChildMemberWithName, at a
point where it pushes an index onto the child_indexes vector, tries to
call itself recursively, then tries to pop the entry from child_indexes.
The problem is that the recursive call can clear child_indexes, so that
this code ends up trying to pop an already empty vector. This change
saves the old vector before the push, then restores the saved vector
rather than trying to pop.

Added: 
    lldb/test/API/commands/target/anon-struct/Makefile
    lldb/test/API/commands/target/anon-struct/TestTargetVarAnonStruct.py
    lldb/test/API/commands/target/anon-struct/main.cpp

Modified: 
    lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
index 1a77c7cf9161a0..46c2002fe139d0 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -6754,12 +6754,12 @@ size_t TypeSystemClang::GetIndexOfChildMemberWithName(
           llvm::StringRef field_name = field->getName();
           if (field_name.empty()) {
             CompilerType field_type = GetType(field->getType());
+            std::vector<uint32_t> save_indices = child_indexes;
             child_indexes.push_back(child_idx);
             if (field_type.GetIndexOfChildMemberWithName(
                     name, omit_empty_base_classes, child_indexes))
               return child_indexes.size();
-            child_indexes.pop_back();
-
+            child_indexes = std::move(save_indices);
           } else if (field_name == name) {
             // We have to add on the number of base classes to this index!
             child_indexes.push_back(

diff  --git a/lldb/test/API/commands/target/anon-struct/Makefile b/lldb/test/API/commands/target/anon-struct/Makefile
new file mode 100644
index 00000000000000..99998b20bcb050
--- /dev/null
+++ b/lldb/test/API/commands/target/anon-struct/Makefile
@@ -0,0 +1,3 @@
+CXX_SOURCES := main.cpp
+
+include Makefile.rules

diff  --git a/lldb/test/API/commands/target/anon-struct/TestTargetVarAnonStruct.py b/lldb/test/API/commands/target/anon-struct/TestTargetVarAnonStruct.py
new file mode 100644
index 00000000000000..869081dc6e5e4c
--- /dev/null
+++ b/lldb/test/API/commands/target/anon-struct/TestTargetVarAnonStruct.py
@@ -0,0 +1,33 @@
+"""
+Test handling of Anonymous Structs, especially that they don't crash lldb.
+"""
+
+
+import lldb
+import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+import os
+import shutil
+import time
+
+
+class TestFrameVarAnonStruct(TestBase):
+    # If your test case doesn't stress debug info, then
+    # set this to true.  That way it won't be run once for
+    # each debug info format.
+    NO_DEBUG_INFO_TESTCASE = True
+
+    def test_frame_var(self):
+        self.build()
+        self.do_test()
+
+    def do_test(self):
+        target = self.createTestTarget()
+
+        # Verify that we don't crash in this case.
+        self.expect(
+            "target variable 'b.x'",
+            error=True,
+            substrs=["can't find global variable 'b.x'"],
+        )

diff  --git a/lldb/test/API/commands/target/anon-struct/main.cpp b/lldb/test/API/commands/target/anon-struct/main.cpp
new file mode 100644
index 00000000000000..fbe26ea0ab8752
--- /dev/null
+++ b/lldb/test/API/commands/target/anon-struct/main.cpp
@@ -0,0 +1,14 @@
+struct A {
+  struct {
+    int x = 1;
+  };
+} a;
+
+struct B {
+  // Anonymous struct inherits another struct.
+  struct : public A {
+    int z = 3;
+  };
+} b;
+
+int main(int argc, char **argv) { return 0; }


        


More information about the lldb-commits mailing list