diff options
-rw-r--r-- | lldb/include/lldb/Core/ValueObject.h | 14 | ||||
-rw-r--r-- | lldb/include/lldb/Core/ValueObjectConstResult.h | 18 | ||||
-rw-r--r-- | lldb/include/lldb/Core/ValueObjectConstResultImpl.h | 9 | ||||
-rw-r--r-- | lldb/source/Core/ValueObjectConstResult.cpp | 7 | ||||
-rw-r--r-- | lldb/source/Core/ValueObjectConstResultImpl.cpp | 23 | ||||
-rw-r--r-- | lldb/source/Expression/ClangExpressionDeclMap.cpp | 14 | ||||
-rw-r--r-- | lldb/test/expression_command/issue_11588/Makefile | 5 | ||||
-rw-r--r-- | lldb/test/expression_command/issue_11588/Test11588.py | 54 | ||||
-rw-r--r-- | lldb/test/expression_command/issue_11588/main.cpp | 54 | ||||
-rw-r--r-- | lldb/test/expression_command/issue_11588/s11588.py | 26 |
10 files changed, 219 insertions, 5 deletions
diff --git a/lldb/include/lldb/Core/ValueObject.h b/lldb/include/lldb/Core/ValueObject.h index 9f4eaa546dd..1472ca3b435 100644 --- a/lldb/include/lldb/Core/ValueObject.h +++ b/lldb/include/lldb/Core/ValueObject.h @@ -696,7 +696,7 @@ public: void SetName (const ConstString &name); - lldb::addr_t + virtual lldb::addr_t GetAddressOf (bool scalar_is_load_address = true, AddressType *address_type = NULL); @@ -747,6 +747,18 @@ public: virtual lldb::ValueObjectSP AddressOf (Error &error); + + virtual lldb::addr_t + GetLiveAddress() + { + return LLDB_INVALID_ADDRESS; + } + + virtual void + SetLiveAddress(lldb::addr_t addr = LLDB_INVALID_ADDRESS, + AddressType address_type = eAddressTypeLoad) + { + } virtual lldb::ValueObjectSP CastPointerType (const char *name, diff --git a/lldb/include/lldb/Core/ValueObjectConstResult.h b/lldb/include/lldb/Core/ValueObjectConstResult.h index d82390ee291..ebba0619e4f 100644 --- a/lldb/include/lldb/Core/ValueObjectConstResult.h +++ b/lldb/include/lldb/Core/ValueObjectConstResult.h @@ -109,11 +109,29 @@ public: virtual lldb::ValueObjectSP AddressOf (Error &error); + virtual lldb::addr_t + GetAddressOf (bool scalar_is_load_address = true, + AddressType *address_type = NULL); + virtual size_t GetPointeeData (DataExtractor& data, uint32_t item_idx = 0, uint32_t item_count = 1); + virtual lldb::addr_t + GetLiveAddress() + { + return m_impl.GetLiveAddress(); + } + + virtual void + SetLiveAddress(lldb::addr_t addr = LLDB_INVALID_ADDRESS, + AddressType address_type = eAddressTypeLoad) + { + m_impl.SetLiveAddress(addr, + address_type); + } + protected: virtual bool UpdateValue (); diff --git a/lldb/include/lldb/Core/ValueObjectConstResultImpl.h b/lldb/include/lldb/Core/ValueObjectConstResultImpl.h index 1b9c63fa4fa..b8c846fa1f5 100644 --- a/lldb/include/lldb/Core/ValueObjectConstResultImpl.h +++ b/lldb/include/lldb/Core/ValueObjectConstResultImpl.h @@ -61,14 +61,20 @@ public: } void - SetLiveAddress(lldb::addr_t addr = LLDB_INVALID_ADDRESS) + SetLiveAddress(lldb::addr_t addr = LLDB_INVALID_ADDRESS, + AddressType address_type = eAddressTypeLoad) { m_live_address = addr; + m_live_address_type = address_type; } lldb::ValueObjectSP DerefOnTarget(); + virtual lldb::addr_t + GetAddressOf (bool scalar_is_load_address = true, + AddressType *address_type = NULL); + virtual size_t GetPointeeData (DataExtractor& data, uint32_t item_idx = 0, @@ -78,6 +84,7 @@ private: ValueObject *m_impl_backend; lldb::addr_t m_live_address; + AddressType m_live_address_type; lldb::ValueObjectSP m_load_addr_backend; lldb::ValueObjectSP m_address_of_backend; diff --git a/lldb/source/Core/ValueObjectConstResult.cpp b/lldb/source/Core/ValueObjectConstResult.cpp index 9a23ca82a1b..fa1503f3217 100644 --- a/lldb/source/Core/ValueObjectConstResult.cpp +++ b/lldb/source/Core/ValueObjectConstResult.cpp @@ -324,6 +324,13 @@ ValueObjectConstResult::AddressOf (Error &error) return m_impl.AddressOf(error); } +lldb::addr_t +ValueObjectConstResult::GetAddressOf (bool scalar_is_load_address, + AddressType *address_type) +{ + return m_impl.GetAddressOf(scalar_is_load_address, address_type); +} + ValueObject * ValueObjectConstResult::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index) { diff --git a/lldb/source/Core/ValueObjectConstResultImpl.cpp b/lldb/source/Core/ValueObjectConstResultImpl.cpp index 119ba015590..afe050291b0 100644 --- a/lldb/source/Core/ValueObjectConstResultImpl.cpp +++ b/lldb/source/Core/ValueObjectConstResultImpl.cpp @@ -40,7 +40,8 @@ using namespace lldb_private; ValueObjectConstResultImpl::ValueObjectConstResultImpl (ValueObject* valobj, lldb::addr_t live_address) : m_impl_backend(valobj), - m_live_address(live_address), + m_live_address(live_address), + m_live_address_type(eAddressTypeLoad), m_load_addr_backend(), m_address_of_backend() { @@ -201,6 +202,26 @@ ValueObjectConstResultImpl::AddressOf (Error &error) return lldb::ValueObjectSP(); } +lldb::addr_t +ValueObjectConstResultImpl::GetAddressOf (bool scalar_is_load_address, + AddressType *address_type) +{ + + if (m_impl_backend == NULL) + return 0; + + if (m_live_address == LLDB_INVALID_ADDRESS) + { + return m_impl_backend->ValueObject::GetAddressOf (scalar_is_load_address, + address_type); + } + + if (address_type) + *address_type = m_live_address_type; + + return m_live_address; +} + size_t ValueObjectConstResultImpl::GetPointeeData (DataExtractor& data, uint32_t item_idx, diff --git a/lldb/source/Expression/ClangExpressionDeclMap.cpp b/lldb/source/Expression/ClangExpressionDeclMap.cpp index e019334a5f7..e115054549a 100644 --- a/lldb/source/Expression/ClangExpressionDeclMap.cpp +++ b/lldb/source/Expression/ClangExpressionDeclMap.cpp @@ -396,13 +396,23 @@ ClangExpressionDeclMap::CompleteResultVariable (lldb::ClangExpressionVariableSP { // The reference comes from the program. We need to set up a live SP for it. + unsigned long long address = value.GetScalar().ULongLong(); + AddressType address_type = value.GetValueAddressType(); + pvar_sp->m_live_sp = ValueObjectConstResult::Create(m_parser_vars->m_exe_ctx->GetBestExecutionContextScope(), pvar_sp->GetTypeFromUser().GetASTContext(), pvar_sp->GetTypeFromUser().GetOpaqueQualType(), pvar_sp->GetName(), - value.GetScalar().ULongLong(), - value.GetValueAddressType(), + address, + address_type, pvar_sp->GetByteSize()); + + // if the frozen object does not yet have a valid live address we replicate the live_sp address + // to it. this solves the issue where synthetic children providers are unable to access + // the address-of result for objects obtained by casting the result of pointer arithmetic + // performed by the expression parser, as in: print *((ClassType*)(value-1)) + if (pvar_sp->m_frozen_sp->GetLiveAddress() == LLDB_INVALID_ADDRESS) + pvar_sp->m_frozen_sp->SetLiveAddress(address); } if (pvar_sp->m_flags & ClangExpressionVariable::EVNeedsFreezeDry) diff --git a/lldb/test/expression_command/issue_11588/Makefile b/lldb/test/expression_command/issue_11588/Makefile new file mode 100644 index 00000000000..8a7102e347a --- /dev/null +++ b/lldb/test/expression_command/issue_11588/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../make + +CXX_SOURCES := main.cpp + +include $(LEVEL)/Makefile.rules diff --git a/lldb/test/expression_command/issue_11588/Test11588.py b/lldb/test/expression_command/issue_11588/Test11588.py new file mode 100644 index 00000000000..ba0c1c622db --- /dev/null +++ b/lldb/test/expression_command/issue_11588/Test11588.py @@ -0,0 +1,54 @@ +""" +Test the solution to issue 11581. +valobj.AddressOf() returns None when an address is +expected in a SyntheticChildrenProvider +""" + +import os, time +import unittest2 +import lldb +from lldbtest import * + +class Issue11581TestCase(TestBase): + + mydir = os.path.join("expression_command", "issue_11588") + + def test_11581_commands(self): + # This is the function to remove the custom commands in order to have a + # clean slate for the next test case. + def cleanup(): + self.runCmd('type synthetic clear', check=False) + + # Execute the cleanup function during test case tear down. + self.addTearDownHook(cleanup) + + """valobj.AddressOf() should return correct values.""" + self.buildDefault() + + self.runCmd("file a.out", CURRENT_EXECUTABLE_SET) + + self.runCmd("breakpoint set --name main") + + self.runCmd("run", RUN_SUCCEEDED) + + self.runCmd("next", RUN_SUCCEEDED) + self.runCmd("next", RUN_SUCCEEDED) + self.runCmd("next", RUN_SUCCEEDED) + self.runCmd("next", RUN_SUCCEEDED) + self.runCmd("next", RUN_SUCCEEDED) + + self.runCmd("command script import s11588.py") + self.runCmd("type synthetic add --python-class s11588.Issue11581SyntheticProvider StgClosure") + + self.expect("print *((StgClosure*)(r14-1))", + substrs = ["(StgClosure) $", + "(StgClosure *) &$0 = 0x", + "(long) addr = ", + "(long) load_address = "]) + + +if __name__ == '__main__': + import atexit + lldb.SBDebugger.Initialize() + atexit.register(lambda: lldb.SBDebugger.Terminate()) + unittest2.main() diff --git a/lldb/test/expression_command/issue_11588/main.cpp b/lldb/test/expression_command/issue_11588/main.cpp new file mode 100644 index 00000000000..45067b7e702 --- /dev/null +++ b/lldb/test/expression_command/issue_11588/main.cpp @@ -0,0 +1,54 @@ +// +// 11588.cpp +// + +#include <iostream> + +class StgInfoTable {}; + +class StgHeader +{ +private: + StgInfoTable* info; +public: + StgHeader() + { + info = new StgInfoTable(); + } + ~StgHeader() + { + delete info; + } +}; + +class StgClosure +{ +private: + StgHeader header; + StgClosure* payload[1]; +public: + StgClosure(bool make_payload = true) + { + if (make_payload) + payload[0] = new StgClosure(false); + else + payload[0] = NULL; + } + ~StgClosure() + { + if (payload[0]) + delete payload[0]; + } +}; + +typedef unsigned long long int ptr_type; + +int main() +{ + StgClosure* r14_ = new StgClosure(); + r14_ = (StgClosure*)(((ptr_type)r14_ | 0x01)); // set the LSB to 1 for tagging + ptr_type r14 = (ptr_type)r14_; + int x = 0; + x = 3; + return (x-1); +} diff --git a/lldb/test/expression_command/issue_11588/s11588.py b/lldb/test/expression_command/issue_11588/s11588.py new file mode 100644 index 00000000000..01bb09a1b0d --- /dev/null +++ b/lldb/test/expression_command/issue_11588/s11588.py @@ -0,0 +1,26 @@ +class Issue11581SyntheticProvider(object): + def __init__(self, valobj, dict): + self.valobj = valobj + self.addrOf = valobj.AddressOf() + self.addr = valobj.GetAddress() + self.load_address = valobj.GetLoadAddress() + + def num_children(self): + return 3; + + def get_child_at_index(self, index): + if index == 0: + return self.addrOf + if index == 1: + return self.valobj.CreateValueFromExpression("addr", str(self.addr)) + if index == 2: + return self.valobj.CreateValueFromExpression("load_address", str(self.load_address)) + + def get_child_index(self, name): + if name == "addrOf": + return 0 + if name == "addr": + return 1 + if name == "load_address": + return 2 + |