This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB 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]

RFC: fix https://bugzilla.redhat.com/show_bug.cgi?id=849357


This patch fixes https://bugzilla.redhat.com/show_bug.cgi?id=849357.

The bug here is that gdb can crash when trying to print a vtable in a
certain situation.  This happens because the code checks
TYPE_VPTR_FIELDNO without also checking TYPE_VPTR_BASETYPE.

The fix is to do this check; but also to use get_vptr_fieldno, which is
necessary to always get the correct result.

Built and regtested on x86-64 F16.
New test case included.

Tom

2012-09-13  Tom Tromey  <tromey@redhat.com>

	Fix https://bugzilla.redhat.com/show_bug.cgi?id=849357
	* cp-valprint.c (cp_print_value_fields): Use get_vptr_fieldno.

2012-09-13  Tom Tromey  <tromey@redhat.com>

	* gdb.cp/derivation.exp: Add regression test.
	* gdb.cp/derivation.cc (class V_base, class V_inter, class
	V_derived): New.
	(vderived): New global.

diff --git a/gdb/cp-valprint.c b/gdb/cp-valprint.c
index c066aa5..e6a99ec 100644
--- a/gdb/cp-valprint.c
+++ b/gdb/cp-valprint.c
@@ -210,7 +210,9 @@ cp_print_value_fields (struct type *type, struct type *real_type,
     {
       int statmem_obstack_initial_size = 0;
       int stat_array_obstack_initial_size = 0;
-      
+      struct type *vptr_basetype = NULL;
+      int vptr_fieldno;
+
       if (dont_print_statmem == 0)
 	{
 	  statmem_obstack_initial_size =
@@ -225,6 +227,7 @@ cp_print_value_fields (struct type *type, struct type *real_type,
 	    }
 	}
 
+      vptr_fieldno = get_vptr_fieldno (type, &vptr_basetype);
       for (i = n_baseclasses; i < len; i++)
 	{
 	  /* If requested, skip printing of static fields.  */
@@ -358,7 +361,7 @@ cp_print_value_fields (struct type *type, struct type *real_type,
 					   v, stream, recurse + 1,
 					   options);
 		}
-	      else if (i == TYPE_VPTR_FIELDNO (type))
+	      else if (i == vptr_fieldno && type == vptr_basetype)
 		{
 		  int i_offset = offset + TYPE_FIELD_BITPOS (type, i) / 8;
 		  struct type *i_type = TYPE_FIELD_TYPE (type, i);
diff --git a/gdb/testsuite/gdb.cp/derivation.cc b/gdb/testsuite/gdb.cp/derivation.cc
index 942fcd2..fcd57ce 100644
--- a/gdb/testsuite/gdb.cp/derivation.cc
+++ b/gdb/testsuite/gdb.cp/derivation.cc
@@ -118,8 +118,37 @@ public:
     
 };
 
+class V_base
+{
+public:
+  virtual void m();
+  int base;
+};
+
+void
+V_base::m()
+{
+}
+
+class V_inter : public virtual V_base
+{
+public:
+  virtual void f();
+  int inter;
+};
+
+void
+V_inter::f()
+{
+}
 
+class V_derived : public V_inter
+{
+public:
+  double x;
+};
 
+V_derived vderived;
 
 int A::afoo() {
     return 1;
diff --git a/gdb/testsuite/gdb.cp/derivation.exp b/gdb/testsuite/gdb.cp/derivation.exp
index b752b52..a4210d9 100644
--- a/gdb/testsuite/gdb.cp/derivation.exp
+++ b/gdb/testsuite/gdb.cp/derivation.exp
@@ -176,3 +176,11 @@ gdb_test_multiple "frame" "re-selected 'main' frame after inferior call" {
 
 gdb_test "print g_instance.bfoo()" "\\$\[0-9\]+ = 2" "print value of g_instance.bfoo()"
 gdb_test "print g_instance.cfoo()" "\\$\[0-9\]+ = 3" "print value of g_instance.cfoo()"
+
+# This is a regression test for a bug that caused a crash when trying
+# to print the vtbl pointer.  We don't care about the output so much
+# here (it is tested elsewhere), just that gdb doesn't crash.  We test
+# "ptype" first because, before the gdb fix, that was the only code
+# path calling get_vptr_fieldno.
+gdb_test "ptype vderived" "type = .*"
+gdb_test "print vderived" " = {.* inter = 0.*x = 0}"


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