[Lldb-commits] [lldb] r136861 - in /lldb/trunk: examples/synthetic/ include/lldb/API/ scripts/Python/interface/ source/API/ source/Core/ test/functionalities/data-formatter/data-formatter-objc/ test/functionalities/data-formatter/data-formatter-python-synth/

Enrico Granata granata.enrico at gmail.com
Wed Aug 3 18:41:03 PDT 2011


Author: enrico
Date: Wed Aug  3 20:41:02 2011
New Revision: 136861

URL: http://llvm.org/viewvc/llvm-project?rev=136861&view=rev
Log:
APIs to GetValueAsSigned/Unsigned() in SBValue now also accept an SBError parameter to give more info about any problem
The synthetic children providers now use the new (safer) APIs to get the values of objects
As a side effect, fixed an issue in ValueObject where ResolveValue() was not always updating the value before reading it

Modified:
    lldb/trunk/examples/synthetic/CFString.py
    lldb/trunk/examples/synthetic/StdListSynthProvider.py
    lldb/trunk/examples/synthetic/StdMapSynthProvider.py
    lldb/trunk/examples/synthetic/StdVectorSynthProvider.py
    lldb/trunk/include/lldb/API/SBValue.h
    lldb/trunk/scripts/Python/interface/SBValue.i
    lldb/trunk/source/API/SBValue.cpp
    lldb/trunk/source/Core/ValueObject.cpp
    lldb/trunk/test/functionalities/data-formatter/data-formatter-objc/CFString.py
    lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/StdListSynthProvider.py
    lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/StdMapSynthProvider.py
    lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/StdVectorSynthProvider.py

Modified: lldb/trunk/examples/synthetic/CFString.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/examples/synthetic/CFString.py?rev=136861&r1=136860&r2=136861&view=diff
==============================================================================
--- lldb/trunk/examples/synthetic/CFString.py (original)
+++ lldb/trunk/examples/synthetic/CFString.py Wed Aug  3 20:41:02 2011
@@ -45,7 +45,7 @@
 			# for 32bit targets, use safe ObjC code
 			return self.handle_unicode_string_safe()
 		offset = 12
-		pointer = int(self.valobj.GetValue(), 0) + offset
+		pointer = self.valobj.GetValueAsUnsigned(0) + offset
 		pystr = self.read_unicode(pointer)
 		return self.valobj.CreateValueFromExpression("content",
 			"(char*)\"" + pystr.encode('utf-8') + "\"")
@@ -60,7 +60,7 @@
 	def handle_unicode_string(self):
 		# step 1: find offset
 		if self.inline:
-			pointer = int(self.valobj.GetValue(), 0) + self.size_of_cfruntime_base();
+			pointer = self.valobj.GetValueAsUnsigned(0) + self.size_of_cfruntime_base();
 			if self.explicit == False:
 				# untested, use the safe code path
 				return self.handle_unicode_string_safe();
@@ -76,11 +76,11 @@
 				# for an inline string)
 				pointer = pointer + 8;
 		else:
-			pointer = int(self.valobj.GetValue(), 0) + self.size_of_cfruntime_base();
+			pointer = self.valobj.GetValueAsUnsigned(0) + self.size_of_cfruntime_base();
 			# read 8 bytes here and make an address out of them
 			vopointer = self.valobj.CreateChildAtOffset("dummy",
 				pointer,self.valobj.GetType().GetBasicType(lldb.eBasicTypeChar).GetPointerType());
-			pointer = int(vopointer.GetValue(), 0)
+			pointer = vopointer.GetValueAsUnsigned(0)
 		# step 2: read Unicode data at pointer
 		pystr = self.read_unicode(pointer)
 		# step 3: return it

Modified: lldb/trunk/examples/synthetic/StdListSynthProvider.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/examples/synthetic/StdListSynthProvider.py?rev=136861&r1=136860&r2=136861&view=diff
==============================================================================
--- lldb/trunk/examples/synthetic/StdListSynthProvider.py (original)
+++ lldb/trunk/examples/synthetic/StdListSynthProvider.py Wed Aug  3 20:41:02 2011
@@ -1,61 +1,68 @@
 import re
 class StdListSynthProvider:
+
     def __init__(self, valobj, dict):
-        self.valobj = valobj;
+        self.valobj = valobj
         self.update()
+
     def num_children(self):
-        next_val = int(self.Mnext.GetValue(),0)
-        prev_val = int(self.Mprev.GetValue(),0)
-        if next_val == 0:
-        	return 0;
-        if next_val == self.Mnode_address:
-        	return 0;
+        next_val = self.next.GetValueAsUnsigned(0)
+        prev_val = self.prev.GetValueAsUnsigned(0)
+        # After a std::list has been initialized, both next and prev will be non-NULL
+        if next_val == 0 or prev_val == 0:
+        	return 0
+        if next_val == self.node_address:
+        	return 0
         if next_val == prev_val:
-        	return 1;
+        	return 1
         size = 2
-        current = self.Mnext
-        while int(current.GetChildMemberWithName('_M_next').GetValue(),0) != self.Mnode_address:
-        	size = size + 1;
+        current = self.next
+        while current.GetChildMemberWithName('_M_next').GetValueAsUnsigned(0) != self.node_address:
+        	size = size + 1
         	current = current.GetChildMemberWithName('_M_next')
         return (size - 1)
+
     def get_child_index(self,name):
         if name == "len":
-            return self.num_children();
+            return self.num_children()
         else:
             return int(name.lstrip('[').rstrip(']'))
+
     def get_child_at_index(self,index):
         if index == self.num_children():
             return self.valobj.CreateValueFromExpression("len",str(self.num_children()))
         else:
             offset = index
-            current = self.Mnext;
+            current = self.next
             while offset > 0:
-            	current = current.GetChildMemberWithName('_M_next');
-            	offset = offset - 1;
+            	current = current.GetChildMemberWithName('_M_next')
+            	offset = offset - 1
             return current.CreateChildAtOffset('['+str(index)+']',2*current.GetType().GetByteSize(),self.data_type)
+
     def extract_type_name(self,name):
         self.type_name = name[16:]
         index = 2
         count_of_template = 1
         while index < len(self.type_name):
             if self.type_name[index] == '<':
-                count_of_template = count_of_template + 1;
+                count_of_template = count_of_template + 1
             elif self.type_name[index] == '>':
-                count_of_template = count_of_template - 1;
+                count_of_template = count_of_template - 1
             elif self.type_name[index] == ',' and count_of_template == 1:
                 self.type_name = self.type_name[:index]
                 break
-            index = index + 1;
+            index = index + 1
         self.type_name_nospaces = self.type_name.replace(", ", ",")
+
     def update(self):
-        self.Mimpl = self.valobj.GetChildMemberWithName('_M_impl')
-        self.Mnode = self.Mimpl.GetChildMemberWithName('_M_node')
-        self.extract_type_name(self.Mimpl.GetType().GetName())
-        self.Mnode_address = int(self.valobj.AddressOf().GetValue(), 0)
-        self.Mnext = self.Mnode.GetChildMemberWithName('_M_next')
-        self.Mprev = self.Mnode.GetChildMemberWithName('_M_prev')
-        self.data_type = self.Mnode.GetTarget().FindFirstType(self.type_name)
+        impl = self.valobj.GetChildMemberWithName('_M_impl')
+        node = impl.GetChildMemberWithName('_M_node')
+        self.extract_type_name(impl.GetType().GetName())
+        self.node_address = self.valobj.AddressOf().GetValueAsUnsigned(0)
+        self.next = node.GetChildMemberWithName('_M_next')
+        self.prev = node.GetChildMemberWithName('_M_prev')
+        self.data_type = node.GetTarget().FindFirstType(self.type_name)
         # tries to fight against a difference in formatting type names between gcc and clang
         if self.data_type.IsValid() == False:
-            self.data_type = self.Mnode.GetTarget().FindFirstType(self.type_name_nospaces)
+            self.data_type = node.GetTarget().FindFirstType(self.type_name_nospaces)
         self.data_size = self.data_type.GetByteSize()

Modified: lldb/trunk/examples/synthetic/StdMapSynthProvider.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/examples/synthetic/StdMapSynthProvider.py?rev=136861&r1=136860&r2=136861&view=diff
==============================================================================
--- lldb/trunk/examples/synthetic/StdMapSynthProvider.py (original)
+++ lldb/trunk/examples/synthetic/StdMapSynthProvider.py Wed Aug  3 20:41:02 2011
@@ -58,7 +58,7 @@
 		root_ptr_val = self.node_ptr_value(self.Mroot)
 		if root_ptr_val == 0:
 			return 0;
-		return int(self.Mimpl.GetChildMemberWithName('_M_node_count').GetValue(), 0);
+		return self.Mimpl.GetChildMemberWithName('_M_node_count').GetValueAsUnsigned(0)
 	def get_child_index(self,name):
 		if name == "len":
 			return self.num_children();
@@ -77,7 +77,7 @@
 			return current.CreateChildAtOffset('['+str(index)+']',self.skip_size,self.data_type)
 	# utility functions
 	def node_ptr_value(self,node):
-		return int(node.GetValue(),0);
+		return node.GetValueAsUnsigned(0)
 	def right(self,node):
 		return node.GetChildMemberWithName("_M_right");
 	def left(self,node):

Modified: lldb/trunk/examples/synthetic/StdVectorSynthProvider.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/examples/synthetic/StdVectorSynthProvider.py?rev=136861&r1=136860&r2=136861&view=diff
==============================================================================
--- lldb/trunk/examples/synthetic/StdVectorSynthProvider.py (original)
+++ lldb/trunk/examples/synthetic/StdVectorSynthProvider.py Wed Aug  3 20:41:02 2011
@@ -1,25 +1,55 @@
 class StdVectorSynthProvider:
+
     def __init__(self, valobj, dict):
         self.valobj = valobj;
         self.update()
+
     def num_children(self):
-        start_val = int(self.Mstart.GetValue(),0)
-        finish_val = int(self.Mfinish.GetValue(),0)
-        return (finish_val-start_val)/self.data_size
+        start_val = self.start.GetValueAsUnsigned(0)
+        finish_val = self.finish.GetValueAsUnsigned(0)
+        end_val  = self.end.GetValueAsUnsigned(0)
+        # Before a vector has been constructed, it will contain bad values
+        # so we really need to be careful about the length we return since
+        # unitialized data can cause us to return a huge number. We need
+        # to also check for any of the start, finish or end of storage values
+        # being zero (NULL). If any are, then this vector has not been 
+        # initialized yet and we should return zero
+        
+        # Make sure nothing is NULL
+        if start_val == 0 or finish_val == 0 or end_val == 0:
+            return 0
+        # Make sure start is less than finish
+        if start_val >= finish_val:
+            return 0
+        # Make sure finish is less than or equal to end of storage
+        if finish_val > end_val:
+            return 0
+
+        # We might still get things wrong, so cap things at 256 items for now
+        # TODO: read a target "settings set" variable for this to allow it to
+        # be customized
+        num_children = (finish_val-start_val)/self.data_size
+        if num_children > 256:
+            return 256
+        return num_children
+
     def get_child_index(self,name):
         if name == "len":
             return self.num_children();
         else:
             return int(name.lstrip('[').rstrip(']'))
+
     def get_child_at_index(self,index):
         if index == self.num_children():
             return self.valobj.CreateValueFromExpression("len",str(self.num_children()))
         else:
             offset = index * self.data_size
-            return self.Mstart.CreateChildAtOffset('['+str(index)+']',offset,self.data_type)
+            return self.start.CreateChildAtOffset('['+str(index)+']',offset,self.data_type)
+
     def update(self):
-        self.Mimpl = self.valobj.GetChildMemberWithName('_M_impl')
-        self.Mstart = self.Mimpl.GetChildMemberWithName('_M_start')
-        self.Mfinish = self.Mimpl.GetChildMemberWithName('_M_finish')
-        self.data_type = self.Mstart.GetType().GetPointeeType()
+        impl = self.valobj.GetChildMemberWithName('_M_impl')
+        self.start = impl.GetChildMemberWithName('_M_start')
+        self.finish = impl.GetChildMemberWithName('_M_finish')
+        self.end = impl.GetChildMemberWithName('_M_end_of_storage')
+        self.data_type = self.start.GetType().GetPointeeType()
         self.data_size = self.data_type.GetByteSize()

Modified: lldb/trunk/include/lldb/API/SBValue.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/API/SBValue.h?rev=136861&r1=136860&r2=136861&view=diff
==============================================================================
--- lldb/trunk/include/lldb/API/SBValue.h (original)
+++ lldb/trunk/include/lldb/API/SBValue.h Wed Aug  3 20:41:02 2011
@@ -72,6 +72,12 @@
     GetValue ();
 
     int64_t
+    GetValueAsSigned(SBError& error, int64_t fail_value=0);
+    
+    uint64_t
+    GetValueAsUnsigned(SBError& error, uint64_t fail_value=0);
+    
+    int64_t
     GetValueAsSigned(int64_t fail_value=0);
     
     uint64_t

Modified: lldb/trunk/scripts/Python/interface/SBValue.i
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/scripts/Python/interface/SBValue.i?rev=136861&r1=136860&r2=136861&view=diff
==============================================================================
--- lldb/trunk/scripts/Python/interface/SBValue.i (original)
+++ lldb/trunk/scripts/Python/interface/SBValue.i Wed Aug  3 20:41:02 2011
@@ -95,9 +95,15 @@
     GetValue ();
 
     int64_t
-    GetValueAsSigned(int64_t fail_value=0);
+    GetValueAsSigned(SBError& error, int64_t fail_value=0);
 
     uint64_t
+    GetValueAsUnsigned(SBError& error, uint64_t fail_value=0);
+    
+    int64_t
+    GetValueAsSigned(int64_t fail_value=0);
+    
+    uint64_t
     GetValueAsUnsigned(uint64_t fail_value=0);
 
     ValueType

Modified: lldb/trunk/source/API/SBValue.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/API/SBValue.cpp?rev=136861&r1=136860&r2=136861&view=diff
==============================================================================
--- lldb/trunk/source/API/SBValue.cpp (original)
+++ lldb/trunk/source/API/SBValue.cpp Wed Aug  3 20:41:02 2011
@@ -619,6 +619,48 @@
 }
 
 int64_t
+SBValue::GetValueAsSigned(SBError& error, int64_t fail_value)
+{
+    if (m_opaque_sp)
+    {
+        if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
+        {
+            Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
+            Scalar scalar;
+            if (m_opaque_sp->ResolveValue (scalar))
+                return scalar.GetRawBits64(fail_value);
+            else
+                error.SetErrorString("could not get value");
+        }
+        else
+            error.SetErrorString("could not get target");
+    }
+    error.SetErrorString("invalid SBValue");
+    return fail_value;
+}
+
+uint64_t
+SBValue::GetValueAsUnsigned(SBError& error, uint64_t fail_value)
+{
+    if (m_opaque_sp)
+    {
+        if (m_opaque_sp->GetUpdatePoint().GetTargetSP())
+        {
+            Mutex::Locker api_locker (m_opaque_sp->GetUpdatePoint().GetTargetSP()->GetAPIMutex());
+            Scalar scalar;
+            if (m_opaque_sp->ResolveValue (scalar))
+                return scalar.GetRawBits64(fail_value);
+            else
+                error.SetErrorString("could not get value");
+        }
+        else
+            error.SetErrorString("could not get target");
+    }
+    error.SetErrorString("invalid SBValue");
+    return fail_value;
+}
+
+int64_t
 SBValue::GetValueAsSigned(int64_t fail_value)
 {
     if (m_opaque_sp)

Modified: lldb/trunk/source/Core/ValueObject.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/ValueObject.cpp?rev=136861&r1=136860&r2=136861&view=diff
==============================================================================
--- lldb/trunk/source/Core/ValueObject.cpp (original)
+++ lldb/trunk/source/Core/ValueObject.cpp Wed Aug  3 20:41:02 2011
@@ -331,12 +331,17 @@
 bool
 ValueObject::ResolveValue (Scalar &scalar)
 {
-    ExecutionContext exe_ctx;
-    ExecutionContextScope *exe_scope = GetExecutionContextScope();
-    if (exe_scope)
-        exe_scope->CalculateExecutionContext(exe_ctx);
-    scalar = m_value.ResolveValue(&exe_ctx, GetClangAST ());
-    return scalar.IsValid();
+    if (UpdateValueIfNeeded(false)) // make sure that you are up to date before returning anything
+    {
+        ExecutionContext exe_ctx;
+        ExecutionContextScope *exe_scope = GetExecutionContextScope();
+        if (exe_scope)
+            exe_scope->CalculateExecutionContext(exe_ctx);
+        scalar = m_value.ResolveValue(&exe_ctx, GetClangAST ());
+        return scalar.IsValid();
+    }
+    else
+        return false;
 }
 
 bool

Modified: lldb/trunk/test/functionalities/data-formatter/data-formatter-objc/CFString.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-objc/CFString.py?rev=136861&r1=136860&r2=136861&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-objc/CFString.py (original)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-objc/CFString.py Wed Aug  3 20:41:02 2011
@@ -45,7 +45,7 @@
 			# for 32bit targets, use safe ObjC code
 			return self.handle_unicode_string_safe()
 		offset = 12
-		pointer = int(self.valobj.GetValue(), 0) + offset
+		pointer = self.valobj.GetValueAsUnsigned(0) + offset
 		pystr = self.read_unicode(pointer)
 		return self.valobj.CreateValueFromExpression("content",
 			"(char*)\"" + pystr.encode('utf-8') + "\"")
@@ -60,7 +60,7 @@
 	def handle_unicode_string(self):
 		# step 1: find offset
 		if self.inline:
-			pointer = int(self.valobj.GetValue(), 0) + self.size_of_cfruntime_base();
+			pointer = self.valobj.GetValueAsUnsigned(0) + self.size_of_cfruntime_base();
 			if self.explicit == False:
 				# untested, use the safe code path
 				return self.handle_unicode_string_safe();
@@ -76,11 +76,11 @@
 				# for an inline string)
 				pointer = pointer + 8;
 		else:
-			pointer = int(self.valobj.GetValue(), 0) + self.size_of_cfruntime_base();
+			pointer = self.valobj.GetValueAsUnsigned(0) + self.size_of_cfruntime_base();
 			# read 8 bytes here and make an address out of them
 			vopointer = self.valobj.CreateChildAtOffset("dummy",
 				pointer,self.valobj.GetType().GetBasicType(lldb.eBasicTypeChar).GetPointerType());
-			pointer = int(vopointer.GetValue(), 0)
+			pointer = vopointer.GetValueAsUnsigned(0)
 		# step 2: read Unicode data at pointer
 		pystr = self.read_unicode(pointer)
 		# step 3: return it

Modified: lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/StdListSynthProvider.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/StdListSynthProvider.py?rev=136861&r1=136860&r2=136861&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/StdListSynthProvider.py (original)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/StdListSynthProvider.py Wed Aug  3 20:41:02 2011
@@ -6,8 +6,8 @@
         self.update()
 
     def num_children(self):
-        next_val = int(self.next.GetValue(),0)
-        prev_val = int(self.prev.GetValue(),0)
+        next_val = self.next.GetValueAsUnsigned(0)
+        prev_val = self.prev.GetValueAsUnsigned(0)
         # After a std::list has been initialized, both next and prev will be non-NULL
         if next_val == 0 or prev_val == 0:
         	return 0
@@ -17,7 +17,7 @@
         	return 1
         size = 2
         current = self.next
-        while int(current.GetChildMemberWithName('_M_next').GetValue(),0) != self.node_address:
+        while current.GetChildMemberWithName('_M_next').GetValueAsUnsigned(0) != self.node_address:
         	size = size + 1
         	current = current.GetChildMemberWithName('_M_next')
         return (size - 1)
@@ -58,7 +58,7 @@
         impl = self.valobj.GetChildMemberWithName('_M_impl')
         node = impl.GetChildMemberWithName('_M_node')
         self.extract_type_name(impl.GetType().GetName())
-        self.node_address = int(self.valobj.AddressOf().GetValue(), 0)
+        self.node_address = self.valobj.AddressOf().GetValueAsUnsigned(0)
         self.next = node.GetChildMemberWithName('_M_next')
         self.prev = node.GetChildMemberWithName('_M_prev')
         self.data_type = node.GetTarget().FindFirstType(self.type_name)

Modified: lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/StdMapSynthProvider.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/StdMapSynthProvider.py?rev=136861&r1=136860&r2=136861&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/StdMapSynthProvider.py (original)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/StdMapSynthProvider.py Wed Aug  3 20:41:02 2011
@@ -58,7 +58,7 @@
 		root_ptr_val = self.node_ptr_value(self.Mroot)
 		if root_ptr_val == 0:
 			return 0;
-		return int(self.Mimpl.GetChildMemberWithName('_M_node_count').GetValue(), 0);
+		return self.Mimpl.GetChildMemberWithName('_M_node_count').GetValueAsUnsigned(0)
 	def get_child_index(self,name):
 		if name == "len":
 			return self.num_children();
@@ -77,7 +77,7 @@
 			return current.CreateChildAtOffset('['+str(index)+']',self.skip_size,self.data_type)
 	# utility functions
 	def node_ptr_value(self,node):
-		return int(node.GetValue(),0);
+		return node.GetValueAsUnsigned(0)
 	def right(self,node):
 		return node.GetChildMemberWithName("_M_right");
 	def left(self,node):

Modified: lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/StdVectorSynthProvider.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/StdVectorSynthProvider.py?rev=136861&r1=136860&r2=136861&view=diff
==============================================================================
--- lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/StdVectorSynthProvider.py (original)
+++ lldb/trunk/test/functionalities/data-formatter/data-formatter-python-synth/StdVectorSynthProvider.py Wed Aug  3 20:41:02 2011
@@ -5,9 +5,9 @@
         self.update()
 
     def num_children(self):
-        start_val = int(self.start.GetValue(),0)
-        finish_val = int(self.finish.GetValue(),0)
-        end_val  = int(self.end.GetValue(),0)
+        start_val = self.start.GetValueAsUnsigned(0)
+        finish_val = self.finish.GetValueAsUnsigned(0)
+        end_val  = self.end.GetValueAsUnsigned(0)
         # Before a vector has been constructed, it will contain bad values
         # so we really need to be careful about the length we return since
         # unitialized data can cause us to return a huge number. We need





More information about the lldb-commits mailing list