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; } _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits