This is the mail archive of the archer@sourceware.org mailing list for the Archer project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[python][commit] Change gdb.Value.address from a method to anattribute.


Hi,

I just committed this to archer-tromey-python, and submitted the patch
to gdb-patches too.

I think the StdListPrinter change needs to be replicated to the
libstdc++ repo, right? Phil, would you mind doing this?
-- 
[]'s
Thiago Jung Bauermann
IBM Linux Technology Center


commit 1948198702b51b31d79793fc49434b529b4e245f
Author: Thiago Jung Bauermann <bauerman@br.ibm.com>
Date:   Sat Mar 28 16:38:18 2009 -0300

    Change gdb.Value.address from a method to an attribute.
    
    gdb/
    	* python/python-value.c (value_object): Add `address' element.
    	(valpy_dealloc): Decrement reference to self->address if set.
    	(valpy_new): Initialize val_obj->address.
    	(valpy_address): Rename to ...
    	(valpy_get_address): ... this.  Change signature from method to
    	attribute.  Update self->address if not set.
    	(value_to_value_object): Initialize val_obj->address.
    	(value_object_getset): Add `address' element.
    	(value_object_methods): Remove `address' element.
    	* python/lib/gdb/libstdcxx/v6/printers.py (StdListPrinter):
    	Update to new syntax.
    
    gdb/testsuite/
    	* gdb.python/find.exp: Update to new syntax.
    	* gdb.python/python-prettyprint.py: Likewise.
    	* gdb.python/python-value.exp: Add tests for the address
    	attribute.
    
    gdb/doc/
    	* gdb.texinfo (Values From Inferior): Change gdb.Value.address
    	from a method to an attribute.

diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 71ae3cc..c415f4c 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -18390,9 +18390,15 @@ bar = some_val['foo']
 
 Again, @code{bar} will also be a @code{gdb.Value} object.
 
-The following attribute is provided:
+The following attributes are provided:
 
 @table @code
+@defmethod Value address
+If the @code{gdb.Value} object is addressable, this read-only attribute
+holds a @code{gdb.Value} object representing the address.  Otherwise,
+this attribute holds @code{None}.
+@end defmethod
+
 @cindex optimized out value in Python
 @defmethod Value is_optimized_out
 This read-only boolean attribute is true if the compiler optimized out
@@ -18403,12 +18409,6 @@ this value, thus it is not available for fetching from the inferior.
 The following methods are provided:
 
 @table @code
-@defmethod Value address
-If the @code{gdb.Value} object is addressable, this will return a new
-@code{gdb.Value} object representing the address.  Otherwise, this
-will throw an exception.
-@end defmethod
-
 @defmethod Value cast type
 Cast the @code{gdb.Value} to the type represented by @var{type}, and
 return a new @code{gdb.Value}.  @var{type} must be a @code{gdb.Type}
diff --git a/gdb/python/lib/gdb/libstdcxx/v6/printers.py b/gdb/python/lib/gdb/libstdcxx/v6/printers.py
index bbd7bbc..149f1dd 100644
--- a/gdb/python/lib/gdb/libstdcxx/v6/printers.py
+++ b/gdb/python/lib/gdb/libstdcxx/v6/printers.py
@@ -49,7 +49,7 @@ class StdListPrinter:
         def __init__(self, nodetype, head):
             self.nodetype = nodetype
             self.base = head['_M_next']
-            self.head = head.address()
+            self.head = head.address
             self.count = 0
 
         def __iter__(self):
@@ -73,7 +73,7 @@ class StdListPrinter:
         return self._iterator(nodetype, self.val['_M_impl']['_M_node'])
 
     def to_string(self):
-        if self.val['_M_impl']['_M_node'].address() == self.val['_M_impl']['_M_node']['_M_next']:
+        if self.val['_M_impl']['_M_node'].address == self.val['_M_impl']['_M_node']['_M_next']:
             return 'empty std::list'
         return 'std::list'
 
diff --git a/gdb/python/python-value.c b/gdb/python/python-value.c
index 5d4f596..f3d24d1 100644
--- a/gdb/python/python-value.c
+++ b/gdb/python/python-value.c
@@ -63,6 +63,7 @@ typedef struct {
   PyObject_HEAD
   struct value *value;
   int owned_by_gdb;
+  PyObject *address;
 } value_object;
 
 /* Called by the Python interpreter when deallocating a value object.  */
@@ -75,6 +76,13 @@ valpy_dealloc (PyObject *obj)
 
   if (!self->owned_by_gdb)
     value_free (self->value);
+
+  if (self->address)
+    /* Use braces to appease gcc warning.  *sigh*  */
+    {
+      Py_DECREF (self->address);
+    }
+
   self->ob_type->tp_free (self);
 }
 
@@ -109,6 +117,7 @@ valpy_new (PyTypeObject *subtype, PyObject *args, PyObject *keywords)
 
   value_obj->value = value;
   value_obj->owned_by_gdb = 0;
+  value_obj->address = NULL;
   release_value (value);
   value_prepend_to_list (&values_in_python, value);
 
@@ -133,18 +142,30 @@ valpy_dereference (PyObject *self, PyObject *args)
 
 /* Return "&value".  */
 static PyObject *
-valpy_address (PyObject *self, PyObject *args)
+valpy_get_address (PyObject *self, void *closure)
 {
   struct value *res_val = NULL;	  /* Initialize to appease gcc warning.  */
+  value_object *val_obj = (value_object *) self;
   volatile struct gdb_exception except;
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  if (!val_obj->address)
     {
-      res_val = value_addr (((value_object *) self)->value);
+      TRY_CATCH (except, RETURN_MASK_ALL)
+	{
+	  res_val = value_addr (val_obj->value);
+	}
+      if (except.reason < 0)
+	{
+	  val_obj->address = Py_None;
+	  Py_INCREF (Py_None);
+	}
+      else
+	val_obj->address = value_to_value_object (res_val);
     }
-  GDB_PY_HANDLE_EXCEPTION (except);
 
-  return value_to_value_object (res_val);
+  Py_INCREF (val_obj->address);
+
+  return val_obj->address;
 }
 
 /* Return type of the value.  */
@@ -766,6 +787,7 @@ value_to_value_object (struct value *val)
     {
       val_obj->value = val;
       val_obj->owned_by_gdb = 0;
+      val_obj->address = NULL;
       release_value (val);
       value_prepend_to_list (&values_in_python, val);
     }
@@ -926,6 +948,8 @@ gdbpy_initialize_values (void)
 
 
 static PyGetSetDef value_object_getset[] = {
+  { "address", valpy_get_address, NULL, "The address of the value.",
+    NULL },
   { "is_optimized_out", valpy_get_is_optimized_out, NULL,
     "Boolean telling whether the value is optimized out (i.e., not available).",
     NULL },
@@ -933,7 +957,6 @@ static PyGetSetDef value_object_getset[] = {
 };
 
 static PyMethodDef value_object_methods[] = {
-  { "address", valpy_address, METH_NOARGS, "Return the address of the value." },
   { "cast", valpy_cast, METH_VARARGS, "Cast the value to the supplied type." },
   { "dereference", valpy_dereference, METH_NOARGS, "Dereferences the value." },
   { "type", valpy_type, METH_NOARGS, "Return type of the value." },
diff --git a/gdb/testsuite/gdb.python/find.exp b/gdb/testsuite/gdb.python/find.exp
index dd9aabc..d63ea84 100644
--- a/gdb/testsuite/gdb.python/find.exp
+++ b/gdb/testsuite/gdb.python/find.exp
@@ -91,7 +91,7 @@ set two_patterns_found "${newline}.${dec_number}L, ${dec_number}L]"
 
 gdb_test "set *(int32_t*) &int8_search_buf\[10\] = 0x61616161" "" ""
 gdb_test "py search_buf = gdb.selected_frame ().read_var ('int8_search_buf')" "" ""
-gdb_test "py start_addr = search_buf.address ()" "" ""
+gdb_test "py start_addr = search_buf.address" "" ""
 gdb_test "py length = search_buf.type ().sizeof ()" "" ""
 
 gdb_test "py print gdb.search_memory (start_addr, length, 'aaa')" \
@@ -129,7 +129,7 @@ gdb_test "py print gdb.search_memory (start_addr, length, \['a', 'a'\], max_coun
 
 gdb_test "set int16_search_buf\[10\] = 0x1234" "" ""
 gdb_test "py search_buf = gdb.selected_frame ().read_var ('int16_search_buf')" "" ""
-gdb_test "py start_addr = search_buf.address ()" "" ""
+gdb_test "py start_addr = search_buf.address" "" ""
 gdb_test "py length = search_buf.type ().sizeof ()" "" ""
 gdb_test "py pattern = gdb.parse_and_eval ('(int16_t) 0x1234')" "" ""
 
@@ -143,7 +143,7 @@ gdb_test "py print gdb.search_memory (start_addr, length, pattern)" \
 
 gdb_test "set int32_search_buf\[10\] = 0x12345678" "" ""
 gdb_test "py search_buf = gdb.selected_frame ().read_var ('int32_search_buf')" "" ""
-gdb_test "py start_addr = search_buf.address ()" "" ""
+gdb_test "py start_addr = search_buf.address" "" ""
 gdb_test "py length = search_buf.type ().sizeof ()" "" ""
 gdb_test "py pattern = gdb.parse_and_eval ('(int32_t) 0x12345678')" "" ""
 
@@ -156,7 +156,7 @@ gdb_test "py print gdb.search_memory (start_addr, length, pattern)" \
 
 gdb_test "set int64_search_buf\[10\] = 0xfedcba9876543210LL" "" ""
 gdb_test "py search_buf = gdb.selected_frame ().read_var ('int64_search_buf')" "" ""
-gdb_test "py start_addr = search_buf.address ()" "" ""
+gdb_test "py start_addr = search_buf.address" "" ""
 gdb_test "py length = search_buf.type ().sizeof ()" "" ""
 gdb_test "py pattern = gdb.parse_and_eval ('(int64_t) 0xfedcba9876543210LL')" "" ""
 
@@ -171,7 +171,7 @@ gdb_test "set *(int8_t*) &search_buf\[10\] = 0x62" "" ""
 gdb_test "set *(int16_t*) &search_buf\[11\] = 0x6363" "" ""
 gdb_test "set *(int32_t*) &search_buf\[13\] = 0x64646464" "" ""
 gdb_test "py search_buf = gdb.selected_frame ().read_var ('search_buf')" "" ""
-gdb_test "py start_addr = search_buf\[0\].address ()" "" ""
+gdb_test "py start_addr = search_buf\[0\].address" "" ""
 gdb_test "py pattern1 = gdb.parse_and_eval ('(int8_t) 0x62')" "" ""
 gdb_test "py pattern2 = gdb.parse_and_eval ('(int16_t) 0x6363')" "" ""
 gdb_test "py pattern3 = gdb.parse_and_eval ('(int32_t) 0x64646464')" "" ""
diff --git a/gdb/testsuite/gdb.python/python-prettyprint.py b/gdb/testsuite/gdb.python/python-prettyprint.py
index 0d9cb87..e032303 100644
--- a/gdb/testsuite/gdb.python/python-prettyprint.py
+++ b/gdb/testsuite/gdb.python/python-prettyprint.py
@@ -60,8 +60,8 @@ class pp_s:
     def to_string(self):
         a = self.val["a"]
         b = self.val["b"]
-        if a.address() != b:
-            raise Exception("&a(%s) != b(%s)" % (str(a.address()), str(b)))
+        if a.address != b:
+            raise Exception("&a(%s) != b(%s)" % (str(a.address), str(b)))
         return " a=<" + str(self.val["a"]) + "> b=<" + str(self.val["b"]) + ">"
 
 class pp_ss:
diff --git a/gdb/testsuite/gdb.python/python-value.exp b/gdb/testsuite/gdb.python/python-value.exp
index 0c0b1f3..cbcf91f 100644
--- a/gdb/testsuite/gdb.python/python-value.exp
+++ b/gdb/testsuite/gdb.python/python-value.exp
@@ -70,6 +70,9 @@ proc test_value_creation {} {
   gdb_py_test_silent_cmd "python a = gdb.Value (u'unicode test')" "create unicode value" 1
   gdb_test "python print a" "\"unicode test\"" "print Unicode string"
   gdb_test "python print a.__class__" "<type 'gdb.Value'>" "verify type of unicode string"
+
+  # Test address attribute is None in a non-addressable value
+  gdb_test "python print 'result =', i.address" "= None" "Test address attribute in non-addressable value"
 }
 
 proc test_value_numeric_ops {} {
@@ -228,6 +231,9 @@ proc test_value_in_inferior {} {
 
   # Smoke-test is_optimized_out attribute
   gdb_test "python print 'result =', arg0.is_optimized_out" "= False" "Test is_optimized_out attribute"
+
+  # Test address attribute
+  gdb_test "python print 'result =', arg0.address" "= 0x\[\[:xdigit:\]\]+" "Test address attribute"
 }
 
 proc test_value_after_death {} {



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]