public inbox for archer@sourceware.org
 help / color / mirror / Atom feed
From: Richard Ward <richard.j.ward1@googlemail.com>
To: archer@sourceware.org
Subject: Patch to add rtti_type member to gdb.Value
Date: Wed, 23 Sep 2009 18:37:00 -0000	[thread overview]
Message-ID: <4ABA6ADD.4000003@googlemail.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 2107 bytes --]

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.


[-- Attachment #2: rtti_type.patch --]
[-- Type: text/x-patch, Size: 4002 bytes --]

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


             reply	other threads:[~2009-09-23 18:37 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-09-23 18:37 Richard Ward [this message]
2009-09-25 19:03 ` Tom Tromey
2009-09-25 19:19   ` Richard Ward
2009-09-25 20:43     ` Tom Tromey
2009-09-28  9:55 Richard Ward

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4ABA6ADD.4000003@googlemail.com \
    --to=richard.j.ward1@googlemail.com \
    --cc=archer@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).