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]

Patch to add rtti_type member to gdb.Value


This patch adds value gdb.Value.rtti_type to go along side gdb.Value.type. the type represents the type of the value determined by rtti. Luckily it turns out that the info is already available in gdb's value struct, where it has already been properly determined, so there is no need to call any real gdb code. This just exposes it. It is very similar to valpy_get_type (without what appears to be an unnecessary Py_INCREF).

If the value is not one where rtti makes sense, the value is just equal to the value's type. The same applies if for example the vtable pointer is garbage.

Sample gdb session follows. class Sub is derived from Base (and they have vtables). broken1 and broken2 have their vtable pointers overwritten by silly values.
Breakpoint 1, main (argc=<value optimised out>, argv=<value optimised out>) at test.cpp:26
26 Base * actually_a_base=new Base();
(gdb) n
27 Base * actually_a_sub=new Sub();
(gdb)
28 ClassWithNoVtable *no_vtable=new ClassWithNoVtable;
(gdb)
29 Base * broken1=new Sub();
(gdb)
30 ((void**)broken1)[0]=0x0;
(gdb)
31 Base * broken2=new Sub();
(gdb)
32 ((void**)broken2)[0]=&no_vtable;
(gdb)
33 }
(gdb) python v=gdb.parse_and_eval("*actually_a_base")
(gdb) python print v.type
Base
(gdb) python print v.rtti_type
Base
(gdb) python v=gdb.parse_and_eval("*actually_a_sub")
(gdb) python print v.type
Base
(gdb) python print v.rtti_type
Sub
(gdb) python print v
{_vptr.Base = 0x8048858, some_val_in_base = 1}
(gdb) python print v.cast(v.rtti_type)
{<Base> = {_vptr.Base = 0x8048858, some_val_in_base = 1}, some_val_in_sub = 2}
(gdb) python v=gdb.parse_and_eval("*no_vtable")
(gdb) python print v.type
ClassWithNoVtable
(gdb) python print v.rtti_type
ClassWithNoVtable
(gdb) python v=gdb.parse_and_eval("*broken1")
(gdb) python print v.rtti_type
Base
(gdb) python v=gdb.parse_and_eval("*broken2")
(gdb) python print v.rtti_type
Base
(gdb) quit


Meant to submit this ages ago (and said in the list that I would), got caught up with other things, sorry. Someone mailed me off list to ask If I could submit it, so here it is. Docs/Changelogs updated also.

>From b7dd5dfc090c6ebd30ac34544c8a044aebba8e1a Mon Sep 17 00:00:00 2001
From: Richard Ward <richard@elemental-lin.(none)>
Date: Wed, 23 Sep 2009 19:21:36 +0100
Subject: [PATCH] 2009-09-23  Richard Ward  <richard.j.ward1@googlemail.com>

	add attribute rtti_type to gdb.Value
	* gdb/python/py-value.c:
		new function valpy_get_rtti_type to get and return the real type
		of a value from the gdb value struct, and store it as a
		type_object in value_object.
	* gdb/doc/gdb.texinfo
		updated to refelect the above.
---
 gdb/ChangeLog         |    6 ++++++
 gdb/doc/ChangeLog     |    4 ++++
 gdb/doc/gdb.texinfo   |    8 ++++++++
 gdb/python/py-value.c |   21 +++++++++++++++++++++
 4 files changed, 39 insertions(+), 0 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index e7b2748..f50b737 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,9 @@
+2009-09-23  Richard Ward  <richard.j.ward1@googlemail.com>
+
+	* py-value.c: Added an attribute called rtti_type
+	denoting the actual run time type of an object where
+	rtti is applicable.
+
 2009-09-10  Joel Brobecker  <brobecker@adacore.com>
 
 	* top.c (interactive_mode): New static variable.
diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog
index b3f8fc7..22c80ac 100644
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -1,3 +1,7 @@
+2009-09-23  Richard Ward  <richard.j.ward1@googlemail.com>
+
+	* gdb.texinfo: Document new attribute rtti_type in gdb.Value
+
 2009-09-10  Joel Brobecker  <brobecker@adacore.com>
 
 	Add documentation for set/show interactive-mode.
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 18ffb09..597757f 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -19104,6 +19104,14 @@ this value, thus it is not available for fetching from the inferior.
 The type of this @code{gdb.Value}.  The value of this attribute is a
 @code{gdb.Type} object.
 @end defivar
+
+@defivar Value rtti_type
+A @code{gdb.Type} object representing the actual type of this
+@code{gdb.Value} determined using Run Time Type Information where
+applicable.  If the value has no RTTI associated with it or if the type
+could not be determined then this attribute will be identical to the
+@code{type} attribute.
+@end defivar
 @end table
 
 The following methods are provided:
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index 14efd79..f5a04f6 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -60,6 +60,7 @@ typedef struct value_object {
   struct value *value;
   PyObject *address;
   PyObject *type;
+  PyObject *rtti_type;
 } value_object;
 
 /* List of all values which are currently exposed to Python. It is
@@ -224,6 +225,24 @@ valpy_get_type (PyObject *self, void *closure)
   return obj->type;
 }
 
+/* Return the real type of the value determined using rtti */
+static PyObject *
+valpy_get_rtti_type (PyObject *self, void *closure)
+{
+  value_object *obj = (value_object *) self;
+  if (!obj->rtti_type)
+    {
+      struct type * rtti_type=value_enclosing_type(obj->value);
+      obj->rtti_type = type_to_type_object (rtti_type);
+      if (!obj->rtti_type)
+	{
+	  obj->rtti_type = Py_None;
+	}
+    }
+  Py_INCREF (obj->rtti_type);
+  return obj->rtti_type;
+}
+
 /* Implementation of gdb.Value.string ([encoding] [, errors]
    [, length]) -> string.  Return Unicode string with value contents.
    If ENCODING is not given, the string is assumed to be encoded in
@@ -854,6 +873,7 @@ value_to_value_object (struct value *val)
       value_incref (val);
       val_obj->address = NULL;
       val_obj->type = NULL;
+      val_obj->rtti_type = NULL;
       note_value (val_obj);
     }
 
@@ -1021,6 +1041,7 @@ static PyGetSetDef value_object_getset[] = {
     "Boolean telling whether the value is optimized out (i.e., not available).",
     NULL },
   { "type", valpy_get_type, NULL, "Type of the value.", NULL },
+  { "rtti_type", valpy_get_rtti_type, NULL, "Actual type of the value determined using rtti.", NULL },
   {NULL}  /* Sentinel */
 };
 
-- 
1.6.0.4


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