This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[PATCH v2] gdb/python: add missing handling for anonymous members of struct and union
- From: Li Yu <raise dot sail at gmail dot com>
- To: gdb-patches at sourceware dot org
- Cc: Paul Koning <paulkoning at comcast dot net>
- Date: Fri, 30 Sep 2011 18:12:06 +0800
- Subject: [PATCH v2] gdb/python: add missing handling for anonymous members of struct and union
gdb.Type.fields() missed handling for anonymous members.
This patch fix it, below are details:
Assume that we have a c source as below:
/////////////////////////////
struct A
{
int a;
union {
int b0;
int b1;
union {
int bb0;
int bb1;
union {
int bbb0;
int bbb1;
};
};
};
int c;
union {
union {
int dd0;
int dd1;
};
int d2;
int d3;
};
};
int main()
{
struct A a;
}
////////////////////////////
And have a python gdb script as below:
##########################
v = gdb.parse_and_eval("a")
t = v.type
fields = t.fields()
for f in fields:
print "[%s]" % f.name, v[f.name]
##########################
Without this patch, above script will print:
[a] -7616
[] {{dd0 = 0, dd1 = 0}, d2 = 0, d3 = 0}
[c] 0
[] {{dd0 = 0, dd1 = 0}, d2 = 0, d3 = 0}
With this patch, above script will print rightly:
[a] -7616
[b0] 32767
[b1] 32767
[bb0] 32767
[bb1] 32767
[bbb0] 32767
[bbb1] 32767
[c] 0
[dd0] 0
[dd1] 0
[d2] 0
[d3] 0
And please note that this patch assumed that Paul's patch in
http://sourceware.org/ml/gdb-patches/2011-09/msg00546.html is
applied first.
Thanks for Paul's feedback for first version of this patch.
Signed-off-by: Li Yu <raise.sail@gmail.com>
gdb/python/:
2011-09-29 Li Yu <raise.sail@gmail.com>
* py-type.c: Add process for anonymous members of struct and union
py-type.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++---------
1 file changed, 54 insertions(+), 9 deletions(-)
diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c
index 27f8b38..d0d8a94 100644
--- a/gdb/python/py-type.c
+++ b/gdb/python/py-type.c
@@ -56,15 +56,20 @@ typedef struct pyty_field_object
static PyTypeObject field_object_type;
/* A type iterator object. */
-typedef struct {
+struct __typy_iterator_object
+{
PyObject_HEAD
+ /* The iterators for support fields of anonymous field */
+ struct __typy_iterator_object *child;
+ struct __typy_iterator_object *parent;
/* The current field index. */
int field;
/* What to return. */
enum gdbpy_iter_kind kind;
/* Pointer back to the original source type object. */
struct pyty_type_object *source;
-} typy_iterator_object;
+};
+typedef struct __typy_iterator_object typy_iterator_object;
static PyTypeObject type_iterator_object_type;
@@ -1201,6 +1206,8 @@ typy_make_iter (PyObject *self, enum gdbpy_iter_kind kind)
if (typy_iter_obj == NULL)
return NULL;
+ typy_iter_obj->child = NULL;
+ typy_iter_obj->parent = NULL;
typy_iter_obj->field = 0;
typy_iter_obj->kind = kind;
Py_INCREF (self);
- struct type *type = iter_obj->source->type;
- int i;
- PyObject *result;
-
- if (iter_obj->field < TYPE_NFIELDS (type))
+ typy_iterator_object *iter_obj = (typy_iterator_object *) self, *child_iter_obj;
+ struct type *type;
+ PyObject *result, *child_pytype;
+ char *name;
+
+ while (iter_obj->child) /* deepest anonymous member first */
+ {
+ iter_obj = iter_obj->child;
+ }
+ type = iter_obj->source->type;
+
+restart:
+ while (iter_obj->field >= TYPE_NFIELDS (type))
+ {
+ iter_obj = iter_obj->parent;
+ if (!iter_obj)
+ return NULL;
+ Py_DECREF(iter_obj->child);
+ iter_obj->child = NULL;
+ type = iter_obj->source->type;
+ }
+
+ name = TYPE_FIELD_NAME (type, iter_obj->field);
+ if (!name)
+ goto abort_clean;
+
+ if (name[0]) /* mostly cases */
{
result = make_fielditem (type, iter_obj->field, iter_obj->kind);
if (result != NULL)
- iter_obj->field++;
+ iter_obj->field++;
return result;
}
+ /* handing for anonymous members here */
+ type = TYPE_FIELD_TYPE(type, iter_obj->field++);
+ child_pytype = type_to_type_object(type);
+ if (!child_pytype)
+ goto abort_clean;;
+ child_iter_obj = (typy_iterator_object*)typy_make_iter (child_pytype, iter_obj->kind);
+ iter_obj->child = child_iter_obj;
+ child_iter_obj->parent = iter_obj;
+ iter_obj = child_iter_obj;
+ goto restart;
+
+abort_clean:
+ while (iter_obj->parent)
+ {
+ iter_obj = iter_obj->parent;
+ Py_DECREF(iter_obj->child);
+ }
return NULL;
}