From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 7359 invoked by alias); 30 Sep 2011 10:12:44 -0000 Received: (qmail 7338 invoked by uid 22791); 30 Sep 2011 10:12:42 -0000 X-SWARE-Spam-Status: No, hits=-2.7 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW,T_TO_NO_BRKTS_FREEMAIL X-Spam-Check-By: sourceware.org Received: from mail-yw0-f41.google.com (HELO mail-yw0-f41.google.com) (209.85.213.41) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 30 Sep 2011 10:12:19 +0000 Received: by ywe9 with SMTP id 9so1653279ywe.0 for ; Fri, 30 Sep 2011 03:12:19 -0700 (PDT) Received: by 10.68.13.35 with SMTP id e3mr50832pbc.31.1317377538730; Fri, 30 Sep 2011 03:12:18 -0700 (PDT) Received: from [10.32.160.31] ([182.92.247.1]) by mx.google.com with ESMTPS id u1sm16534111pbr.9.2011.09.30.03.12.15 (version=SSLv3 cipher=OTHER); Fri, 30 Sep 2011 03:12:17 -0700 (PDT) Message-ID: <4E8595F6.7080004@gmail.com> Date: Fri, 30 Sep 2011 11:04:00 -0000 From: Li Yu User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.23) Gecko/20110922 Thunderbird/3.1.15 MIME-Version: 1.0 To: gdb-patches@sourceware.org CC: Paul Koning Subject: [PATCH v2] gdb/python: add missing handling for anonymous members of struct and union Content-Type: text/plain; charset=GB2312 Content-Transfer-Encoding: 7bit X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2011-09/txt/msg00570.txt.bz2 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 gdb/python/: 2011-09-29 Li Yu * 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; }