[Lldb-commits] [lldb] r146768 - in /lldb/trunk: include/lldb/Core/ValueObject.h include/lldb/Core/ValueObjectConstResult.h include/lldb/Core/ValueObjectConstResultImpl.h source/Core/ValueObjectConstResult.cpp source/Core/ValueObjectConstResultImpl.cpp source/Expression/ClangExpressionDeclMap.cpp test/expression_command/issue_11588/ test/expression_command/issue_11588/Makefile test/expression_command/issue_11588/Test11588.py test/expression_command/issue_11588/main.cpp test/expression_command/issue_11588/s11588.py

Johnny Chen johnny.chen at apple.com
Fri Dec 16 15:04:52 PST 2011


Author: johnny
Date: Fri Dec 16 17:04:52 2011
New Revision: 146768

URL: http://llvm.org/viewvc/llvm-project?rev=146768&view=rev
Log:
http://llvm.org/bugs/show_bug.cgi?id=11588
valobj.AddressOf() returns None when an address is expected in a SyntheticChildrenProvider

Patch from Enrico Granata:

The problem was that the frozen object created by the expression parser was a copy of the contents of the StgClosure, rather than a pointer to it. Thus, the expression parser was correctly computing the result of the arithmetic&cast operation along with its address, but only saving it in the live object. This meant that the frozen copy acted as an address-less variable, hence the problem.

The fix attached to this email lets the expression parser store the "live address" in the frozen copy of the address when the object is built without a valid address of its own.
Doing so, along with delegating ValueObjectConstResult to calculate its own address when necessary, solves the issue. I have also added a new test case to check for regressions in this area, and checked that existing test cases pass correctly.

Added:
    lldb/trunk/test/expression_command/issue_11588/
    lldb/trunk/test/expression_command/issue_11588/Makefile
    lldb/trunk/test/expression_command/issue_11588/Test11588.py
    lldb/trunk/test/expression_command/issue_11588/main.cpp
    lldb/trunk/test/expression_command/issue_11588/s11588.py
Modified:
    lldb/trunk/include/lldb/Core/ValueObject.h
    lldb/trunk/include/lldb/Core/ValueObjectConstResult.h
    lldb/trunk/include/lldb/Core/ValueObjectConstResultImpl.h
    lldb/trunk/source/Core/ValueObjectConstResult.cpp
    lldb/trunk/source/Core/ValueObjectConstResultImpl.cpp
    lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp

Modified: lldb/trunk/include/lldb/Core/ValueObject.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObject.h?rev=146768&r1=146767&r2=146768&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ValueObject.h (original)
+++ lldb/trunk/include/lldb/Core/ValueObject.h Fri Dec 16 17:04:52 2011
@@ -696,7 +696,7 @@
     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 @@
     
     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,

Modified: lldb/trunk/include/lldb/Core/ValueObjectConstResult.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObjectConstResult.h?rev=146768&r1=146767&r2=146768&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ValueObjectConstResult.h (original)
+++ lldb/trunk/include/lldb/Core/ValueObjectConstResult.h Fri Dec 16 17:04:52 2011
@@ -109,11 +109,29 @@
     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 ();

Modified: lldb/trunk/include/lldb/Core/ValueObjectConstResultImpl.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/ValueObjectConstResultImpl.h?rev=146768&r1=146767&r2=146768&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/ValueObjectConstResultImpl.h (original)
+++ lldb/trunk/include/lldb/Core/ValueObjectConstResultImpl.h Fri Dec 16 17:04:52 2011
@@ -61,14 +61,20 @@
     }
     
     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 @@
     
     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;
     

Modified: lldb/trunk/source/Core/ValueObjectConstResult.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectConstResult.cpp?rev=146768&r1=146767&r2=146768&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObjectConstResult.cpp (original)
+++ lldb/trunk/source/Core/ValueObjectConstResult.cpp Fri Dec 16 17:04:52 2011
@@ -324,6 +324,13 @@
     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)
 {

Modified: lldb/trunk/source/Core/ValueObjectConstResultImpl.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObjectConstResultImpl.cpp?rev=146768&r1=146767&r2=146768&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObjectConstResultImpl.cpp (original)
+++ lldb/trunk/source/Core/ValueObjectConstResultImpl.cpp Fri Dec 16 17:04:52 2011
@@ -40,7 +40,8 @@
 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 @@
         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,

Modified: lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp?rev=146768&r1=146767&r2=146768&view=diff
==============================================================================
--- lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp (original)
+++ lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp Fri Dec 16 17:04:52 2011
@@ -396,13 +396,23 @@
     {
         // 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)

Added: lldb/trunk/test/expression_command/issue_11588/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/expression_command/issue_11588/Makefile?rev=146768&view=auto
==============================================================================
--- lldb/trunk/test/expression_command/issue_11588/Makefile (added)
+++ lldb/trunk/test/expression_command/issue_11588/Makefile Fri Dec 16 17:04:52 2011
@@ -0,0 +1,5 @@
+LEVEL = ../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules

Added: lldb/trunk/test/expression_command/issue_11588/Test11588.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/expression_command/issue_11588/Test11588.py?rev=146768&view=auto
==============================================================================
--- lldb/trunk/test/expression_command/issue_11588/Test11588.py (added)
+++ lldb/trunk/test/expression_command/issue_11588/Test11588.py Fri Dec 16 17:04:52 2011
@@ -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()

Added: lldb/trunk/test/expression_command/issue_11588/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/expression_command/issue_11588/main.cpp?rev=146768&view=auto
==============================================================================
--- lldb/trunk/test/expression_command/issue_11588/main.cpp (added)
+++ lldb/trunk/test/expression_command/issue_11588/main.cpp Fri Dec 16 17:04:52 2011
@@ -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);
+}

Added: lldb/trunk/test/expression_command/issue_11588/s11588.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/expression_command/issue_11588/s11588.py?rev=146768&view=auto
==============================================================================
--- lldb/trunk/test/expression_command/issue_11588/s11588.py (added)
+++ lldb/trunk/test/expression_command/issue_11588/s11588.py Fri Dec 16 17:04:52 2011
@@ -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
+





More information about the lldb-commits mailing list