diff options
7 files changed, 133 insertions, 24 deletions
diff --git a/lldb/include/lldb/Core/ValueObject.h b/lldb/include/lldb/Core/ValueObject.h index f952acec3bf..b9e1e54fe7a 100644 --- a/lldb/include/lldb/Core/ValueObject.h +++ b/lldb/include/lldb/Core/ValueObject.h @@ -285,18 +285,19 @@ public: SetUpdated (); bool - NeedsUpdating() + NeedsUpdating(bool accept_invalid_exe_ctx) { - SyncWithProcessState(); + SyncWithProcessState(accept_invalid_exe_ctx); return m_needs_update; } bool IsValid () { + const bool accept_invalid_exe_ctx = false; if (!m_mod_id.IsValid()) return false; - else if (SyncWithProcessState ()) + else if (SyncWithProcessState (accept_invalid_exe_ctx)) { if (!m_mod_id.IsValid()) return false; @@ -318,7 +319,7 @@ public: private: bool - SyncWithProcessState (); + SyncWithProcessState (bool accept_invalid_exe_ctx); ProcessModID m_mod_id; // This is the stop id when this ValueObject was last evaluated. ExecutionContextRef m_exe_ctx_ref; @@ -851,12 +852,19 @@ public: virtual bool SetData (DataExtractor &data, Error &error); - bool + virtual bool GetIsConstant () const { return m_update_point.IsConstant(); } + virtual bool + NeedsUpdating () + { + const bool accept_invalid_exe_ctx = false; + return m_update_point.NeedsUpdating(accept_invalid_exe_ctx); + } + void SetIsConstant () { diff --git a/lldb/include/lldb/Core/ValueObjectDynamicValue.h b/lldb/include/lldb/Core/ValueObjectDynamicValue.h index 7607bd38137..09f2f195e29 100644 --- a/lldb/include/lldb/Core/ValueObjectDynamicValue.h +++ b/lldb/include/lldb/Core/ValueObjectDynamicValue.h @@ -56,6 +56,19 @@ public: return true; } + virtual bool + GetIsConstant () const + { + return false; + } + + virtual bool + NeedsUpdating () + { + const bool accept_invalid_exe_ctx = true; + return m_update_point.NeedsUpdating(accept_invalid_exe_ctx); + } + virtual ValueObject * GetParent() { diff --git a/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h b/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h index 79c1e458af8..2ee14f71446 100644 --- a/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h +++ b/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h @@ -141,6 +141,19 @@ public: } virtual bool + GetIsConstant () const + { + return false; + } + + virtual bool + NeedsUpdating () + { + const bool accept_invalid_exe_ctx = true; + return m_update_point.NeedsUpdating(accept_invalid_exe_ctx); + } + + virtual bool SetValueFromCString (const char *value_str, Error& error); virtual void diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp index 503b9dfd66f..1d40eab25a0 100644 --- a/lldb/source/Core/ValueObject.cpp +++ b/lldb/source/Core/ValueObject.cpp @@ -198,7 +198,7 @@ ValueObject::UpdateValueIfNeeded (bool update_format) bool first_update = IsChecksumEmpty(); - if (m_update_point.NeedsUpdating()) + if (NeedsUpdating()) { m_update_point.SetUpdated(); @@ -3952,9 +3952,8 @@ ValueObject::EvaluationPoint::~EvaluationPoint () // exe_scope will be set to the current execution context scope. bool -ValueObject::EvaluationPoint::SyncWithProcessState() +ValueObject::EvaluationPoint::SyncWithProcessState(bool accept_invalid_exe_ctx) { - // Start with the target, if it is NULL, then we're obviously not going to get any further: const bool thread_and_frame_only_if_stopped = true; ExecutionContext exe_ctx(m_exe_ctx_ref.Lock(thread_and_frame_only_if_stopped)); @@ -3997,30 +3996,33 @@ ValueObject::EvaluationPoint::SyncWithProcessState() // That way we'll be sure to return a valid exe_scope. // If we used to have a thread or a frame but can't find it anymore, then mark ourselves as invalid. - if (m_exe_ctx_ref.HasThreadRef()) + if (!accept_invalid_exe_ctx) { - ThreadSP thread_sp (m_exe_ctx_ref.GetThreadSP()); - if (thread_sp) + if (m_exe_ctx_ref.HasThreadRef()) { - if (m_exe_ctx_ref.HasFrameRef()) + ThreadSP thread_sp (m_exe_ctx_ref.GetThreadSP()); + if (thread_sp) { - StackFrameSP frame_sp (m_exe_ctx_ref.GetFrameSP()); - if (!frame_sp) + if (m_exe_ctx_ref.HasFrameRef()) { - // We used to have a frame, but now it is gone - SetInvalid(); - changed = was_valid; + StackFrameSP frame_sp (m_exe_ctx_ref.GetFrameSP()); + if (!frame_sp) + { + // We used to have a frame, but now it is gone + SetInvalid(); + changed = was_valid; + } } } + else + { + // We used to have a thread, but now it is gone + SetInvalid(); + changed = was_valid; + } } - else - { - // We used to have a thread, but now it is gone - SetInvalid(); - changed = was_valid; - } - } + return changed; } diff --git a/lldb/test/expression_command/persistent_ptr_update/Makefile b/lldb/test/expression_command/persistent_ptr_update/Makefile new file mode 100644 index 00000000000..db5f575866d --- /dev/null +++ b/lldb/test/expression_command/persistent_ptr_update/Makefile @@ -0,0 +1,7 @@ +LEVEL = ../../make + +C_SOURCES := main.c + +include $(LEVEL)/Makefile.rules + + diff --git a/lldb/test/expression_command/persistent_ptr_update/TestPersistentPtrUpdate.py b/lldb/test/expression_command/persistent_ptr_update/TestPersistentPtrUpdate.py new file mode 100644 index 00000000000..9c291219529 --- /dev/null +++ b/lldb/test/expression_command/persistent_ptr_update/TestPersistentPtrUpdate.py @@ -0,0 +1,55 @@ +""" +Test that we can have persistent pointer variables +""" + +import unittest2 +import lldb +import lldbutil +from lldbtest import * + +class PersistentPtrUpdateTestCase(TestBase): + + mydir = TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + + @skipUnlessDarwin + @dsym_test + def test_with_dsym(self): + """Test that we can have persistent pointer variables""" + self.buildDsym() + self.do_my_test() + + @skipUnlessDarwin + @dwarf_test + def test_with_dwarf(self): + """Test that we can have persistent pointer variables""" + self.buildDwarf() + self.do_my_test() + + def do_my_test(self): + def cleanup(): + pass + + # Execute the cleanup function during test case tear down. + self.addTearDownHook(cleanup) + + self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) + + self.runCmd('break set -p here') + + self.runCmd("run", RUN_SUCCEEDED) + + self.runCmd("expr void* $foo = nullptr") + + self.runCmd("continue") + + self.expect("expr $foo", substrs=['$foo','0x0']) + +if __name__ == '__main__': + import atexit + lldb.SBDebugger.Initialize() + atexit.register(lambda: lldb.SBDebugger.Terminate()) + unittest2.main() diff --git a/lldb/test/expression_command/persistent_ptr_update/main.c b/lldb/test/expression_command/persistent_ptr_update/main.c new file mode 100644 index 00000000000..73346969ecc --- /dev/null +++ b/lldb/test/expression_command/persistent_ptr_update/main.c @@ -0,0 +1,11 @@ +void* foo(void *p) +{ + return p; // break here +} + +int main() { + while (1) { + foo(0); + } + return 0; +} |