diff --git a/lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp b/lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp index d1d844bb4ca41246a48ef06f28b5e88f4f5ba977..6ea020e5deb69713dca595f7ac1624fc54939bd1 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp @@ -85,8 +85,13 @@ bool GenericBitsetFrontEnd::Update() { size_t size = 0; + // OHOS_LOCAL begin + const size_t bit_in_byte_cnt = 8; + const size_t sizeof_sizet_in_bits = sizeof(size_t) * bit_in_byte_cnt; + if (auto arg = m_backend.GetCompilerType().GetIntegralTemplateArgument(0)) - size = arg->value.getLimitedValue(); + size = (arg->value.getLimitedValue() + sizeof_sizet_in_bits - 1) / sizeof_sizet_in_bits; + // OHOS_LOCAL end m_elements.assign(size, ValueObjectSP()); m_first = m_backend.GetChildMemberWithName(GetDataContainerMemberName(), true) @@ -102,32 +107,23 @@ ValueObjectSP GenericBitsetFrontEnd::GetChildAtIndex(size_t idx) { return m_elements[idx]; ExecutionContext ctx = m_backend.GetExecutionContextRef().Lock(false); - CompilerType type; ValueObjectSP chunk; // For small bitsets __first_ is not an array, but a plain size_t. - if (m_first->GetCompilerType().IsArrayType(&type)) { - llvm::Optional bit_size = - type.GetBitSize(ctx.GetBestExecutionContextScope()); - if (!bit_size || *bit_size == 0) - return {}; - chunk = m_first->GetChildAtIndex(idx / *bit_size, true); + // OHOS_LOCAL begin + if (m_first->GetCompilerType().IsArrayType(nullptr)) { + chunk = m_first->GetChildAtIndex(idx, true); + // OHOS_LOCAL end } else { - type = m_first->GetCompilerType(); chunk = m_first->GetSP(); } - if (!type || !chunk) - return {}; - - llvm::Optional bit_size = - type.GetBitSize(ctx.GetBestExecutionContextScope()); - if (!bit_size || *bit_size == 0) + // OHOS_LOCAL begin + if (!chunk) return {}; - size_t chunk_idx = idx % *bit_size; - uint8_t value = !!(chunk->GetValueAsUnsigned(0) & (uint64_t(1) << chunk_idx)); - DataExtractor data(&value, sizeof(value), m_byte_order, m_byte_size); - m_elements[idx] = CreateValueObjectFromData(llvm::formatv("[{0}]", idx).str(), - data, ctx, m_bool_type); + StreamString name; + name.Printf("[%" PRIu64 "]", (uint64_t)idx); + m_elements[idx] = chunk->Clone(ConstString(name.GetString())); + // OHOS_LOCAL end return m_elements[idx]; } diff --git a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/bitset/TestDataFormatterGenericBitset.py b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/bitset/TestDataFormatterGenericBitset.py index 9cf0aa4fd5ede8ce366592ce03629c971d61154b..4bbb6c76ff15541f9d87bb9b8a9d66dd53936151 100644 --- a/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/bitset/TestDataFormatterGenericBitset.py +++ b/lldb/test/API/functionalities/data-formatter/data-formatter-stl/generic/bitset/TestDataFormatterGenericBitset.py @@ -60,10 +60,20 @@ class GenericBitsetDataFormatterTestCase(TestBase): self.check("large", 1000, VALUE) @add_test_categories(["libstdcxx"]) + # OHOS_LOCAL begin + @expectedFailureAll( + "Bitset frontend changed to be able " + "to update values during debugging") + # OHOS_LOCAL end def test_value_libstdcpp(self): self.do_test_value(USE_LIBSTDCPP) @add_test_categories(["libc++"]) + # OHOS_LOCAL begin + @expectedFailureAll( + "Bitset frontend changed to be able " + "to update values during debugging") + # OHOS_LOCAL end def test_value_libcpp(self): self.do_test_value(USE_LIBCPP) @@ -89,9 +99,19 @@ class GenericBitsetDataFormatterTestCase(TestBase): self.check("ptr", 1000, POINTER) @add_test_categories(["libstdcxx"]) + # OHOS_LOCAL begin + @expectedFailureAll( + "Bitset frontend changed to be able " + "to update values during debugging") + # OHOS_LOCAL end def test_ptr_and_ref_libstdcpp(self): self.do_test_ptr_and_ref(USE_LIBSTDCPP) @add_test_categories(["libc++"]) + # OHOS_LOCAL begin + @expectedFailureAll( + "Bitset frontend changed to be able " + "to update values during debugging") + # OHOS_LOCAL end def test_ptr_and_ref_libcpp(self): self.do_test_ptr_and_ref(USE_LIBCPP) diff --git a/lldb/test/API/python_api/value/change_values/libcxx/bitset/Makefile b/lldb/test/API/python_api/value/change_values/libcxx/bitset/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..564cbada74e080ec50299623dd06e3f19aa87f76 --- /dev/null +++ b/lldb/test/API/python_api/value/change_values/libcxx/bitset/Makefile @@ -0,0 +1,6 @@ +CXX_SOURCES := main.cpp + +USE_LIBCPP := 1 + +CXXFLAGS_EXTRAS := -O0 +include Makefile.rules diff --git a/lldb/test/API/python_api/value/change_values/libcxx/bitset/TestChangeBitsetValue.py b/lldb/test/API/python_api/value/change_values/libcxx/bitset/TestChangeBitsetValue.py new file mode 100644 index 0000000000000000000000000000000000000000..6fad4057e426b81d7e0c3a0af71dc376d9072395 --- /dev/null +++ b/lldb/test/API/python_api/value/change_values/libcxx/bitset/TestChangeBitsetValue.py @@ -0,0 +1,59 @@ +""" +Test change libc++ std::atomic values. +""" + +import lldb +from lldbsuite.test.decorators import * +from lldbsuite.test.lldbtest import * +from lldbsuite.test import lldbutil + +class LibcxxChangeBitsetValueTestCase(TestBase): + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + + def do_test_var(self, var_name, frame, expected_child_cnt): + value = frame.FindVariable(var_name) + self.assertTrue(value.IsValid(), "Got the SBValue for val") + child_cnt = value.GetNumChildren() + self.assertTrue(child_cnt == expected_child_cnt, + "Expected child cnt = {}".format(expected_child_cnt)) + for i in range(child_cnt): + child_val = value.GetChildAtIndex(i) + self.assertTrue(child_val.IsValid(), "Got the SBValue for inner atomic val") + new_val = 1000+i + result = child_val.SetValueFromCString(str(new_val)) + self.assertTrue(result, "Setting val returned True.") + self.assertTrue(child_val.GetValueDidChange(), "LLDB noticed that value changed") + result = child_val.GetValueAsUnsigned() + self.assertTrue(result == new_val, "Got correct value ({})".format(new_val)) + + @add_test_categories(["libc++", "libstdcxx"]) + @expectedFailureAll(oslist=["windows"], bugnumber="llvm.org/pr24772") + def test(self): + """Test that we can change values of libc++ std::bitset.""" + self.build() + self.runCmd("file " + self.getBuildArtifact("a.out"), CURRENT_EXECUTABLE_SET) + + bkpt = self.target().FindBreakpointByID( + lldbutil.run_break_set_by_source_regexp( + self, "Set break point at this line.")) + + self.runCmd("run", RUN_SUCCEEDED) + + # Get Frame #0. + target = self.dbg.GetSelectedTarget() + process = target.GetProcess() + self.assertState(process.GetState(), lldb.eStateStopped) + thread = lldbutil.get_stopped_thread( + process, lldb.eStopReasonBreakpoint) + self.assertTrue( + thread.IsValid(), + "There should be a thread stopped due to breakpoint condition") + frame0 = thread.GetFrameAtIndex(0) + self.assertTrue(frame0.IsValid(), "Got a valid frame.") + + self.do_test_var('empty', frame0, 0) + self.do_test_var('small', frame0, 1) + self.do_test_var('big', frame0, 2) diff --git a/lldb/test/API/python_api/value/change_values/libcxx/bitset/main.cpp b/lldb/test/API/python_api/value/change_values/libcxx/bitset/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e1361fdc14c524c2a5a74dc5a0a6559ff8495f36 --- /dev/null +++ b/lldb/test/API/python_api/value/change_values/libcxx/bitset/main.cpp @@ -0,0 +1,9 @@ +#include + +int main() +{ + std::bitset<0> empty; + std::bitset<4> small{15}; + std::bitset<65> big{"11111111111111111111111111111111111111111111111111111111111111111"}; + return 0; // Set break point at this line. +}