[python][commit] Change gdb.Value.address from a method to an attribute.
Thiago Jung Bauermann
bauerman@br.ibm.com
Sat Mar 28 21:26:00 GMT 2009
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 {} {
More information about the Archer
mailing list