werat created this revision. werat added a reviewer: teemperor. werat requested review of this revision. Herald added a project: LLDB. Herald added a subscriber: lldb-commits.
Children of ValueObject automatically update themselves when they detect the state of the process has changed, which typically happens when the parent value is updated. However, if in case of updating ValueObjectConstResult the process state is unchanged and the children remain stale. Explicitly clear the children upon the parent update, so that they're re-calculated afterwards. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D105470 Files: lldb/source/Core/ValueObject.cpp lldb/test/API/python_api/value/change_values/TestChangeValueAPI.py lldb/test/API/python_api/value/change_values/main.c Index: lldb/test/API/python_api/value/change_values/main.c =================================================================== --- lldb/test/API/python_api/value/change_values/main.c +++ lldb/test/API/python_api/value/change_values/main.c @@ -8,7 +8,12 @@ uint32_t second_val; uint64_t third_val; }; - + +struct bar +{ + int value; +}; + int main () { int val = 100; @@ -18,6 +23,11 @@ ptr->second_val = 6666; ptr->third_val = 66666666; + struct bar *b1 = (struct bar *) malloc (sizeof (struct bar)); + b1->value = 1; + struct bar *b2 = (struct bar *) malloc (sizeof (struct bar)); + b2->value = 2; + // Stop here and set values printf ("Val - %d Mine - %d, %d, %llu. Ptr - %d, %d, %llu\n", val, mine.first_val, mine.second_val, mine.third_val, Index: lldb/test/API/python_api/value/change_values/TestChangeValueAPI.py =================================================================== --- lldb/test/API/python_api/value/change_values/TestChangeValueAPI.py +++ lldb/test/API/python_api/value/change_values/TestChangeValueAPI.py @@ -130,6 +130,23 @@ self.assertEquals(actual_value, 98765, "Got the right changed value from ptr->second_val") + # Test updating the children after updating the parent value. + b = frame0.EvaluateExpression("auto $b_0 = b1; $b_0") + self.assertEquals( + b.GetValue(), + frame0.FindVariable("b1").GetValue()) + self.assertEquals( + b.GetChildAtIndex(0, lldb.eNoDynamicValues, True).GetValue(), + "1") + + b.SetValueFromCString(frame0.FindVariable("b2").GetValue()) + self.assertEquals( + b.GetValue(), + frame0.FindVariable("b2").GetValue()) + self.assertEquals( + b.GetChildAtIndex(0, lldb.eNoDynamicValues, True).GetValue(), + "2") + # gcc may set multiple locations for breakpoint breakpoint.SetEnabled(False) Index: lldb/source/Core/ValueObject.cpp =================================================================== --- lldb/source/Core/ValueObject.cpp +++ lldb/source/Core/ValueObject.cpp @@ -231,6 +231,10 @@ // We have to clear the value string here so ConstResult children will notice // if their values are changed by hand (i.e. with SetValueAsCString). ClearUserVisibleData(eClearUserVisibleDataItemsValue); + // Children have to be re-computed after updating the parent value. + m_flags.m_children_count_valid = false; + m_children.Clear(); + SetSyntheticChildren(lldb::SyntheticChildrenSP()); } void ValueObject::ClearDynamicTypeInformation() {
Index: lldb/test/API/python_api/value/change_values/main.c =================================================================== --- lldb/test/API/python_api/value/change_values/main.c +++ lldb/test/API/python_api/value/change_values/main.c @@ -8,7 +8,12 @@ uint32_t second_val; uint64_t third_val; }; - + +struct bar +{ + int value; +}; + int main () { int val = 100; @@ -18,6 +23,11 @@ ptr->second_val = 6666; ptr->third_val = 66666666; + struct bar *b1 = (struct bar *) malloc (sizeof (struct bar)); + b1->value = 1; + struct bar *b2 = (struct bar *) malloc (sizeof (struct bar)); + b2->value = 2; + // Stop here and set values printf ("Val - %d Mine - %d, %d, %llu. Ptr - %d, %d, %llu\n", val, mine.first_val, mine.second_val, mine.third_val, Index: lldb/test/API/python_api/value/change_values/TestChangeValueAPI.py =================================================================== --- lldb/test/API/python_api/value/change_values/TestChangeValueAPI.py +++ lldb/test/API/python_api/value/change_values/TestChangeValueAPI.py @@ -130,6 +130,23 @@ self.assertEquals(actual_value, 98765, "Got the right changed value from ptr->second_val") + # Test updating the children after updating the parent value. + b = frame0.EvaluateExpression("auto $b_0 = b1; $b_0") + self.assertEquals( + b.GetValue(), + frame0.FindVariable("b1").GetValue()) + self.assertEquals( + b.GetChildAtIndex(0, lldb.eNoDynamicValues, True).GetValue(), + "1") + + b.SetValueFromCString(frame0.FindVariable("b2").GetValue()) + self.assertEquals( + b.GetValue(), + frame0.FindVariable("b2").GetValue()) + self.assertEquals( + b.GetChildAtIndex(0, lldb.eNoDynamicValues, True).GetValue(), + "2") + # gcc may set multiple locations for breakpoint breakpoint.SetEnabled(False) Index: lldb/source/Core/ValueObject.cpp =================================================================== --- lldb/source/Core/ValueObject.cpp +++ lldb/source/Core/ValueObject.cpp @@ -231,6 +231,10 @@ // We have to clear the value string here so ConstResult children will notice // if their values are changed by hand (i.e. with SetValueAsCString). ClearUserVisibleData(eClearUserVisibleDataItemsValue); + // Children have to be re-computed after updating the parent value. + m_flags.m_children_count_valid = false; + m_children.Clear(); + SetSyntheticChildren(lldb::SyntheticChildrenSP()); } void ValueObject::ClearDynamicTypeInformation() {
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits