This is the mail archive of the gdb-cvs@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]

[binutils-gdb/gdb-8.2-branch] Fix PR c++/23373: GDB hangs when printing a struct with a static member of itself


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=ad3c631a762734c39b85086d20ba28940c2fc9b8

commit ad3c631a762734c39b85086d20ba28940c2fc9b8
Author: Sergio Durigan Junior <sergiodj@redhat.com>
Date:   Sat Jul 7 17:16:55 2018 -0400

    Fix PR c++/23373: GDB hangs when printing a struct with a static member of itself
    
    This patch fixes a failure that happens when a structure has a static
    member whose type is the same as itself.  From the bug report:
    
      Example code:
      struct A
      {
          static A Empty;
          int a;
      };
    
      int main(void) {
          A a;
          return 0;
      }
    
      Output:
      (gdb) ptype/o A
      /* offset    |  size */  type = struct A {
    			     static struct A {
    				 static struct A {
    				     static struct A {
    					 static struct A {
    					     static struct A {
    						 static struct A {
    						     ... # infinite loop
    
    The problem here is that GDB is not taking into account the fact that
    static members inside a class/struct are not stored in the
    class/struct, and therefore they should not be accounted for during
    the display of the offsets/sizes.  The fix is simple: we just check if
    the field we're dealing with (on
    c-typeprint.c:c_type_print_base_struct_union) is static, and if it is
    then we don't iterate over it.
    
    This patch also adds a new test for this case, and doesn't introduce
    any regressions.  I believe it is important enough to be included in
    the 8.2 branch.
    
    OK?
    
    gdb/ChangeLog:
    2018-07-11  Sergio Durigan Junior  <sergiodj@redhat.com>
    
    	PR c++/23373
    	* c-typeprint.c (c_type_print_base_struct_union): Don't print
    	offsets/sizes for static members of a class/struct.
    
    gdb/testsuite/ChangeLog:
    2018-07-11  Sergio Durigan Junior  <sergiodj@redhat.com>
    
    	PR c++/23373
    	* gdb.base/ptype-offsets.cc (struct static_member): New
    	struct.
    	(main) <stmember>: New variable.
    	* gdb.base/ptype-offsets.exp: Add test for printing a struct
    	with a static member in it.

Diff:
---
 gdb/ChangeLog                            |  6 ++++++
 gdb/c-typeprint.c                        |  2 +-
 gdb/testsuite/ChangeLog                  |  9 +++++++++
 gdb/testsuite/gdb.base/ptype-offsets.cc  |  8 ++++++++
 gdb/testsuite/gdb.base/ptype-offsets.exp | 11 +++++++++++
 5 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 9920aa7..f36edde 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,9 @@
+2018-07-11  Sergio Durigan Junior  <sergiodj@redhat.com>
+
+	PR c++/23373
+	* c-typeprint.c (c_type_print_base_struct_union): Don't print
+	offsets/sizes for static members of a class/struct.
+
 2018-07-07  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
 	* contrib/gdb-add-index.sh ($dwarf5): New, use it.
diff --git a/gdb/c-typeprint.c b/gdb/c-typeprint.c
index c167e21..eccb972 100644
--- a/gdb/c-typeprint.c
+++ b/gdb/c-typeprint.c
@@ -1168,7 +1168,7 @@ c_type_print_base_struct_union (struct type *type, struct ui_file *stream,
 
 	  int newshow = show - 1;
 
-	  if (flags->print_offsets
+	  if (!is_static && flags->print_offsets
 	      && (TYPE_CODE (TYPE_FIELD_TYPE (type, i)) == TYPE_CODE_STRUCT
 		  || TYPE_CODE (TYPE_FIELD_TYPE (type, i)) == TYPE_CODE_UNION))
 	    {
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index a9e1618..4d0c88e 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -1,3 +1,12 @@
+2018-07-11  Sergio Durigan Junior  <sergiodj@redhat.com>
+
+	PR c++/23373
+	* gdb.base/ptype-offsets.cc (struct static_member): New
+	struct.
+	(main) <stmember>: New variable.
+	* gdb.base/ptype-offsets.exp: Add test for printing a struct
+	with a static member in it.
+
 2018-07-04  Tom de Vries  <tdevries@suse.de>
 
 	* gdb.dwarf2/dw2-error.exp: Update expected error message.
diff --git a/gdb/testsuite/gdb.base/ptype-offsets.cc b/gdb/testsuite/gdb.base/ptype-offsets.cc
index 7b01dbc..e1aefe5 100644
--- a/gdb/testsuite/gdb.base/ptype-offsets.cc
+++ b/gdb/testsuite/gdb.base/ptype-offsets.cc
@@ -177,6 +177,13 @@ struct asd
   void *f16;
 };
 
+/* See PR c++/23373.  */
+
+struct static_member
+{
+  static static_member Empty;
+  int abc;
+};
 
 int
 main (int argc, char *argv[])
@@ -188,6 +195,7 @@ main (int argc, char *argv[])
   struct tyu e;
   struct asd f;
   uint8_t i;
+  static_member stmember;
 
   return 0;
 }
diff --git a/gdb/testsuite/gdb.base/ptype-offsets.exp b/gdb/testsuite/gdb.base/ptype-offsets.exp
index d8718d5..ca0c5de 100644
--- a/gdb/testsuite/gdb.base/ptype-offsets.exp
+++ b/gdb/testsuite/gdb.base/ptype-offsets.exp
@@ -328,3 +328,14 @@ gdb_test_multiple "$test" "$test" {
        pass $test
    }
 }
+
+# Test that printing a struct with a static member of itself doesn't
+# get us into an infinite loop.
+gdb_test "ptype/o static_member" \
+    [multi_line \
+{/\* offset    |  size \*/  type = struct static_member \{} \
+{                           static static_member Empty;} \
+{\/*    0      |     4 \*/    int abc;} \
+{} \
+{                           /\* total size \(bytes\):    4 \*/} \
+{                         \}}]


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